Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
7838 lines (7039 sloc) 412 KB
;;; icicles-cmd2.el --- Top-level commands for Icicles
;;
;; Filename: icicles-cmd2.el
;; Description: Top-level commands for Icicles
;; Author: Drew Adams
;; Maintainer: Drew Adams
;; Copyright (C) 1996-2012, Drew Adams, all rights reserved.
;; Created: Thu May 21 13:31:43 2009 (-0700)
;; Version: 22.0
;; Last-Updated: Fri Jan 20 16:50:10 2012 (-0800)
;; By: dradams
;; Update #: 5009
;; URL: http://www.emacswiki.org/cgi-bin/wiki/icicles-cmd2.el
;; Keywords: extensions, help, abbrev, local, minibuffer,
;; keys, apropos, completion, matching, regexp, command
;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x
;;
;; Features that might be required by this library:
;;
;; `apropos', `apropos-fn+var', `avoid', `backquote', `bytecomp',
;; `cl', `cus-edit', `cus-face', `cus-load', `cus-start', `doremi',
;; `easymenu', `el-swank-fuzzy', `ffap', `ffap-', `frame-cmds',
;; `frame-fns', `fuzzy', `fuzzy-match', `hexrgb', `icicles-cmd1',
;; `icicles-face', `icicles-fn', `icicles-mcmd', `icicles-opt',
;; `icicles-var', `image-dired', `kmacro', `levenshtein',
;; `misc-fns', `mouse3', `mwheel', `naked', `pp', `pp+',
;; `regexp-opt', `ring', `ring+', `second-sel', `strings',
;; `thingatpt', `thingatpt+', `wid-edit', `wid-edit+', `widget'.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Commentary:
;;
;; This is a helper library for library `icicles.el'. It defines
;; top-level commands (and a few non-interactive functions used in
;; those commands). This is a continuation of library
;; `icicles-cmd1.el' (a single file for all top-level commands would
;; be too large to upload to Emacs Wiki).
;;
;; For commands to be used mainly in the minibuffer or buffer
;; `*Completions*', see `icicles-mcmd.el'.
;;
;; For Icicles documentation, see `icicles-doc1.el' and
;; `icicles-doc2.el'.
;;
;; If you use the byte-compiled version of this library,
;; `icicles-cmd2.elc', in Emacs 23, then it must be byte-compiled
;; using Emacs 23. Otherwise, Icicles key completion (and perhaps
;; other things?) will not work correctly.
;;
;; Macros defined here:
;;
;; `icicle-maybe-byte-compile-after-load', `icicle-search-modes',
;; `icicle-with-comments-hidden'.
;;
;; Commands defined here - (+) means a multi-command:
;;
;; (+)`a', (+)`any', (+)`buffer', (+)`file', (+)`icicle-anything',
;; (+)`icicle-apply', `icicle-apropos', `icicle-apropos-command',
;; `icicle-apropos-function', `icicle-apropos-option',
;; `icicle-apropos-variable', `icicle-apropos-zippy',
;; (+)`icicle-bookmark-a-file', (+)`icicle-choose-faces',
;; (+)`icicle-choose-invisible-faces',
;; (+)`icicle-choose-visible-faces', (+)`icicle-comint-command',
;; (+)`icicle-comint-search', (+)`icicle-compilation-search',
;; (+)`icicle-complete-keys', `icicle-complete-thesaurus-entry',
;; (+)`icicle-describe-option-of-type', `icicle-describe-process',
;; (+)`icicle-doc', (+)`icicle-exchange-point-and-mark',
;; (+)`icicle-find-file-all-tags',
;; (+)`icicle-find-file-all-tags-other-window',
;; (+)`icicle-find-file-all-tags-regexp',
;; (+)`icicle-find-file-all-tags-regexp-other-window',
;; (+)`icicle-find-file-some-tags',
;; (+)`icicle-find-file-some-tags-other-window',
;; (+)`icicle-find-file-some-tags-regexp',
;; (+)`icicle-find-file-some-tags-regexp-other-window',
;; (+)`icicle-find-file-tagged',
;; (+)`icicle-find-file-tagged-other-window', (+)`icicle-font',
;; (+)`icicle-frame-bg', (+)`icicle-frame-fg', (+)`icicle-fundoc',
;; (+)`icicle-goto-global-marker',
;; (+)`icicle-goto-global-marker-or-pop-global-mark',
;; (+)`icicle-goto-marker',
;; (+)`icicle-goto-marker-or-set-mark-command',
;; (+)`icicle-hide-faces', (+)`icicle-hide-only-faces',
;; `icicle-hide/show-comments', (+)`icicle-imenu',
;; (+)`icicle-imenu-command', (+)`icicle-imenu-command-full',
;; (+)`icicle-imenu-face-full', (+)`icicle-imenu-face-full',
;; (+)`icicle-imenu-full', (+)`icicle-imenu-key-explicit-map',
;; (+)`icicle-imenu-key-explicit-map-full',
;; (+)`icicle-imenu-key-implicit-map',
;; (+)`icicle-imenu-key-implicit-map-full',
;; (+)`icicle-imenu-macro', (+)`icicle-imenu-macro-full',
;; (+)`icicle-imenu-non-interactive-function',
;; (+)`icicle-imenu-non-interactive-function-full',
;; (+)`icicle-imenu-user-option',
;; (+)`icicle-imenu-user-option-full', (+)`icicle-imenu-variable',
;; (+)`icicle-imenu-variable-full', `icicle-ido-like-mode',
;; (+)`icicle-Info-goto-node', (+)`icicle-Info-index',
;; (+)`icicle-Info-index-20', (+)`icicle-Info-menu',
;; `icicle-Info-virtual-book', (+)`icicle-insert-thesaurus-entry',
;; (+)`icicle-map', `icicle-next-visible-thing',
;; `icicle-non-whitespace-string-p', (+)`icicle-object-action',
;; (+)`icicle-occur', (+)`icicle-pick-color-by-name',
;; (+)`icicle-plist', `icicle-previous-visible-thing',
;; `icicle-read-color', `icicle-read-color-wysiwyg',
;; `icicle-save-string-to-variable', (+)`icicle-search',
;; (+)`icicle-search-all-tags-bookmark',
;; (+)`icicle-search-all-tags-regexp-bookmark',
;; (+)`icicle-search-autofile-bookmark',
;; (+)`icicle-search-autonamed-bookmark',
;; (+)`icicle-search-bookmark',
;; (+)`icicle-search-bookmark-list-bookmark',
;; `icicle-search-bookmark-list-marked',
;; (+)`icicle-search-bookmarks-together',
;; (+)`icicle-search-buffer', (+)`icicle-search-buff-menu-marked',
;; (+)`icicle-search-char-property', (+)`icicle-search-defs',
;; (+)`icicle-search-defs-full',
;; (+)`icicle-search-desktop-bookmark',
;; (+)`icicle-search-dired-bookmark',
;; (+)`icicle-search-dired-marked', (+)`icicle-search-file',
;; (+)`icicle-search-file-bookmark', (+)`icicle-search-generic',
;; (+)`icicle-search-gnus-bookmark',
;; `icicle-search-highlight-cleanup',
;; (+)`icicle-search-ibuffer-marked',
;; (+)`icicle-search-info-bookmark', (+)`icicle-search-keywords',
;; (+)`icicle-search-lines',
;; (+)`icicle-search-local-file-bookmark',
;; (+)`icicle-search-man-bookmark',
;; (+)`icicle-search-non-file-bookmark',
;; (+)`icicle-search-overlay-property',
;; (+)`icicle-search-paragraphs', (+)`icicle-search-pages',
;; (+)`icicle-search-region-bookmark',
;; (+)`icicle-search-remote-file-bookmark',
;; (+)`icicle-search-sentences',
;; (+)`icicle-search-some-tags-bookmark',
;; (+)`icicle-search-some-tags-regexp-bookmark',
;; (+)`icicle-search-specific-buffers-bookmark',
;; (+)`icicle-search-specific-files-bookmark',
;; (+)`icicle-search-temporary-bookmark',
;; (+)`icicle-search-text-property', (+)`icicle-search-thing',
;; (+)`icicle-search-this-buffer-bookmark',
;; (+)`icicle-search-url-bookmark',
;; `icicle-search-w-isearch-string',
;; (+)`icicle-search-w3m-bookmark', (+)`icicle-search-word',
;; (+)`icicle-search-xml-element',
;; (+)`icicle-search-xml-element-text-node',
;; (+)`icicle-select-frame', `icicle-select-frame-by-name',
;; (+)`icicle-send-signal-to-process',
;; `icicle-set-S-TAB-methods-for-command',
;; `icicle-set-TAB-methods-for-command', (+)`icicle-show-faces',
;; (+)`icicle-show-only-faces', (+)`icicle-synonyms',
;; (+)`icicle-tag-a-file', (+)`icicle-tags-search',
;; (+)`icicle-untag-a-file', (+)`icicle-vardoc',
;; (+)`icicle-where-is', (+)`synonyms', (+)`what-which-how'.
;;
;; Non-interactive functions defined here:
;;
;; `icicle-add-key+cmd', `icicle-anything-candidate-value',
;; `icicle-apply-action', `icicle-apply-list-action',
;; `icicle-char-properties-in-buffer',
;; `icicle-char-properties-in-buffers',
;; `icicle-choose-anything-candidate',
;; `icicle-choose-candidate-of-type',
;; `icicle-cmd2-after-load-bookmark+',
;; `icicle-cmd2-after-load-hexrgb',
;; `icicle-cmd2-after-load-highlight',
;; `icicle-cmd2-after-load-palette',
;; `icicle-cmd2-after-load-synonyms', `icicle-color-blue-lessp',
;; `icicle-color-completion-setup',
;; `icicle-color-distance-hsv-lessp',
;; `icicle-color-distance-rgb-lessp', `icicle-color-green-lessp',
;; `icicle-color-help', `icicle-color-hsv-lessp',
;; `icicle-color-hue-lessp', `icicle-color-red-lessp',
;; `icicle-color-saturation-lessp', `icicle-color-value-lessp',
;; `icicle-comint-hook-fn',
;; `icicle-comint-search-get-final-choice',
;; `icicle-comint-search-get-minibuffer-input',
;; `icicle-comint-search-send-input', `icicle-compilation-hook-fn',
;; `icicle-compilation-search-in-context-fn',
;; `icicle-complete-keys-1', `icicle-complete-keys-action',
;; `icicle-defined-thing-p', `icicle-describe-opt-action',
;; `icicle-describe-opt-of-type-complete', `icicle-doc-action',
;; `icicle-fn-doc-minus-sig', `icicle-font-w-orig-size',
;; `icicle-get-anything-actions-for-type',
;; `icicle-get-anything-cached-candidates',
;; `icicle-get-anything-candidates',
;; `icicle-get-anything-candidates-of-type',
;; `icicle-get-anything-default-actions-for-type',
;; `icicle-get-anything-input-delay',
;; `icicle-get-anything-req-pat-chars',
;; `icicle-get-anything-types', `icicle-goto-marker-1',
;; `icicle-goto-marker-1-action', `icicle-group-regexp',
;; `icicle-imenu-command-p', `icicle-imenu-in-buffer-p',
;; `icicle-imenu-non-interactive-function-p',
;; `icicle-Info-book-order-p',
;; `icicle-Info-build-node-completions',
;; `icicle-Info-build-node-completions-1',
;; `icicle-Info-goto-node-1', `icicle-Info-goto-node-action',
;; `icicle-Info-index-action', `icicle-Info-read-node-name',
;; `icicle-insert-thesaurus-entry-cand-fn',
;; `icicle-invisible-face-p', `icicle-invisible-p',
;; `icicle-keys+cmds-w-prefix', `icicle-make-color-candidate',
;; `icicle-marker+text', `icicle-markers',
;; `icicle-next-single-char-property-change',
;; `icicle-next-visible-thing-1', `icicle-next-visible-thing-2',
;; `icicle-next-visible-thing-and-bounds',
;; `icicle-pick-color-by-name-action',
;; `icicle-previous-single-char-property-change',
;; `icicle-read-args-for-set-completion-methods',
;; `icicle-read-var-value-satisfying',
;; `icicle-region-or-buffer-limits', `icicle-search-action',
;; `icicle-search-action-1', `icicle-search-bookmark-action',
;; `icicle-search-char-property-scan',
;; `icicle-search-char-prop-matches-p',
;; `icicle-search-choose-buffers', `icicle-search-cleanup',
;; `icicle-search-define-candidates',
;; `icicle-search-define-candidates-1', `icicle-search-final-act',
;; `icicle-search-help',
;; `icicle-search-highlight-all-input-matches',
;; `icicle-search-highlight-and-maybe-replace',
;; `icicle-search-highlight-input-matches-here',
;; `icicle-search-in-context-default-fn',
;; `icicle-search-property-args',
;; `icicle-search-property-default-match-fn',
;; `icicle-search-quit-or-error',
;; `icicle-search-read-context-regexp', `icicle-search-read-word',
;; `icicle-search-regexp-scan',
;; `icicle-search-replace-all-search-hits',
;; `icicle-search-replace-cand-in-alist',
;; `icicle-search-replace-cand-in-mct',
;; `icicle-search-replace-fixed-case-p',
;; `icicle-search-replace-match',
;; `icicle-search-replace-search-hit', `icicle-search-thing-args',
;; `icicle-search-thing-scan', `icicle-search-where-arg',
;; `icicle-set-completion-methods-for-command',
;; `icicle-things-alist', `icicle-this-command-keys-prefix'.
;;
;; Internal variables defined here:
;;
;; `icicle-active-map', `icicle-info-buff', `icicle-info-window',
;; `icicle-key-prefix', `icicle-key-prefix-2',
;; `icicle-last-thing-type', `icicle-named-colors',
;; `icicle-orig-extra-cands', `icicle-orig-font',
;; `icicle-orig-frame', `icicle-orig-menu-bar',
;; `icicle-orig-pixelsize', `icicle-orig-pointsize',
;; `icicle-orig-show-initially-flag',
;; `icicle-orig-sort-orders-alist', `icicle-this-cmd-keys'.
;;
;;
;; ***** NOTE: The following functions defined in `cus-edit.el' have
;; been REDEFINED HERE:
;;
;; `customize-face', `customize-face-other-window' - Multi-commands.
;;
;;
;; Key bindings made by Icicles: See "Key Bindings" in
;; `icicles-doc2.el'.
;;
;; For descriptions of changes to this file, see `icicles-chg.el'.
;;(@> "Index")
;;
;; If you have library `linkd.el' and Emacs 22 or later, load
;; `linkd.el' and turn on `linkd-mode' now. It lets you easily
;; navigate around the sections of this doc. Linkd mode will
;; highlight this Index, as well as the cross-references and section
;; headings throughout this file. You can get `linkd.el' here:
;; http://dto.freeshell.org/notebook/Linkd.html.
;;
;; (@> "Icicles Commands for Other Packages")
;; (@> "Icicles Top-Level Commands, Part 2")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 3, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
;; Floor, Boston, MA 02110-1301, USA.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Code:
(eval-when-compile (require 'cl)) ;; case, loop
;; plus, for Emacs < 21: dolist, push
(eval-when-compile (when (>= emacs-major-version 22) (require 'edmacro))) ;; edmacro-subseq
(eval-when-compile (require 'comint))
;; comint-check-proc, comint-copy-old-input, comint-get-old-input, comint-input-ring,
;; comint-prompt-regexp, comint-send-input
(eval-when-compile (require 'imenu)) ;; imenu-syntax-alist
(eval-when-compile (require 'compile)) ;; compilation-find-buffer
(eval-when-compile (require 'info)) ;; Info-goto-node
(eval-when-compile (require 'etags)) ;; tags-case-fold-search, tags-table-files,
;; visit-tags-table-buffer
(eval-when-compile (when (> emacs-major-version 21)
(require 'anything nil t))) ;; (no error if not found):
;; anything-candidate-cache, anything-get-sources, anything-idle-delay, anything-pattern,
;; anything-sources, anything-transform-candidates
(eval-when-compile (require 'yow nil t)) ;; (no error if not found):
;; apropos-zippy, yow-after-load-message, yow-file, yow-load-message
(eval-when-compile (require 'cookie1 nil t)) ;; (no error if not found): cookie-cache
(require 'apropos-fn+var nil t) ;; (no error if not found):
;; apropos-command, apropos-function, apropos-option, apropos-variable
(require 'strings nil t) ;; (no error if not found): read-number (my version)
(eval-when-compile (require 'bookmark+ nil t)) ;; (no error if not found):
;; bmkp-bmenu-barf-if-not-in-menu-list, bmkp-bmenu-get-marked-files, bmkp-bookmark-last-access-cp,
;; bmkp-buffer-last-access-cp, bmkp-describe-bookmark, bmkp-describe-bookmark-internals,
;; bmkp-file-alpha-cp, bmkp-get-buffer-name, bmkp-get-end-position, bmkp-get-tags, bmkp-gnus-cp,
;; bmkp-handler-cp, bmkp-info-cp, bmkp-local-file-accessed-more-recently-cp,
;; bmkp-local-file-size-cp, bmkp-local-file-type-cp, bmkp-local-file-updated-more-recently-cp,
;; bmkp-marked-cp, bmkp-non-file-filename, bmkp-read-tags-completing, bmkp-region-alist-only,
;; bmkp-region-bookmark-p, bmkp-sorted-alist, bmkp-sort-omit, bmkp-url-cp, bmkp-visited-more-cp
(eval-when-compile (require 'hexrgb nil t)) ;; (no error if not found):
;; hexrgb-color-name-to-hex, hexrgb-defined-colors, hexrgb-defined-colors-alist, hexrgb-hex-to-hsv,
;; hexrgb-hex-to-rgb, hexrgb-read-color, hexrgb-(red|green|blue|hue|saturation|value),
;; hexrgb-rgb-hex-string-p, hexrgb-rgb-to-hsv, hexrgb-value
(eval-when-compile (require 'highlight nil t)) ;; (no error if not found):
;; hlt-act-on-any-face-flag, hlt-hide-default-face, hlt-highlight-faces-in-buffer,
;; hlt-region-or-buffer-limits, hlt-show-default-face
(eval-when-compile
(or (condition-case nil
(load-library "icicles-mac") ; Use load-library to ensure latest .elc.
(error nil))
(require 'icicles-mac))) ; Require, so can load separately if not on `load-path'.
;; icicle-bind-file-candidate-keys, icicle-define-command, icicle-define-file-command,
;; icicle-file-bindings, icicle-unbind-file-candidate-keys
(require 'icicles-mcmd)
;; icicle-search-define-replacement
(require 'icicles-opt) ; (This is required anyway by `icicles-var.el'.)
;; icicle-alternative-sort-comparer, icicle-buffer-extras, icicle-buffer-ignore-space-prefix-flag,
;; icicle-buffer-match-regexp, icicle-buffer-no-match-regexp, icicle-buffer-predicate,
;; icicle-buffer-require-match-flag, icicle-buffer-sort, icicle-complete-keys-self-insert-ranges,
;; icicle-ignore-space-prefix-flag, icicle-key-descriptions-use-<>-flag, icicle-recenter,
;; icicle-require-match-flag, icicle-saved-completion-sets,
;; icicle-search-cleanup-flag, icicle-search-highlight-all-current-flag,
;; icicle-search-highlight-threshold, icicle-search-hook, icicle-sort-comparer,
;; icicle-transform-function
(require 'icicles-var) ; (This is required anyway by `icicles-fn.el'.)
;; icicle-abs-file-candidates, icicle-acting-on-next/prev, icicle-all-candidates-action,
;; icicle-all-candidates-list-action-fn, icicle-all-candidates-list-alt-action-fn,
;; icicle-apply-nomsg, icicle-apropos-complete-match-fn, icicle-bookmark-history,
;; icicle-buffer-sort-first-time-p, icicle-candidate-action-fn, icicle-candidate-alt-action-fn,
;; icicle-candidate-entry-fn, icicle-candidate-help-fn, icicle-candidate-nb,
;; icicle-candidate-properties-alist, icicle-candidates-alist, icicle-char-property-value-history,
;; icicle-color-history, icicle-complete-keys-alist, icicle-completing-keys-p,
;; icicle-completion-candidates, icicle-completion-set-history, icicle-current-completion-mode,
;; icicle-current-input, icicle-delete-candidate-object, icicle-dictionary-history,
;; icicle-doc-last-initial-cand-set, icicle-explore-final-choice, icicle-explore-final-choice-full,
;; icicle-extra-candidates, icicle-extra-candidates-dir-insert-p, icicle-face-name-history,
;; icicle-fancy-candidates-p, icicle-font-name-history, icicle-full-cand-fn,
;; icicle-function-name-history, icicle-fundoc-last-initial-cand-set,
;; icicle-get-alist-candidate-function, icicle-hist-cands-no-highlight, icicle-hist-var,
;; icicle-Info-only-rest-of-book-p, icicle-key-prefix-description, icicle-last-completion-candidate,
;; icicle-last-completion-command, icicle-last-input, icicle-last-sort-comparer,
;; icicle-last-transform-function, icicle-list-use-nth-parts, icicle-minibuffer-message-ok-p,
;; icicle-must-match-regexp, icicle-must-not-match-regexp, icicle-must-pass-after-match-predicate,
;; icicle-nb-of-other-cycle-candidates, icicle-orig-buff, icicle-orig-pt-explore, icicle-orig-window,
;; icicle-orig-win-explore, icicle-other-window, icicle-plist-last-initial-cand-set,
;; icicle-predicate-types-alist, icicle-pref-arg, icicle-prompt, icicle-proxy-candidate-regexp,
;; icicle-proxy-candidates, icicle-require-match-p, icicle-saved-completion-candidate,
;; icicle-saved-completion-candidates, icicle-scan-fn-or-regexp, icicle-search-command,
;; icicle-search-complement-domain-p, icicle-search-context-level, icicle-search-context-regexp,
;; icicle-search-current-overlay, icicle-search-final-choice, icicle-search-history,
;; icicle-search-in-context-fn, icicle-searching-p, icicle-search-level-overlays, icicle-search-modes,
;; icicle-search-overlays, icicle-search-refined-overlays, icicle-search-replacement,
;; icicle-transform-before-sort-p, icicle-vardoc-last-initial-cand-set,
;; icicle-vardoc-last-initial-option-cand-set, icicle-variable-name-history,
;; icicle-whole-candidate-as-text-prop-p
(require 'icicles-fn) ; (This is required anyway by `icicles-mcmd.el'.)
;; icicle-candidate-short-help, icicle-completing-read-history,
;; icicle-highlight-lighter, icicle-insert-cand-in-minibuffer, icicle-kill-a-buffer, icicle-some
(require 'icicles-cmd1)
;; custom-variable-p, icicle-bookmark-cleanup,
;; icicle-bookmark-cleanup-on-quit, icicle-bookmark-cmd, icicle-bookmark-help-string,
;; icicle-bookmark-propertize-candidate, icicle-buffer-list,
;; icicle-explore, icicle-face-list, icicle-file-list, icicle-keyword-list, icicle-make-frame-alist,
;; icicle-select-bookmarked-region
;; Byte-compiling this file, you will likely get some byte-compiler warning messages.
;; These are probably benign - ignore them. Icicles is designed to work with multiple
;; versions of Emacs, and that fact provokes compiler warnings. If you get byte-compiler
;; errors (not warnings), then please report a bug, using `M-x icicle-send-bug-report'.
;;; Some defvars to quiet byte-compiler a bit:
(defvar anything-sources) ; In `anything.el'
(defvar anything-candidate-cache) ; In `anything.el'
(defvar anything-idle-delay) ; In `anything.el'
(defvar apropos-do-all) ; In `apropos.el'
(defvar bmkp-non-file-filename) ; In `bookmark+-1.el'
(defvar bmkp-sorted-alist) ; In `bookmark+-1.el'
(defvar hlt-act-on-any-face-flag) ; In `highlight.el'
(defvar icicle-complete-keys-self-insert-ranges) ; In `icicles-var.el' (Emacs 22+)
(defvar icicle-search-ecm) ; In `icicle-search'
(defvar icicle-track-pt) ; In `icicle-insert-thesaurus-entry'
(defvar replace-count) ; In `replace.el'.
;; (< emacs-major-version 21)
(defvar tooltip-mode) ; In `tooltip.el'
;; (< emacs-major-version 22)
(defvar compilation-current-error)
(defvar cookie-cache)
(defvar Info-menu-entry-name-re) ; In `info.el'
(defvar Info-read-node-completion-table) ; In `info.el'
(defvar list-colors-sort) ; In `facemenu.el' (Emacs 23+)
(defvar palette-current-color) ; In `palette.el'
(defvar palette-last-color) ; In `palette.el'
(defvar palette-mode-map) ; In `palette.el'
(defvar palette-popup-map) ; In `palette.el'
(defvar proced-signal-list) ; In `proced.el' (Emacs 23+)
(defvar read-file-name-completion-ignore-case) ; In `minibuffer.el'
(defvar synonyms-obarray) ; In `synonyms.el'
(defvar tags-case-fold-search) ; In `etags.el'
(defvar yow-after-load-message)
(defvar yow-file)
(defvar yow-load-message)
;; (> emacs-major-version 21)
(defvar Info-saved-nodes) ; In `info+.el'
;; (< emacs-major-version 23)
(defvar read-buffer-completion-ignore-case)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;(@* "Icicles Commands for Other Packages")
;;; Icicles Commands for Other Packages ------------------------------
;; Same as the definition in `icicles-face.el'.
(defmacro icicle-maybe-byte-compile-after-load (function)
"Byte-compile FUNCTION if `icicle-byte-compile-eval-after-load-flag'.
Do nothing if FUNCTION has not been defined (`fboundp')."
`(when (and icicle-byte-compile-eval-after-load-flag (fboundp ',function))
(require 'bytecomp)
(let ((byte-compile-warnings ())
(byte-compile-verbose nil))
(byte-compile ',function))))
(defun icicle-cmd2-after-load-bookmark+ ()
"Things to do for `icicles-cmd2.el' after loading `bookmark+.el'."
(icicle-define-file-command icicle-bookmark-a-file ; `C-x p c a'
"Bookmark a file (create an autofile bookmark).
\(You need library `Bookmark+' for this command.)
When prompted for the file you can use `M-n' to pick up the file name
at point, or if none then the visited file.
The autofile bookmark created has the same name as the file.
During file-name completion:
You can use `C-x a +' or `C-x a -' to add or remove tags from the
current-candidate file. You are prompted for the tags.
(This action requires library `Bookmark+'.)
You can use `C-c C-d' (a la `cd') to change the `default-directory'.
You can use `C-c +' to create a new directory.
You can use `M-|' to open Dired on currently matching file names.
You can use `S-delete' to delete a candidate file or (empty) dir."
(lambda (file) (bmkp-bookmark-a-file file nil nil 'MSG))
"File to bookmark (autofile): " nil nil nil nil nil ; `read-file-name' args
(icicle-file-bindings ; Bindings
((icicle-use-candidates-only-once-flag t)
(icicle-all-candidates-list-alt-action-fn ; `M-|'
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
(icicle-bind-file-candidate-keys) ; First code
nil ; Undo code
(icicle-unbind-file-candidate-keys)) ; Last code
(icicle-maybe-byte-compile-after-load icicle-bookmark-a-file)
(icicle-define-file-command icicle-tag-a-file ; `C-x p t + a'
"Tag a file (an autofile bookmark) with one or more tags.
You are prompted for the tags, then the file name.
Hit `RET' to enter each tag, then hit `RET' again after the last tag.
You can use completion to enter each tag. Completion is lax: you are
not limited to existing tags.
When prompted for the file you can use `M-n' to pick up the file name
at point, or if none then the visited file.
The tags are added to an autofile bookmark for the same file name and
directory. If the bookmark does not yet exist it is created.
Candidate help shows information about the file's autofile bookmark if
it already exists, or the file itself if not."
(lambda (file) (bmkp-autofile-add-tags file tags nil nil 'MSG))
"File to tag: " nil nil nil nil nil ; `read-file-name' args
(icicle-file-bindings ; Bindings
((tags (bmkp-read-tags-completing))
(icicle-use-candidates-only-once-flag t))))
(icicle-maybe-byte-compile-after-load icicle-tag-a-file)
(icicle-define-file-command icicle-untag-a-file ; `C-x p t - a'
"Remove one or more tags from a file (an autofile bookmark).
You are prompted for the tags, then the file name.
Hit `RET' to enter each tag, then hit `RET' again after the last tag.
You can use completion to enter each tag. Completion is lax: you are
not limited to existing tags.
When prompted for the file you can use `M-n' to pick up the file name
at point, or if none then the visited file.
The tags are removed from an autofile bookmark for the same file name
and directory. During file-name completion, only files tagged with
all of the given input tags are completion candidates."
(lambda (file)
(bmkp-autofile-remove-tags file tags nil nil 'MSG))
"File to untag: " nil nil t nil nil ; `read-file-name' args
(icicle-file-bindings ; Bindings
((tags (bmkp-read-tags-completing)) ; Pre bindings
(icicle-use-candidates-only-once-flag t))
((icicle-must-pass-after-match-predicate ; Post bindings
#'(lambda (ff)
;; Expand relative file name, using directory from minibuffer.
(setq ff (expand-file-name ff (icicle-file-name-directory-w-default
(icicle-input-from-minibuffer))))
(let* ((bmk (bmkp-get-autofile-bookmark ff))
(btgs (and bmk (bmkp-get-tags bmk))))
(and btgs (catch 'icicle-untag-a-file
(dolist (tag tags) (when (not (member tag btgs))
(throw 'icicle-untag-a-file nil)))
t))))))))
(icicle-maybe-byte-compile-after-load icicle-untag-a-file)
;;$$$ Do not bother with autofiles that have a PREFIX.
(icicle-define-command icicle-find-file-tagged ; `C-x j t a a'.
"Find one or more files with tags that match your input.
By default, only tagged files are candidates. With a prefix argument,
all autofiles are candidates. (Autofiles are autofile bookmarks - you
need library `Bookmark+' for this command.)
Each completion candidate is a multi-completion composed of these
fields: an absolute file name plus the file's tags, all separated by
`icicle-list-join-string' (\"^G^J\", by default). As always, you can
type `C-M-j' to insert this separator into the minibuffer.
For this command, by default `.' in your input matches any character,
including a newline. As always, you can use `C-M-.' to toggle
this (so `.' does not match newline).
You can match your input against the file name or tags or both.
E.g., type:
`red S-TAB' to match all files with the tag `red'
`red M-SPC green M-SPC blue' to match all files with tags `red',
`green', and `blue' (in any order)
That assumes that these tags do not also match any file names.
If you need to match against a particular field (e.g. the file name or
a specific tag position), then use the field separator. Otherwise,
just use progressive completion, as shown above.
E.g., to match only tags and not the filename, start with `C-M-j' to
get past the file-name field. To match both file name and tags, type
something to match the file name before the `C-M-j'. E.g., type:
`2011 C-M-j red M-SPC blue' to match all files tagged `red' and
`blue' that have `2011' in their names
During completion (`*': requires library `Bookmark+'):
*You can use `C-x a +' or `C-x a -' to add or remove tags from the
current-candidate file. You are prompted for the tags.
*You can use `C-x m' to access file bookmarks (not just autofiles).
You can use `C-c C-d' (a la `cd') to change the `default-directory'.
You can use `C-c +' to create a new directory.
You can use `M-|' to open Dired on currently matching file names.
You can use `S-delete' to delete a candidate file or (empty) dir." ; Doc string
(lambda (f) (find-file (icicle-transform-multi-completion f) 'WILDCARDS)) ; Action function
prompt icicle-abs-file-candidates ; `completing-read' args
nil nil nil 'icicle-filetags-history nil nil
(icicle-file-bindings ; Bindings
((prompt "FILE `C-M-j' TAGS: ")
(icicle-full-cand-fn (lambda (file)
(list (cons file
(bmkp-get-tags
(bmkp-get-autofile-bookmark file))))))
(icicle-abs-file-candidates ; An alist whose items are ((FILE TAG...)).
(let ((result ()))
(dolist (autofile (bmkp-autofile-alist-only))
(let ((tags (bmkp-get-tags autofile)))
(when (or tags current-prefix-arg)
(push (list (cons (bookmark-get-filename autofile) tags)) result))))
result))
(icicle-dot-string (icicle-anychar-regexp))
(icicle-candidate-properties-alist '((1 (face icicle-candidate-part))))
(icicle-list-use-nth-parts '(1))
(icicle-whole-candidate-as-text-prop-p t)))
(progn ; First code
(put-text-property 0 1 'icicle-fancy-candidates t prompt)
(icicle-highlight-lighter)
(message "Gathering tagged files...")
(icicle-bind-file-candidate-keys))
nil ; Undo code
(icicle-unbind-file-candidate-keys)) ; Last code
(icicle-maybe-byte-compile-after-load icicle-find-file-tagged)
(icicle-define-command icicle-find-file-tagged-other-window ; `C-x 4 j t a a'
"Same as `icicle-find-file-tagged', except uses another window." ; Doc string
(lambda (f) (find-file-other-window (icicle-transform-multi-completion f) 'WILDCARDS)) ; Action
prompt icicle-abs-file-candidates ; `completing-read' args
nil nil nil 'icicle-filetags-history nil nil
(icicle-file-bindings ; Bindings
((prompt "FILE `C-M-j' TAGS: ")
(icicle-full-cand-fn (lambda (file)
(list (cons file
(bmkp-get-tags
(bmkp-get-autofile-bookmark file))))))
(icicle-abs-file-candidates ; An alist whose items are ((FILE TAG...)).
(let ((result ()))
(dolist (autofile (bmkp-autofile-alist-only))
(let ((tags (bmkp-get-tags autofile)))
(when (or tags current-prefix-arg)
(push (list (cons (bookmark-get-filename autofile) tags)) result))))
result))
(icicle-dot-string (icicle-anychar-regexp))
(icicle-candidate-properties-alist '((1 (face icicle-candidate-part))))
(icicle-list-use-nth-parts '(1))
(icicle-whole-candidate-as-text-prop-p t)))
(progn ; First code
(put-text-property 0 1 'icicle-fancy-candidates t prompt)
(icicle-highlight-lighter)
(message "Gathering tagged files...")
(icicle-bind-file-candidate-keys))
nil ; Undo code
(icicle-unbind-file-candidate-keys)) ; Last code
(icicle-maybe-byte-compile-after-load icicle-find-file-tagged-other-window)
;;; These are like multi-command versions of `bmkp-find-file-all-tags' etc.,
;;; except that the predicate is applied after matching the user's input
;;; (`icicle-must-pass-after-match-predicate').
(icicle-define-file-command icicle-find-file-all-tags ; `C-x j t a *'
"Visit a file or directory that has all of the tags you enter.
This is otherwise like `icicle-find-file'.
You are prompted for the tags, then the file name.
Hit `RET' to enter each tag, then hit `RET' again after the last tag.
You can use completion to enter each tag. Completion is lax: you are
not limited to existing tags.
When prompted for the file you can use `M-n' to pick up the file name
at point, or if none then the visited file."
(lambda (file) ; Function to perform the action
(let* ((r-o (if (eq this-command 'icicle-candidate-action)
(or (and init-pref-arg (not current-prefix-arg))
(and (not init-pref-arg) current-prefix-arg))
init-pref-arg))
(fn (if r-o 'find-file-read-only 'find-file)))
(funcall fn file 'WILDCARDS)))
"Find file: " nil nil t nil nil
(icicle-file-bindings ; Bindings
((init-pref-arg current-prefix-arg) ; Pre bindings
(tags (bmkp-read-tags-completing))
(icicle-all-candidates-list-alt-action-fn ; `M-|'
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ") files))))))
((icicle-must-pass-after-match-predicate ; Post bindings
(lambda (ff) (let* ((bmk (bmkp-get-autofile-bookmark ff))
(btgs (and bmk (bmkp-get-tags bmk))))
(and btgs (bmkp-every #'(lambda (tag) (bmkp-has-tag-p bmk tag)) tags))))))))
(icicle-maybe-byte-compile-after-load icicle-find-file-all-tags)
(icicle-define-file-command icicle-find-file-all-tags-other-window ; `C-x 4 j t a *'
"Same as `icicle-find-file-all-tags', except uses another window."
(lambda (file) ; Function to perform the action
(let* ((r-o (if (eq this-command 'icicle-candidate-action)
(or (and init-pref-arg (not current-prefix-arg))
(and (not init-pref-arg) current-prefix-arg))
init-pref-arg))
(fn (if r-o 'find-file-read-only-other-window 'find-file-other-window)))
(funcall fn file 'WILDCARDS)))
"Find file: " nil nil t nil nil
(icicle-file-bindings ; Bindings
((init-pref-arg current-prefix-arg) ; Pre bindings
(tags (bmkp-read-tags-completing))
(icicle-all-candidates-list-alt-action-fn ; `M-|'
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ") files))))))
((icicle-must-pass-after-match-predicate ; Post bindings
(lambda (ff) (let* ((bmk (bmkp-get-autofile-bookmark ff))
(btgs (and bmk (bmkp-get-tags bmk))))
(and btgs (bmkp-every #'(lambda (tag) (bmkp-has-tag-p bmk tag)) tags))))))))
(icicle-maybe-byte-compile-after-load icicle-find-file-all-tags-other-window)
(icicle-define-file-command icicle-find-file-all-tags-regexp ; `C-x j t a % *'
"Visit a file or directory that has each tag matching a regexp you enter.
When prompted for the file you can use `M-n' to pick up the file name
at point, or if none then the visited file."
(lambda (file) ; Function to perform the action
(let* ((r-o (if (eq this-command 'icicle-candidate-action)
(or (and init-pref-arg (not current-prefix-arg))
(and (not init-pref-arg) current-prefix-arg))
init-pref-arg))
(fn (if r-o 'find-file-read-only 'find-file)))
(funcall fn file 'WILDCARDS)))
"Find file: " nil nil t nil nil
(icicle-file-bindings ; Bindings
((init-pref-arg current-prefix-arg) ; Pre bindings
(regexp (read-string "Regexp for tags: "))
(icicle-all-candidates-list-alt-action-fn ; `M-|'
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ") files))))))
((icicle-must-pass-after-match-predicate ; Post bindings
(lambda (ff)
(let* ((bmk (bmkp-get-autofile-bookmark ff))
(btgs (and bmk (bmkp-get-tags bmk))))
(and btgs (bmkp-every #'(lambda (tag) (string-match regexp (bmkp-tag-name tag)))
btgs))))))))
(icicle-maybe-byte-compile-after-load icicle-find-file-all-tags-regexp)
(icicle-define-file-command icicle-find-file-all-tags-regexp-other-window ; `C-x 4 j t a % *'
"Same as `icicle-find-file-all-tags-regexp', except uses another window."
(lambda (file) ; Function to perform the action
(let* ((r-o (if (eq this-command 'icicle-candidate-action)
(or (and init-pref-arg (not current-prefix-arg))
(and (not init-pref-arg) current-prefix-arg))
init-pref-arg))
(fn (if r-o 'find-file-read-only-other-window 'find-file-other-window)))
(funcall fn file 'WILDCARDS)))
"Find file: " nil nil t nil nil
(icicle-file-bindings ; Bindings
((init-pref-arg current-prefix-arg) ; Pre bindings
(regexp (read-string "Regexp for tags: "))
(icicle-all-candidates-list-alt-action-fn ; `M-|'
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ") files))))))
((icicle-must-pass-after-match-predicate ; Post bindings
(lambda (ff)
(let* ((bmk (bmkp-get-autofile-bookmark ff))
(btgs (and bmk (bmkp-get-tags bmk))))
(and btgs (bmkp-every #'(lambda (tag) (string-match regexp (bmkp-tag-name tag)))
btgs))))))))
(icicle-maybe-byte-compile-after-load icicle-find-file-all-tags-regexp-other-window)
(icicle-define-file-command icicle-find-file-some-tags ; `C-x j t a +'
"Visit a file or directory that has at least one of the tags you enter.
This is otherwise like `icicle-find-file'.
You are prompted for the tags, then the file name.
Hit `RET' to enter each tag, then hit `RET' again after the last tag.
You can use completion to enter each tag. Completion is lax: you are
not limited to existing tags.
When prompted for the file you can use `M-n' to pick up the file name
at point, or if none then the visited file."
(lambda (file) ; Function to perform the action
(let* ((r-o (if (eq this-command 'icicle-candidate-action)
(or (and init-pref-arg (not current-prefix-arg))
(and (not init-pref-arg) current-prefix-arg))
init-pref-arg))
(fn (if r-o 'find-file-read-only 'find-file)))
(funcall fn file 'WILDCARDS)))
"Find file: " nil nil t nil nil
(icicle-file-bindings ; Bindings
((init-pref-arg current-prefix-arg) ; Pre bindings
(tags (bmkp-read-tags-completing))
(icicle-all-candidates-list-alt-action-fn ; `M-|'
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ") files))))))
((icicle-must-pass-after-match-predicate ; Post bindings
(lambda (ff) (let* ((bmk (bmkp-get-autofile-bookmark ff))
(btgs (and bmk (bmkp-get-tags bmk))))
(and btgs (bmkp-some #'(lambda (tag) (bmkp-has-tag-p bmk tag)) tags))))))))
(icicle-maybe-byte-compile-after-load icicle-find-file-some-tags)
(icicle-define-file-command icicle-find-file-some-tags-other-window ; `C-x 4 j t a +'
"Same as `icicle-find-file-some-tags', except uses another window."
(lambda (file) ; Function to perform the action
(let* ((r-o (if (eq this-command 'icicle-candidate-action)
(or (and init-pref-arg (not current-prefix-arg))
(and (not init-pref-arg) current-prefix-arg))
init-pref-arg))
(fn (if r-o 'find-file-read-only-other-window 'find-file-other-window)))
(funcall fn file 'WILDCARDS)))
"Find file: " nil nil t nil nil
(icicle-file-bindings ; Bindings
((init-pref-arg current-prefix-arg) ; Pre bindings
(tags (bmkp-read-tags-completing))
(icicle-all-candidates-list-alt-action-fn ; `M-|'
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ") files))))))
((icicle-must-pass-after-match-predicate ; Post bindings
(lambda (ff) (let* ((bmk (bmkp-get-autofile-bookmark ff))
(btgs (and bmk (bmkp-get-tags bmk))))
(and btgs (bmkp-some #'(lambda (tag) (bmkp-has-tag-p bmk tag)) tags))))))))
(icicle-maybe-byte-compile-after-load icicle-find-file-some-tags-other-window)
(icicle-define-file-command icicle-find-file-some-tags-regexp ; `C-x j t a % +'
"Visit a file or directory that has a tag matching a regexp you enter.
When prompted for the file you can use `M-n' to pick up the file name
at point, or if none then the visited file."
(lambda (file) ; Function to perform the action
(let* ((r-o (if (eq this-command 'icicle-candidate-action)
(or (and init-pref-arg (not current-prefix-arg))
(and (not init-pref-arg) current-prefix-arg))
init-pref-arg))
(fn (if r-o 'find-file-read-only 'find-file)))
(funcall fn file 'WILDCARDS)))
"Find file: " nil nil t nil nil
(icicle-file-bindings ; Bindings
((init-pref-arg current-prefix-arg) ; Pre bindings
(regexp (read-string "Regexp for tags: "))
(icicle-all-candidates-list-alt-action-fn ; `M-|'
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ") files))))))
((icicle-must-pass-after-match-predicate ; Post bindings
(lambda (ff)
(let* ((bmk (bmkp-get-autofile-bookmark ff))
(btgs (and bmk (bmkp-get-tags bmk))))
(and btgs (bmkp-some #'(lambda (tag) (string-match regexp (bmkp-tag-name tag)))
btgs))))))))
(icicle-maybe-byte-compile-after-load icicle-find-file-some-tags-regexp)
(icicle-define-file-command icicle-find-file-some-tags-regexp-other-window ; `C-x 4 j t a % +'
"Same as `icicle-find-file-some-tags-regexp', except uses another window."
(lambda (file) ; Function to perform the action
(let* ((r-o (if (eq this-command 'icicle-candidate-action)
(or (and init-pref-arg (not current-prefix-arg))
(and (not init-pref-arg) current-prefix-arg))
init-pref-arg))
(fn (if r-o 'find-file-read-only-other-window 'find-file-other-window)))
(funcall fn file 'WILDCARDS)))
"Find file: " nil nil t nil nil
(icicle-file-bindings ; Bindings
((init-pref-arg current-prefix-arg) ; Pre bindings
(regexp (read-string "Regexp for tags: "))
(icicle-all-candidates-list-alt-action-fn ; `M-|'
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ") files))))))
((icicle-must-pass-after-match-predicate ; Post bindings
(lambda (ff)
(let* ((bmk (bmkp-get-autofile-bookmark ff))
(btgs (and bmk (bmkp-get-tags bmk))))
(and btgs (bmkp-some #'(lambda (tag) (string-match regexp (bmkp-tag-name tag)))
btgs))))))))
(icicle-maybe-byte-compile-after-load icicle-find-file-some-tags-regexp-other-window)
)
(defun icicle-cmd2-after-load-hexrgb ()
"Things to do for `icicles-cmd2.el' after loading `hexrgb.el'."
(when (and (fboundp 'read-color) (not (fboundp 'old-read-color))) ; Exists with Emacs 23+.
(defalias 'old-read-color (symbol-function 'read-color))) ; Not used, but save it anyway.
;; See also `hexrgb-read-color' in `hexrgb.el'.
(defun icicle-read-color (&optional prompt convert-to-RGB-p allow-empty-name-p msgp)
"Read a color name or hex RGB hexadecimal color value #RRRRGGGGBBBB.
Return the name or the RGB hex string for the chosen color.
By default (see option `icicle-functions-to-redefine'), this is used
in place of standard command `read-color' when you are in Icicle mode,
so that any existing code that calls that command invokes this one
instead.
`icicle-read-color' has the advantage of being an Icicles
multi-command that provides WYSIWYG completion, color-variable proxy
candidates, alternate candidate actions, candidate help, and multiple
color-related candidate sort orders.
In this it is like command `icicle-read-color-wysiwyg' (which see),
but it is less flexible and powerful than that command.
`icicle-read-color' always returns the RGB hex string, and your input
cannot be an arbitrary string - it must match a color candidate (or be
empty if ALLOW-EMPTY-NAME-P is non-nil).
In Lisp code that you write, and for interactive use,
`icicle-read-color-wysiwyg' is generally a better choice than
`icicle-read-color'.
Optional argument PROMPT is the prompt to use (default \"Color: \").
Interactively, or if CONVERT-TO-RGB-P is non-nil, return the RGB hex
string for the chosen color. If nil, return the color name.
Optional arg ALLOW-EMPTY-NAME-P controls what happens if you enter an
empty color name (that is, you just hit `RET'). If non-nil, then
`icicle-read-color' returns an empty color name, \"\". If nil, then
it raises an error. Calling programs must test for \"\" if
ALLOW-EMPTY-NAME-P is non-nil. They can then perform an appropriate
action in case of empty input.
Interactively, or with non-nil MSGP, show chosen color in echo area."
(interactive "i\np\ni\np") ; Always convert to RGB interactively.
(let* ((icicle-require-match-p (not allow-empty-name-p))
(color (icicle-read-color-wysiwyg (if convert-to-RGB-p 2 1) prompt)))
(when (and (not allow-empty-name-p) (string= "" color))
(error "No such color: %S" color))
(let ((icicle-list-use-nth-parts (if convert-to-RGB-p '(2) '(1)))
(colr (icicle-transform-multi-completion color)))
(when msgp (message "Color: `%s'" (icicle-propertize colr 'face 'icicle-msg-emphasis)))
colr)))
(defun icicle-read-color-wysiwyg (&optional arg prompt msgp)
"Read a color name or hex RGB color value #RRRRGGGGBBBB.
Return a string value.
Interactively, optional argument ARG is the prefix arg.
Optional argument PROMPT is the prompt to use (default \"Color: \").
Interactively, or with non-nil MSGP, show chosen color in echo area.
In addition to standard color names and RGB (red, green, blue) hex
values, the following are also available as proxy color candidates,
provided `icicle-add-proxy-candidates-flag' is non-nil and library
`palette.el' or `eyedropper.el' is used. In each case, the
corresponding color is used.
* `*copied foreground*' - last copied foreground, if available
* `*copied background*' - last copied background, if available
* `*mouse-2 foreground*' - foreground where you click `mouse-2'
* `*mouse-2 background*' - background where you click `mouse-2'
* `*point foreground*' - foreground under the text cursor
* `*point background*' - background under the text cursor
\(You can copy a color using eyedropper commands such as
`eyedrop-pick-foreground-at-mouse'.)
In addition, the names of user options (variables) whose custom type
is `color' are also proxy candidates, but with `'' as a prefix and
suffix. So, for example, option `icicle-region-background' appears as
proxy color candidate `'icicle-region-background''.
As always, you can toggle the use of proxy candidates using `\\<minibuffer-local-completion-map>\
\\[icicle-toggle-proxy-candidates]' in
the minibuffer.
With plain `C-u', use `hexrgb-read-color', which lets you complete a
color name or input any valid RGB hex value (without completion).
With no prefix arg, return a string with both the color name and the
RGB value, separated by `icicle-list-nth-parts-join-string'.
With a numeric prefix arg of 0 or 1, return the color name. With any
other numeric prefix arg, return the RGB value.
In the plain `C-u' case, your input is checked to ensure that it
represents a valid color.
In all other cases:
- You can complete your input against the color name, the RGB value,
or both.
- If you enter input without completing or cycling, the input is not
checked: whatever is entered is returned as the string value.
From Emacs Lisp, ARG controls what is returned. If ARG is nil,
`icicle-list-use-nth-parts' can also be used to control the behavior.
Note: Duplicate color names are removed by downcasing and removing
whitespace. For example, \"AliceBlue\" and \"alice blue\" are both
treated as \"aliceblue\". Otherwise, candidates with different names
but the same RGB values are not considered duplicates, so, for
example, input can match either \"darkred\" or \"red4\", which both
have RGB #8b8b00000000. You can toggle duplicate removal at any time
using `C-$'.
During completion, candidate help (e.g. `C-M-RET') shows you the RGB
and HSV (hue, saturation, value) color components.
This command is intended only for use in Icicle mode (but it can be
used with `C-u', with Icicle mode turned off)."
(interactive "P\ni\np")
(unless (featurep 'hexrgb) (error "`icicle-read-color-wysiwyg' requires library `hexrgb.el'"))
(let (color)
(if (consp arg) ; Plain `C-u': complete against color name only, and be able to
(setq color (hexrgb-read-color nil 'CONVERT-TO-RGB)) ; input any valid RGB string.
;; Complete against name+RGB pairs, but user can enter invalid value without completing.
(let ((icicle-list-use-nth-parts
(or (and arg (if (< arg 2) '(1) '(2))) ; 1 or 2, by program or via `C-1' or `C-2'.
icicle-list-use-nth-parts ; Bound externally by program.
'(1 2))) ; Both parts, by default.
(mouse-pseudo-color-p nil)
icicle-candidate-help-fn completion-ignore-case
icicle-transform-function icicle-sort-orders-alist
icicle-list-nth-parts-join-string icicle-list-join-string
;; $$$$$$ icicle-list-end-string
icicle-proxy-candidate-regexp icicle-named-colors
icicle-proxy-candidates)
;; Copy the prompt string because `icicle-color-completion-setup' puts a text prop on it.
;; Use `icicle-prompt' from now on, since that's what `icicle-color-completion-setup'
;; sets up.
(setq icicle-prompt (copy-sequence (or prompt "Color: ")))
(icicle-color-completion-setup)
(setq icicle-proxy-candidates
(append icicle-proxy-candidates
(mapcar ; Convert multi-completions to strings.
;; $$$$$$ #'(lambda (entry)
;; (concat (mapconcat #'identity (car entry)
;; icicle-list-join-string)
;; icicle-list-end-string)) ; $$$$$$
#'(lambda (entry) (mapconcat #'identity (car entry)
icicle-list-join-string))
'((("*mouse-2 foreground*")) (("*mouse-2 background*")))))
color (icicle-transform-multi-completion
(let ((icicle-orig-window (selected-window))
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn
(icicle-alt-act-fn-for-type "color")))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn
(icicle-alt-act-fn-for-type "color"))))
(completing-read icicle-prompt icicle-named-colors))))
(when (fboundp 'eyedrop-foreground-at-point)
(cond ((string-match "^\*mouse-2 foreground\*" color)
(setq color (prog1 (eyedrop-foreground-at-mouse
(read-event
"Click `mouse-2' anywhere to choose foreground color"))
(read-event)) ; Discard mouse up event.
mouse-pseudo-color-p t))
((string-match "^\*mouse-2 background\*" color)
(setq color (prog1 (eyedrop-background-at-mouse
(read-event
"Click `mouse-2' anywhere to choose background color"))
(read-event)) ; Discard mouse up event.
mouse-pseudo-color-p t))))
(when mouse-pseudo-color-p
(let ((icicle-list-nth-parts-join-string ": ")
(icicle-list-join-string ": ")
;; $$$$$$ (icicle-list-end-string "")
(icicle-list-use-nth-parts
(or (and arg
(if (< arg 2) '(1) '(2))) ; 1 or 2, by program or via `C-1' or `C-2'.
icicle-list-use-nth-parts ; Bound externally by program.
'(1 2)))) ; Both parts, by default.
(setq color (icicle-transform-multi-completion
(concat color ": " (hexrgb-color-name-to-hex color))))))))
(when msgp (message "Color: `%s'" (icicle-propertize color 'face 'icicle-msg-emphasis)))
color))
(icicle-maybe-byte-compile-after-load icicle-read-color-wysiwyg)
(icicle-define-command icicle-frame-bg ; Command name
"Change background of current frame.
Read color name or hex RGB color value #RRRRGGGGBBBB with completion.
In addition to standard color names and RGB (red, green, blue) hex
values, the following are also available as proxy color candidates,
provided `icicle-add-proxy-candidates-flag' is non-nil and library
`palette.el' or `eyedropper.el' is used. In each case, the
corresponding color is used.
* `*copied foreground*' - last copied foreground, if available
* `*copied background*' - last copied background, if available
* `*point foreground*' - foreground under the text cursor
* `*point background*' - background under the text cursor
\(You can copy a color using eyedropper commands such as
`eyedrop-pick-foreground-at-mouse'.)
In addition, the names of user options (variables) whose custom type
is `color' are also proxy candidates, but with `'' as a prefix and
suffix. So, for example, option `icicle-region-background' appears as
proxy color candidate `'icicle-region-background''.
As always, you can toggle the use of proxy candidates using `\\<minibuffer-local-completion-map>\
\\[icicle-toggle-proxy-candidates]' in
the minibuffer.
You can complete your input against the color name, the RGB value, or
both.
Note: Duplicate color names are removed by downcasing and removing
whitespace. For example, \"AliceBlue\" and \"alice blue\" are both
treated as \"aliceblue\". Otherwise, candidates with different names
but the same RGB values are not considered duplicates, so, for
example, input can match either \"darkred\" or \"red4\", which both
have RGB #8b8b00000000. You can toggle duplicate removal at any time
using `C-$'.
During completion, candidate help (e.g. `C-M-RET') shows you the RGB
and HSV (hue, saturation, value) color components.
This command is intended only for use in Icicle mode." ; Doc string
(lambda (color) ; Action function
(modify-frame-parameters
icicle-orig-frame (list (cons 'background-color (icicle-transform-multi-completion color)))))
icicle-prompt icicle-named-colors nil t nil ; `completing-read' args
(if (boundp 'color-history) 'color-history 'icicle-color-history) nil nil
((icicle-orig-frame (selected-frame)) ; Bindings
(orig-bg (frame-parameter nil 'background-color))
(icicle-prompt "Background color: ")
(icicle-list-use-nth-parts '(2)) ; Use RGB part.
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "color")))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "color")))
icicle-candidate-help-fn completion-ignore-case icicle-transform-function
icicle-sort-orders-alist icicle-list-nth-parts-join-string icicle-list-join-string
;; $$$$$$ icicle-list-end-string
icicle-proxy-candidate-regexp icicle-named-colors icicle-proxy-candidates)
(icicle-color-completion-setup) ; First code - needs `hexrgb.el'
(modify-frame-parameters icicle-orig-frame (list (cons 'background-color orig-bg))) ; Undo code
nil) ; Last code
(icicle-maybe-byte-compile-after-load icicle-frame-bg)
(icicle-define-command icicle-frame-fg ; Command name
"Change foreground of current frame.
See `icicle-frame-bg' - but this is for foreground, not background." ; Doc string
(lambda (color) ; Action function
(modify-frame-parameters
icicle-orig-frame (list (cons 'foreground-color (icicle-transform-multi-completion color)))))
icicle-prompt icicle-named-colors nil t nil ; `completing-read' args
(if (boundp 'color-history) 'color-history 'icicle-color-history) nil nil
((icicle-orig-frame (selected-frame)) ; Bindings
(orig-bg (frame-parameter nil 'foreground-color))
(icicle-prompt "Foreground color: ")
(icicle-list-use-nth-parts '(2)) ; Use RGB part.
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "color")))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "color")))
icicle-candidate-help-fn completion-ignore-case icicle-transform-function
icicle-sort-orders-alist icicle-list-nth-parts-join-string icicle-list-join-string
;; $$$$$$ icicle-list-end-string
icicle-proxy-candidate-regexp icicle-named-colors icicle-proxy-candidates)
(icicle-color-completion-setup) ; First code - needs `hexrgb.el'
(modify-frame-parameters icicle-orig-frame (list (cons 'foreground-color orig-bg))) ; Undo code
nil) ; Last code
(icicle-maybe-byte-compile-after-load icicle-frame-fg)
;; Free vars here:
;; `icicle-prompt', `icicle-candidate-help-fn', `completion-ignore-case',
;; `icicle-transform-function', `icicle-sort-orders-alist', `icicle-list-nth-parts-join-string',
;; `icicle-list-join-string', `icicle-proxy-candidate-regexp', `icicle-named-colors',
;; `icicle-proxy-candidates'.
(defun icicle-color-completion-setup ()
"Set up for color-name/RGB-value completion (helper function).
Sets these variables, which are assumed to be already `let'-bound:
`icicle-prompt'
`icicle-candidate-help-fn'
`completion-ignore-case'
`icicle-transform-function'
`icicle-sort-orders-alist'
`icicle-list-nth-parts-join-string'
`icicle-list-join-string'
`icicle-proxy-candidate-regexp'
`icicle-named-colors'
`icicle-proxy-candidates'
Puts property `icicle-fancy-candidates' on string `icicle-prompt'."
(if (< emacs-major-version 22)
(require 'eyedropper nil t)
(or (require 'palette nil t) (require 'eyedropper nil t)))
(when (stringp icicle-prompt) ; Sanity check - should be true.
(put-text-property 0 1 'icicle-fancy-candidates t icicle-prompt))
(icicle-highlight-lighter)
(setq icicle-candidate-help-fn 'icicle-color-help
completion-ignore-case t
icicle-sort-orders-alist
'(("by color name" . icicle-part-1-lessp)
("by color hue" . (lambda (s1 s2) (not (icicle-color-hue-lessp s1 s2))))
("by color purity (saturation)"
. (lambda (s1 s2) (not (icicle-color-saturation-lessp s1 s2))))
("by color brightness (value)"
. (lambda (s1 s2) (not (icicle-color-value-lessp s1 s2))))
("by color hsv" . (lambda (s1 s2) (not (icicle-color-hsv-lessp s1 s2))))
("by hsv distance" . (lambda (s1 s2) (icicle-color-distance-hsv-lessp s1 s2)))
("by amount of red" . (lambda (s1 s2) (not (icicle-color-red-lessp s1 s2))))
("by amount of green" . (lambda (s1 s2) (not (icicle-color-green-lessp s1 s2))))
("by amount of blue" . (lambda (s1 s2) (not (icicle-color-blue-lessp s1 s2))))
("by color rgb" . (lambda (s1 s2) (not (icicle-color-rgb-lessp s1 s2))))
("by rgb distance" . (lambda (s1 s2) (icicle-color-distance-rgb-lessp s1 s2)))
("turned OFF"))
;; Make the two `*-join-string' variables the same, so past inputs are recognized.
;; Do not use " " as the value, because color names such as "white smoke" would be
;; split, and "smoke" would not be recognized as a color name when trying to list
;; candidates in `*Completions*'.
icicle-list-nth-parts-join-string ": "
icicle-list-join-string ": "
;; $$$$$$ icicle-list-end-string ""
icicle-proxy-candidate-regexp "^[*'].+[*']"
icicle-named-colors (mapcar #'icicle-make-color-candidate
(hexrgb-defined-colors))
icicle-proxy-candidates
(mapcar ; Convert multi-completions to strings.
(lambda (entry)
;; $$$$$$ (concat (mapconcat #'identity (car entry) icicle-list-join-string)
;; icicle-list-end-string) ; $$$$$$
(mapconcat #'identity (car entry) icicle-list-join-string))
(append
(and (fboundp 'eyedrop-foreground-at-point)
(append
(and eyedrop-picked-foreground ; Multi-completions.
`(,(icicle-make-color-candidate
"*copied foreground*" (downcase (hexrgb-color-name-to-hex
eyedrop-picked-foreground)))))
(and eyedrop-picked-background
`(,(icicle-make-color-candidate
"*copied background*" (downcase (hexrgb-color-name-to-hex
eyedrop-picked-background)))))
`(,(icicle-make-color-candidate
"*point foreground*" (downcase (hexrgb-color-name-to-hex
(eyedrop-foreground-at-point))))
,(icicle-make-color-candidate
"*point background*" (downcase (hexrgb-color-name-to-hex
(eyedrop-background-at-point)))))))
(let ((ipc ()))
(mapatoms
(lambda (cand)
(when (and (user-variable-p cand)
(condition-case nil (icicle-var-is-of-type-p cand '(color)) (error nil))
;; This should not be necessary, but type `color' isn't
;; enforced - it just means `string' (so far).
(x-color-defined-p (symbol-value cand)))
(push `,(icicle-make-color-candidate
(concat "'" (symbol-name cand) "'")
(downcase (hexrgb-color-name-to-hex (symbol-value cand))))
ipc))))
ipc)))))
(icicle-maybe-byte-compile-after-load icicle-color-completion-setup)
(defun icicle-color-help (color)
"Display help on COLOR.
COLOR is a color name, an RGB string, or a multi-completion of both.
If only a color name, then just say \"No help\"."
(if (not (member icicle-list-use-nth-parts '((1 2) (2))))
(icicle-msg-maybe-in-minibuffer "No help")
(with-output-to-temp-buffer "*Help*"
(princ (format "Color: %s" color)) (terpri) (terpri)
(let* ((icicle-list-use-nth-parts '(2))
(colr (icicle-transform-multi-completion color))
(rgb (hexrgb-hex-to-rgb colr))
(hsv (apply #'hexrgb-rgb-to-hsv rgb)))
(princ "RGB:")
(mapcar (lambda (component) (princ (format " %.18f" component))) rgb)
(terpri) (terpri)
(princ "HSV:")
(mapcar (lambda (component) (princ (format " %.18f" component))) hsv)))))
(icicle-maybe-byte-compile-after-load icicle-color-help)
(defun icicle-make-color-candidate (color-name &optional hex-rgb)
"Return multi-completion candidate of COLOR-NAME and its hex RGB string.
If `icicle-WYSIWYG-Completions-flag' is non-nil, then the hex RGB
string has the color as its background text property.
Optional arg HEX-RGB is the hex RGB string. If HEX-RGB is nil, then
COLOR-NAME is used to determine the hex RGB string."
(let* ((rgb-string (or hex-rgb (hexrgb-color-name-to-hex color-name)))
(value (hexrgb-value rgb-string)))
(when icicle-WYSIWYG-Completions-flag
(put-text-property 0 (length rgb-string) 'face
(list (cons 'foreground-color (if (< value 0.6) "White" "Black"))
(cons 'background-color rgb-string))
rgb-string))
(when (or (> icicle-help-in-mode-line-delay 0) ; Construct help only if user will see it.
(and (boundp 'tooltip-mode) tooltip-mode))
(let* ((rgb (hexrgb-hex-to-rgb rgb-string))
(hsv (apply #'hexrgb-rgb-to-hsv rgb))
(help (format "RGB: %.6f, %.6f, %.6f; HSV: %.6f, %.6f, %.6f"
(nth 0 rgb) (nth 1 rgb) (nth 2 rgb)
(nth 0 hsv) (nth 1 hsv) (nth 2 hsv))))
(icicle-candidate-short-help help color-name)
(icicle-candidate-short-help help rgb-string)))
(list (list color-name rgb-string))))
(icicle-maybe-byte-compile-after-load icicle-make-color-candidate)
;; This predicate is used for color completion.
(defun icicle-color-red-lessp (s1 s2)
"Non-nil means the RGB in S1 has less red than in S2.
The strings are assumed to have at least two parts, with the parts
separated by `icicle-list-join-string' The RGB values are assumed to
be the second parts of the strings, and they are assumed to start with
`#'."
(let ((rgb1 (elt (split-string s1 icicle-list-join-string) 1))
(rgb2 (elt (split-string s2 icicle-list-join-string) 1)))
(and rgb1 rgb2 ; Just in case strings were not multipart.
(< (hexrgb-red rgb1) (hexrgb-red rgb2)))))
(icicle-maybe-byte-compile-after-load icicle-color-red-lessp)
;; This predicate is used for color completion.
(defun icicle-color-green-lessp (s1 s2)
"Non-nil means the RGB in S1 has less green than in S2.
The strings are assumed to have at least two parts, with the parts
separated by `icicle-list-join-string' The RGB values are assumed to
be the second parts of the strings, and they are assumed to start with
`#'."
(let ((rgb1 (elt (split-string s1 icicle-list-join-string) 1))
(rgb2 (elt (split-string s2 icicle-list-join-string) 1)))
(and rgb1 rgb2 ; Just in case strings were not multipart.
(< (hexrgb-green rgb1) (hexrgb-green rgb2)))))
(icicle-maybe-byte-compile-after-load icicle-color-green-lessp)
;; This predicate is used for color completion.
(defun icicle-color-blue-lessp (s1 s2)
"Non-nil means the RGB in S1 has less blue than in S2.
The strings are assumed to have at least two parts, with the parts
separated by `icicle-list-join-string' The RGB values are assumed to
be the second parts of the strings, and they are assumed to start with
`#'."
(let ((rgb1 (elt (split-string s1 icicle-list-join-string) 1))
(rgb2 (elt (split-string s2 icicle-list-join-string) 1)))
(and rgb1 rgb2 ; Just in case strings were not multipart.
(< (hexrgb-blue rgb1) (hexrgb-blue rgb2)))))
(icicle-maybe-byte-compile-after-load icicle-color-blue-lessp)
;; This predicate is used for color completion.
(defun icicle-color-distance-rgb-lessp (s1 s2)
"Return non-nil if color S1 is RGB-closer than S2 to the base color.
S1 and S2 are color names (strings).
The base color name is the cdr of option `list-colors-sort', whose car
must be `rgb-dist'. If the option value is not already a cons with
car `rgb-dist' then it is made so: you are prompted for the base color
name to use."
(let* ((base-color (if (and (boundp 'list-colors-sort) ; Emacs 23+
(consp list-colors-sort) (eq 'rgb-dist (car list-colors-sort)))
(cdr list-colors-sort) ; `list-colors-sort' is free here.
(cdr (setq list-colors-sort
(cons 'rgb-dist
(let ((enable-recursive-minibuffers t)
(icicle-sort-comparer nil))
(icicle-read-color-wysiwyg ; Use the color name only.
0 "With RGB close to color: ")))))))
(base-rgb (hexrgb-hex-to-rgb (hexrgb-color-name-to-hex base-color)))
(base-red (nth 0 base-rgb))
(base-green (nth 1 base-rgb))
(base-blue (nth 2 base-rgb))
(s1-rgb (hexrgb-hex-to-rgb (elt (split-string s1 icicle-list-join-string) 1)))
(s2-rgb (hexrgb-hex-to-rgb (elt (split-string s2 icicle-list-join-string) 1))))
(< (+ (expt (- (nth 0 s1-rgb) base-red) 2)
(expt (- (nth 1 s1-rgb) base-green) 2)
(expt (- (nth 2 s1-rgb) base-blue) 2))
(+ (expt (- (nth 0 s2-rgb) base-red) 2)
(expt (- (nth 1 s2-rgb) base-green) 2)
(expt (- (nth 2 s2-rgb) base-blue) 2)))))
(icicle-maybe-byte-compile-after-load icicle-color-distance-rgb-lessp)
;; This predicate is used for color completion.
(defun icicle-color-hue-lessp (s1 s2)
"Non-nil means the RGB hue in S1 is less than that in S2.
The strings are assumed to have at least two parts, with the parts
separated by `icicle-list-join-string' The RGB values are assumed to
be the second parts of the strings, and they are assumed to start with
`#'."
(let ((rgb1 (elt (split-string s1 icicle-list-join-string) 1))
(rgb2 (elt (split-string s2 icicle-list-join-string) 1)))
(and rgb1 rgb2 ; Just in case strings were not multipart.
(< (hexrgb-hue rgb1) (hexrgb-hue rgb2)))))
(icicle-maybe-byte-compile-after-load icicle-color-hue-lessp)
;; This predicate is used for color completion.
(defun icicle-color-saturation-lessp (s1 s2)
"Non-nil means the RGB in S1 is less saturated than in S2.
The strings are assumed to have at least two parts, with the parts
separated by `icicle-list-join-string' The RGB values are assumed to
be the second parts of the strings, and they are assumed to start with
`#'."
(let ((rgb1 (elt (split-string s1 icicle-list-join-string) 1))
(rgb2 (elt (split-string s2 icicle-list-join-string) 1)))
(and rgb1 rgb2 ; Just in case strings were not multipart.
(< (hexrgb-saturation rgb1) (hexrgb-saturation rgb2)))))
(icicle-maybe-byte-compile-after-load icicle-color-saturation-lessp)
;; This predicate is used for color completion.
(defun icicle-color-value-lessp (s1 s2)
"Non-nil means the RGB value in S1 is darker than that in S2.
The strings are assumed to have at least two parts, with the parts
separated by `icicle-list-join-string' The RGB values are assumed to
be the second parts of the strings, and they are assumed to start with
`#'."
(let ((rgb1 (elt (split-string s1 icicle-list-join-string) 1))
(rgb2 (elt (split-string s2 icicle-list-join-string) 1)))
(and rgb1 rgb2 ; Just in case strings were not multipart.
(< (hexrgb-value rgb1) (hexrgb-value rgb2)))))
(icicle-maybe-byte-compile-after-load icicle-color-value-lessp)
;; This predicate is used for color completion.
(defun icicle-color-hsv-lessp (s1 s2)
"Non-nil means the HSV components of S1 are less than those of S2.
Specifically, the hues are compared first, then if hues are equal then
saturations are compared, then if those are also equal values are
compared.
The strings are assumed to have at least two parts, with the parts
separated by `icicle-list-join-string' The second parts of the strings
are RGB triplets that start with `#'."
(let* ((rgb1 (elt (split-string s1 icicle-list-join-string) 1))
(hsv1 (and rgb1 (hexrgb-hex-to-hsv rgb1)))
(rgb2 (elt (split-string s2 icicle-list-join-string) 1))
(hsv2 (and rgb2 (hexrgb-hex-to-hsv rgb2))))
(and hsv1 hsv2 ; Just in case strings were not multipart.
(or (< (nth 0 hsv1) (nth 0 hsv2))
(and (= (nth 0 hsv1) (nth 0 hsv2))
(< (nth 1 hsv1) (nth 1 hsv2)))
(and (= (nth 0 hsv1) (nth 0 hsv2))
(= (nth 1 hsv1) (nth 1 hsv2))
(< (nth 2 hsv1) (nth 2 hsv2)))))))
(icicle-maybe-byte-compile-after-load icicle-color-hsv-lessp)
;; This predicate is used for color completion.
(defun icicle-color-distance-hsv-lessp (s1 s2)
"Return non-nil if color S1 is HSV-closer than S2 to the base color.
S1 and S2 are color names (strings).
The base color name is the cdr of option `list-colors-sort', whose car
must be `hsv-dist'. If the option value is not already a cons with
car `hsv-dist' then it is made so: you are prompted for the base color
name to use."
(let* ((base-color (if (and (boundp 'list-colors-sort) ; Emacs 23+
(consp list-colors-sort) (eq 'hsv-dist (car list-colors-sort)))
(cdr list-colors-sort) ; `list-colors-sort' is free here.
(cdr (setq list-colors-sort
(cons 'hsv-dist
(let ((enable-recursive-minibuffers t)
(icicle-sort-comparer nil))
(icicle-read-color-wysiwyg ; Use the color name only.
0 "With HSV close to color: ")))))))
(base-hsv (hexrgb-hex-to-hsv (hexrgb-color-name-to-hex base-color)))
(base-hue (nth 0 base-hsv))
(base-sat (nth 1 base-hsv))
(base-val (nth 2 base-hsv))
(s1-hsv (apply #'hexrgb-rgb-to-hsv
(hexrgb-hex-to-rgb
(elt (split-string s1 icicle-list-join-string) 1))))
(s2-hsv (apply #'hexrgb-rgb-to-hsv
(hexrgb-hex-to-rgb
(elt (split-string s2 icicle-list-join-string) 1)))))
(< (+ (expt (- (nth 0 s1-hsv) base-hue) 2)
(expt (- (nth 1 s1-hsv) base-sat) 2)
(expt (- (nth 2 s1-hsv) base-val) 2))
(+ (expt (- (nth 0 s2-hsv) base-hue) 2)
(expt (- (nth 1 s2-hsv) base-sat) 2)
(expt (- (nth 2 s2-hsv) base-val) 2)))))
)
(defun icicle-cmd2-after-load-highlight ()
"Things to do for `icicles-cmd2.el' after loading `highlight.el'."
(when (fboundp 'next-single-char-property-change) ; Don't bother, for Emacs 20.
(icicle-define-command icicle-choose-faces
"Choose a list of face names (strings).
Option `hlt-act-on-any-face-flag' determines whether only highlighting
faces in the buffer are candidates. The list of names (strings) is
returned."
(lambda (name) (push name face-names)) ; Action function
prompt ; `completing-read' args
(mapcar #'icicle-make-face-candidate
(if hlt-act-on-any-face-flag
(face-list)
(hlt-highlight-faces-in-buffer (point-min) (point-max))))
nil (not (stringp icicle-WYSIWYG-Completions-flag)) nil
(if (boundp 'face-name-history) 'face-name-history 'icicle-face-name-history) nil nil
((icicle-list-nth-parts-join-string ": ") ; Additional bindings
(icicle-list-join-string ": ")
;; $$$$$$ (icicle-list-end-string "")
(icicle-list-use-nth-parts '(1))
(prompt (copy-sequence "Choose face (`RET' when done): "))
(face-names ()))
(put-text-property 0 1 'icicle-fancy-candidates t prompt) ; First code.
nil ; Undo code.
(prog1 (setq face-names (delete "" face-names)) ; Return the list of faces.
(when (interactive-p) (message "Faces: %S" face-names))))
(icicle-maybe-byte-compile-after-load icicle-choose-faces)
(icicle-define-command icicle-choose-invisible-faces
"Choose a list of face names (strings) from currently invisible faces.
Option `hlt-act-on-any-face-flag' determines whether only highlighting
faces in the buffer are candidates. The list of names (strings) is
returned."
(lambda (name) (push name face-names)) ; Action function
prompt ; `completing-read' args
(mapcar #'icicle-make-face-candidate
(icicle-remove-if-not #'icicle-invisible-face-p
(if hlt-act-on-any-face-flag
(face-list)
(hlt-highlight-faces-in-buffer (point-min) (point-max)))))
nil (not (stringp icicle-WYSIWYG-Completions-flag)) nil
(if (boundp 'face-name-history) 'face-name-history 'icicle-face-name-history) nil nil
((icicle-list-nth-parts-join-string ": ") ; Additional bindings
(icicle-list-join-string ": ")
;; $$$$$$ (icicle-list-end-string "")
(icicle-list-use-nth-parts '(1))
(prompt (copy-sequence "Choose face (`RET' when done): "))
(face-names ()))
(put-text-property 0 1 'icicle-fancy-candidates t prompt) ; First code.
nil ; Undo code.
(prog1 (setq face-names (delete "" face-names)) ; Return the list of faces.
(when (interactive-p) (message "Faces: %S" face-names))))
(icicle-maybe-byte-compile-after-load icicle-choose-invisible-faces)
(icicle-define-command icicle-choose-visible-faces
"Choose a list of face names (strings) from currently visible faces.
Option `hlt-act-on-any-face-flag' determines whether only highlighting
faces in the buffer are candidates. The list of names (strings) is
returned."
(lambda (name) (push name face-names)) ; Action function
prompt ; `completing-read' args
(mapcar #'icicle-make-face-candidate
(icicle-remove-if #'icicle-invisible-face-p
(if hlt-act-on-any-face-flag
(face-list)
(hlt-highlight-faces-in-buffer (point-min) (point-max)))))
nil (not (stringp icicle-WYSIWYG-Completions-flag)) nil
(if (boundp 'face-name-history) 'face-name-history 'icicle-face-name-history) nil nil
((icicle-list-nth-parts-join-string ": ") ; Additional bindings
(icicle-list-join-string ": ")
;; $$$$$$ (icicle-list-end-string "")
(icicle-list-use-nth-parts '(1))
(prompt (copy-sequence "Choose face (`RET' when done): "))
(face-names ()))
(put-text-property 0 1 'icicle-fancy-candidates t prompt) ; First code.
nil ; Undo code.
(prog1 (setq face-names (delete "" face-names)) ; Return the list of faces.
(when (interactive-p) (message "Faces: %S" face-names))))
(icicle-maybe-byte-compile-after-load icicle-choose-visible-faces)
(defun icicle-show-only-faces (&optional start end faces)
"Show only the faces you choose, hiding all others.
Non-nil `hlt-act-on-any-face-flag' means choose from among all
faces. Nil means choose only from among faces used to highlight.
When choosing faces, completion and cycling are available. During
cycling, these keys with prefix `C-' act on the current face name:
`C-mouse-2', `C-RET' - Choose current face candidate only
`C-down' - Choose, then move to next prefix-completion candidate
`C-up' - Choose, then move to previous prefix-completion candidate
`C-next' - Choose, then move to next apropos-completion candidate
`C-prior' - Choose, then move to previous apropos-completion candidate
`C-!' - Choose *all* matching face names"
(interactive `(,@(hlt-region-or-buffer-limits)
,(mapcar #'intern (icicle-choose-faces)))) ; An Icicles multi-command
(dolist (face (if hlt-act-on-any-face-flag
(face-list)
(hlt-highlight-faces-in-buffer start end)))
(if (memq face faces)
(hlt-show-default-face face)
(hlt-hide-default-face start end face))))
(icicle-maybe-byte-compile-after-load icicle-show-only-faces)
(defun icicle-hide-only-faces (&optional start end faces)
"Hide only the faces you choose, showing all others.
Non-nil `hlt-act-on-any-face-flag' means choose from among all
faces. Nil means choose only from among faces used to highlight.
When choosing faces, completion and cycling are available. During
cycling, these keys with prefix `C-' act on the current face name:
`C-mouse-2', `C-RET' - Choose current face candidate only
`C-down' - Choose, then move to next prefix-completion candidate
`C-up' - Choose, then move to previous prefix-completion candidate
`C-next' - Choose, then move to next apropos-completion candidate
`C-prior' - Choose, then move to previous apropos-completion candidate
`C-!' - Choose *all* matching face names"
(interactive `(,@(hlt-region-or-buffer-limits)
,(mapcar #'intern (icicle-choose-faces)))) ; An Icicles multi-command
(dolist (face (if hlt-act-on-any-face-flag
(face-list)
(hlt-highlight-faces-in-buffer start end)))
(if (memq face faces)
(hlt-hide-default-face start end face)
(hlt-show-default-face face))))
(icicle-maybe-byte-compile-after-load icicle-hide-only-faces)
(defun icicle-show-faces (faces)
"Show invisible faces that you choose. Do nothing to other faces.
Non-nil `hlt-act-on-any-face-flag' means choose from among all
invisible faces. Nil means choose only from among invisible faces
used to highlight.
When choosing faces, completion and cycling are available. During
cycling, these keys with prefix `C-' act on the current face name:
`C-mouse-2', `C-RET' - Choose current face candidate only
`C-down' - Choose, then move to next prefix-completion candidate
`C-up' - Choose, then move to previous prefix-completion candidate
`C-next' - Choose, then move to next apropos-completion candidate
`C-prior' - Choose, then move to previous apropos-completion candidate
`C-!' - Choose *all* matching face names"
(interactive
(list (let ((fs (icicle-remove-if-not #'icicle-invisible-face-p
(if hlt-act-on-any-face-flag
(face-list)
(hlt-highlight-faces-in-buffer
(point-min) (point-max))))))
(if fs
(mapcar #'intern (icicle-choose-invisible-faces)) ; An Icicles multi-command
(error "No%s faces are invisible"
(if hlt-act-on-any-face-flag "" " highlight"))))))
(dolist (face faces) (hlt-show-default-face face)))
(icicle-maybe-byte-compile-after-load icicle-show-faces)
(defun icicle-hide-faces (&optional start end faces)
"Hide visible faces that you choose. Do nothing to other faces.
Non-nil `hlt-act-on-any-face-flag' means choose from among all
visible faces. Nil means choose only from among visible faces used to
highlight.
When choosing faces, completion and cycling are available. During
cycling, these keys with prefix `C-' act on the current face name:
`C-mouse-2', `C-RET' - Choose current face candidate only
`C-down' - Choose, then move to next prefix-completion candidate
`C-up' - Choose, then move to previous prefix-completion candidate
`C-next' - Choose, then move to next apropos-completion candidate
`C-prior' - Choose, then move to previous apropos-completion candidate
`C-!' - Choose *all* matching face names"
(interactive `(,@(hlt-region-or-buffer-limits)
,(mapcar #'intern (icicle-choose-faces)))) ; An Icicles multi-command
(dolist (face faces) (hlt-hide-default-face start end face)))
(icicle-maybe-byte-compile-after-load icicle-hide-faces)
))
(defun icicle-cmd2-after-load-palette ()
"Things to do for `icicles-cmd2.el' after loading `palette.el'."
(icicle-define-command icicle-pick-color-by-name ; Bound to `c' in color palette.
"Set the current color to a color you name.
Instead of a color name, you can use an RGB string #XXXXXXXXXXXX,
where each X is a hex digit. The number of Xs must be a multiple of
3, with the same number of Xs for each of red, green, and blue.
If you enter an empty color name, then a color is picked randomly.
The new current color is returned." ; Doc string
icicle-pick-color-by-name-action ; Action function
"Color (name or #R+G+B+): " ; `completing-read' arguments
(hexrgb-defined-colors-alist) nil nil nil nil nil nil
((completion-ignore-case t))) ; Bindings
(icicle-maybe-byte-compile-after-load icicle-pick-color-by-name)
(defun icicle-pick-color-by-name-action (color)
"Action function for `icicle-pick-color-by-name'."
(if (string= "" color)
(let* ((colors (hexrgb-defined-colors))
(rand (random (length colors)))) ; Random color.
(setq color (elt colors rand)))
(let ((hex-string (hexrgb-rgb-hex-string-p color t)))
(when (and hex-string (not (eq 0 hex-string))) (setq color (concat "#" color))) ; Add #.
(if (not (or hex-string (if (fboundp 'test-completion) ; Not defined in Emacs 20.
(test-completion color (hexrgb-defined-colors-alist))
(try-completion color (hexrgb-defined-colors-alist)))))
(error "No such color: %S" color)
(setq color (hexrgb-color-name-to-hex color))))
(setq palette-last-color palette-current-color)
(save-selected-window
(setq color (hexrgb-color-name-to-hex color)) ; Needed if not interactive.
(palette-set-current-color color)
(palette-where-is-color color)
(palette-brightness-scale)
(palette-swatch))
palette-current-color))
(icicle-maybe-byte-compile-after-load icicle-pick-color-by-name-action)
(define-key palette-mode-map (icicle-kbd "c") 'icicle-pick-color-by-name)
(define-key palette-popup-map [pick-color-by-name] ; Use same name as in `palette.el'.
`(menu-item "Choose Color By Name" icicle-pick-color-by-name
:help "Set the current color to a color you name"))
)
(defun icicle-cmd2-after-load-synonyms ()
"Things to do for `icicles-cmd2.el' after loading `synonyms.el'."
(defalias 'synonyms 'icicle-synonyms)
(icicle-define-command icicle-synonyms ; Command
"Show synonyms that match a regular expression (e.g. a word or phrase).
You are prompted for the regexp. By default, it is the text
of the region, if it is active and `transient-mark-mode' is enabled,
or the nearest word to the cursor, if not.
Option `synonyms-match-more-flag' non-nil means additional thesaurus
entries can be matched. This can be more time-consuming. It means
two things:
1) Input can match parts of synonyms, in addition to whole synonyms.
2) All synonyms are shown, even if input matches a thesaurus entry.
Option `synonyms-append-result-flag' non-nil means to append search
result to previous results.
A prefix argument toggles the meaning of each of those options for the
duration of the command:
If `C-u' or `C-u C-u', then toggle `synonyms-match-more-flag'.
If negative or `C-u C-u', then toggle `synonyms-append-result-flag'.
\(`C-u C-u' thus means toggle both options.)
When called from Lisp, optional second argument REGEXP is the regexp
to match (no prompting)." ; Doc string
synonyms-action ; Action function, defined in `synonyms.el'.
"Show synonyms for word or phrase (regexp): " ; `completing-read' arguments
synonyms-obarray nil nil nil 'synonyms-history (synonyms-default-regexp) nil
((num-arg (prefix-numeric-value current-prefix-arg)) ; Bindings
(morep (eq synonyms-match-more-flag (atom current-prefix-arg)))
(appendp (eq synonyms-append-result-flag (and (wholenump num-arg) (/= 16 num-arg))))
(icicle-sort-function 'icicle-case-insensitive-string-less-p))
(synonyms-ensure-synonyms-read-from-cache)) ; Fill `synonyms-obarray' initially, for completion.
(icicle-maybe-byte-compile-after-load icicle-synonyms)
(icicle-define-command icicle-insert-thesaurus-entry ; Command name
"Insert an entry from a thesaurus.
Library `synonyms.el' is needed for this. If you have never used
command `synonyms' before, then the first use of
`icicle-insert-thesaurus-entry' will take a while, because it will
build a cache file of synonyms that are used for completion. See
`synonyms.el'.
Remember that you can use `\\<minibuffer-local-completion-map>\
\\[icicle-cycle-incremental-completion] to toggle incremental completion." ; Doc string
icicle-insert-thesaurus-entry-cand-fn ; Action function
"Thesaurus entry to match: " synonyms-obarray ; `completing-read' args
nil t nil 'icicle-dictionary-history nil nil
((icicle-track-pt (point))) ; Bindings
(progn ; First code
(unless (or (boundp 'synonyms-obarray) (require 'synonyms nil t))
(error "You must first load library `synonyms.el'"))
(synonyms-ensure-synonyms-read-from-cache))
nil ; Undo code
(when (window-live-p icicle-orig-window) ; Last code
(select-window icicle-orig-window)
(select-frame-set-input-focus (selected-frame))
(goto-char icicle-track-pt)))
(icicle-maybe-byte-compile-after-load icicle-insert-thesaurus-entry)
;; Free vars here: `icicle-orig-buff' is bound in `icicle-insert-thesaurus-entry'.
(defun icicle-insert-thesaurus-entry-cand-fn (string)
"Action function for `icicle-insert-thesaurus-entry'.
Insert STRING, followed by a space, at position TRACK-PT of buffer
ORIG-BUFF."
(set-buffer icicle-orig-buff)
(goto-char icicle-track-pt)
(insert string " ")
(setq icicle-track-pt (point))
(unless (pos-visible-in-window-p) (recenter icicle-recenter))
(with-current-buffer (window-buffer (minibuffer-window)) (icicle-clear-minibuffer))
(save-selected-window (icicle-remove-Completions-window)))
(icicle-maybe-byte-compile-after-load icicle-insert-thesaurus-entry-cand-fn)
(defun icicle-complete-thesaurus-entry (word) ; Bound to `C-c /' in Icicle mode.
"Complete WORD to an entry from a thesaurus.
The default value of WORD is the word at the cursor.
Library `synonyms.el' is needed for this. If you have never used
command `synonyms' before, then the first use of
`icicle-insert-thesaurus-entry' will take a while, because it will
build a cache file of synonyms that are used for completion. See
`synonyms.el'."
(interactive (list (word-at-point)))
(unless word (error "No word at point to complete"))
(unless (or (boundp 'synonyms-obarray) (require 'synonyms nil t))
(error "You must first load library `synonyms.el'"))
(synonyms-ensure-synonyms-read-from-cache)
(when (and (looking-at "\\b") (not (looking-at "\\s-"))) (forward-word 1))
(delete-region (progn (forward-word -1) (point)) (progn (forward-word 1) (point)))
(insert (completing-read "Thesaurus entry to match: " synonyms-obarray
nil nil word 'icicle-dictionary-history word))
(unless (looking-at "\\s-") (insert " ")))
(icicle-maybe-byte-compile-after-load icicle-complete-thesaurus-entry)
)
;;; Library `Bookmark+' - Icicles multi-commands.
;;;
;;;###autoload (autoload 'icicle-tag-a-file "icicles-cmd2.el")
;;;###autoload (autoload 'icicle-untag-a-file "icicles-cmd2.el")
;;;###autoload (autoload 'icicle-find-file-tagged "icicles-cmd2.el")
;;;###autoload (autoload 'icicle-find-file-tagged-other-window "icicles-cmd2.el")
;;;###autoload (autoload 'icicle-find-file-all-tags "icicles-cmd2.el")
;;;###autoload (autoload 'icicle-find-file-all-tags-other-window "icicles-cmd2.el")
;;;###autoload (autoload 'icicle-find-file-all-tags-regexp "icicles-cmd2.el")
;;;###autoload (autoload 'icicle-find-file-all-tag-regexp-other-windows "icicles-cmd2.el")
;;;###autoload (autoload 'icicle-find-file-some-tags "icicles-cmd2.el")
;;;###autoload (autoload 'icicle-find-file-some-tags-other-window "icicles-cmd2.el")
;;;###autoload (autoload 'icicle-find-file-some-tags-regexp "icicles-cmd2.el")
;;;###autoload (autoload 'icicle-find-file-some-tags-regexp-other-window "icicles-cmd2.el")
(eval-after-load "bookmark+" '(icicle-cmd2-after-load-bookmark+))
;;; Library `hexrgb.el' - Icicles multi-commands.
;;;
;;;###autoload (autoload 'icicle-frame-bg "icicles-cmd2.el")
;;;###autoload (autoload 'icicle-frame-fg "icicles-cmd2.el")
(eval-after-load "hexrgb" '(icicle-cmd2-after-load-hexrgb))
;;; Library `highlight.el' - Icicles multi-commands. Emacs 21+.
;;;
;;;###autoload (autoload 'icicle-choose-faces "icicles-cmd2.el")
;;;###autoload (autoload 'icicle-choose-invisible-faces "icicles-cmd2.el")
;;;###autoload (autoload 'icicle-choose-visible-faces "icicles-cmd2.el")
;;;###autoload (autoload 'icicle-hide-faces "icicles-cmd2.el")
;;;###autoload (autoload 'icicle-hide-only-faces "icicles-cmd2.el")
;;;###autoload (autoload 'icicle-show-faces "icicles-cmd2.el")
;;;###autoload (autoload 'icicle-show-only-faces "icicles-cmd2.el")
(eval-after-load "highlight" '(icicle-cmd2-after-load-highlight))
;;; Library `palette.el' - Icicles multi-commands.
;;;
;;;###autoload (autoload 'icicle-pick-color-by-name "icicles-cmd2.el")
(eval-after-load "palette" '(icicle-cmd2-after-load-palette))
;;; Library `synonyms.el' - Icicles multi-commands.
;;;
;;;###autoload (autoload 'synonyms "icicles-cmd2.el")
;;;###autoload (autoload 'icicle-synonyms "icicles-cmd2.el")
;;;###autoload (autoload 'icicle-insert-thesaurus-entry "icicles-cmd2.el")
;;;###autoload (autoload 'icicle-complete-thesaurus-entry "icicles-cmd2.el")
(eval-after-load "synonyms" '(icicle-cmd2-after-load-synonyms))
;;(@* "Icicles Top-Level Commands, Part 2")
;;; Icicles Top-Level Commands, Part 2 -------------------------------
(defvar icicle-orig-font nil
"Font of selected frame, before command.")
(defvar icicle-orig-frame nil
"Selected frame, before command.")
(defvar icicle-orig-menu-bar nil
"`menu-bar-lines' of selected frame, before command.")
(defvar icicle-orig-pixelsize nil
"Size of font of selected frame in pixels, before command.")
(defvar icicle-orig-pointsize nil
"Size of font of selected frame in points, before command.")
;;;###autoload (autoload 'icicle-font "icicles-cmd2.el")
(icicle-define-command icicle-font ; Command name
"Change font of current frame." ; Doc string
(lambda (font) (modify-frame-parameters icicle-orig-frame (list (cons 'font font)))) ; Action fn
"Font: " ; `completing-read' args
(let ((fonts ())
fws)
(dolist (ft (x-list-fonts "*") fonts) ; Just avoiding two traversals, one to remove nil elts.
(when (setq fws (icicle-font-w-orig-size ft)) (push fws fonts)))) ; Ignore nil entries.
nil t nil (if (boundp 'font-name-history) 'font-name-history 'icicle-font-name-history) nil nil
((icicle-orig-frame (selected-frame)) ; Bindings
(icicle-orig-font (frame-parameter nil 'font))
(icicle-orig-pixelsize (aref (x-decompose-font-name icicle-orig-font)
xlfd-regexp-pixelsize-subnum))
(icicle-orig-pointsize (aref (x-decompose-font-name icicle-orig-font)
xlfd-regexp-pointsize-subnum))
(icicle-orig-menu-bar (assq 'menu-bar-lines (frame-parameters icicle-orig-frame))))
;; First code - remove menu-bar, to avoid Emacs bug that resizes frame.
(modify-frame-parameters icicle-orig-frame (list '(menu-bar-lines . 0)))
(modify-frame-parameters icicle-orig-frame ; Undo code.
(list (cons 'font icicle-orig-font) icicle-orig-menu-bar))
(modify-frame-parameters icicle-orig-frame (list icicle-orig-menu-bar))) ; Last code.
;; Free var here: `icicle-orig-pixelsize' is bound in `icicle-font'.
(defun icicle-font-w-orig-size (font)
"Return a font like FONT, but with pixel size `icicle-orig-pixelsize'.
Return nil if `x-decompose-font-name' returns nil for FONT.
`icicle-orig-pixelsize' is the original pixel size for `icicle-font'."
(let ((xlfd-fields (x-decompose-font-name font)))
(if (not xlfd-fields) ; Can't handle such font names - return nil.
nil
(aset xlfd-fields xlfd-regexp-pixelsize-subnum icicle-orig-pixelsize)
(aset xlfd-fields xlfd-regexp-pointsize-subnum icicle-orig-pointsize)
(let* ((sized-font (x-compose-font-name xlfd-fields))
(font-info (and (or (> icicle-help-in-mode-line-delay 0) ; Only if user will see it.
(and (boundp 'tooltip-mode) tooltip-mode))
(font-info sized-font)))
(iii (if (< emacs-major-version 21) 3 2))
(help-string (if font-info
(format "width: %s, height: %s, offset: %s, compose: %s"
(aref font-info iii) (aref font-info (+ iii 1))
(aref font-info (+ iii 2)) (aref font-info (+ iii 3)))
"Font is not yet loaded (used)")))
(icicle-candidate-short-help help-string sized-font)
(list sized-font)))))
(defvar icicle-named-colors ()
"Named colors.")
(defvar icicle-info-buff nil
"Info buffer before command was invoked.")
(defvar icicle-info-window nil
"Info window before command was invoked.")
;;;###autoload
(defun icicle-Info-index ()
"Like vanilla `Info-index', but you can use multi-command keys `C-RET', `C-up' etc."
(interactive)
(when (and (boundp 'Info-current-file) (equal Info-current-file "dir"))
(error "The Info directory node has no index; use `m' to select a manual"))
(let ((icicle-info-buff (current-buffer))
(icicle-info-window (selected-window))
(icicle-candidate-action-fn 'icicle-Info-index-action)
(C-x-m (lookup-key minibuffer-local-completion-map "\C-xm")))
(when (and (require 'bookmark+ nil t) (fboundp 'icicle-bookmark-info-other-window))
(define-key minibuffer-local-completion-map (icicle-kbd "C-x m")
'icicle-bookmark-info-other-window))
(unwind-protect
(call-interactively (if (> emacs-major-version 21) 'old-Info-index 'icicle-Info-index-20))
(define-key minibuffer-local-completion-map (icicle-kbd "C-x m") C-x-m))))
;; Thx to Tamas Patrovics for this Emacs 20 version.
;;;###autoload
(defun icicle-Info-index-20 ()
"Like `Info-index', but you can use completion for the index topic."
(interactive)
(let* ((symb (or (and (fboundp 'symbol-nearest-point) ; Defined in `thingatpt+.el'.
(symbol-nearest-point))
(symbol-at-point)))
(topic (and symb (symbol-name symb))))
(old-Info-index "")
(let ((pattern "\\* +\\([^:]*\\):.")
(candidates ()))
(goto-char (point-min))
(while (re-search-forward pattern nil t) (push (list (match-string 1)) candidates))
(old-Info-index (completing-read "Index topic: " candidates nil t nil nil topic)))))
;; Free vars here: `icicle-info-buff' and `icicle-info-window' are bound in `icicle-Info-index'.
(defun icicle-Info-index-action (topic)
"Completion action function for `icicle-Info-index'."
(let ((minibuf-win (selected-window)))
(set-buffer icicle-info-buff)
(select-window icicle-info-window)
(old-Info-index topic)
(select-window minibuf-win)))
;; Free vars here: `Info-menu-entry-name-re' is bound in `info.el'.
(icicle-define-command icicle-Info-menu
"Go to a menu node." ; Doc string
(lambda (m) (icicle-Info-goto-node (cdr (funcall icicle-get-alist-candidate-function m)))) ; Action
"Menu item: " icicle-candidates-alist ; `completing-read' args
nil t nil nil (save-excursion
(goto-char (point-min))
(unless (search-forward "\n* menu:" nil t) (error "No menu in this node"))
(setq menu-eol (point))
(and (< menu-eol opoint)
(save-excursion
(goto-char opoint) (end-of-line)
(and (re-search-backward (concat "\n\\* +\\("
(if (boundp 'Info-menu-entry-name-re)
Info-menu-entry-name-re
"[^:\t\n]*")
"\\):")
menu-eol t)
(match-string-no-properties 1)))))
nil
((opoint (point)) ; Bindings
(completion-ignore-case t)
(case-fold-search t)
(icicle-sort-comparer nil)
(icicle-whole-candidate-as-text-prop-p t)
(Info-complete-menu-buffer (current-buffer))
(icicle-candidates-alist (mapcar #'(lambda (m) (cons m (Info-extract-menu-item m)))
(reverse
(all-completions "" 'Info-complete-menu-item))))
menu-eol))
;;;###autoload
(defun icicle-Info-goto-node (nodename &optional arg)
"Go to Info node named NODENAME.
NODENAME has the form NODE or (FILE)NODE-IN-FILE, where:
NODE names a node in the current Info file or one of its subfiles.
FILE names an Info file containing node NODE-IN-FILE.
Completion is available for node names in the current Info file.
With a prefix argument:
* Plain `C-u' means prepend the current Info file name (manual name)
to each node name. For example: `(emacs)Paragraphs' instead of
just `Paragraphs'.
* A negative numeric prefix arg (e.g. `C--') means present completion
candidates in book order, and limit the candidates to the current
node and the rest of the book following it. In this case, the
first candidate is `..', which means go up.
* A negative numeric prefix arg (e.g. `C-1') means show the target
node in a new Info buffer (not available prior to Emacs 21).
(This applies only to the final completion choice, not to
intermediate candidate actions using, e.g., `C-RET'.)
In Lisp code, if optional argument ARG is a string, then show the node
in a new Info buffer named `*info-ARG*'.
With no prefix argument, or with a non-negative prefix arg, you can
use `C-,' to choose how to sort completion candidates. By default,
they are sorted alphabetically.
Input-candidate completion and cycling are available. While cycling,
these keys with prefix `C-' are active:
`C-mouse-2', `C-RET' - Go to current completion candidate (node)
`C-down' - Go to next completion candidate
`C-up' - Go to previous completion candidate
`C-next' - Go to next apropos-completion candidate
`C-prior' - Go to previous apropos-completion candidate
`C-end' - Go to next prefix-completion candidate
`C-home' - Go to previous prefix-completion candidate
Use `mouse-2', `RET', or `S-RET' to finally choose a candidate, or
`C-g' to quit.
This is an Icicles command - see command `icicle-mode'."
(interactive
(let* ((icicle-info-buff (current-buffer))
(icicle-info-window (selected-window))
(icicle-candidate-action-fn 'icicle-Info-goto-node-action)
(icicle-Info-only-rest-of-book-p (< (prefix-numeric-value current-prefix-arg) 0))
(icicle-sort-orders-alist (cons '("in book order" . icicle-Info-book-order-p)
icicle-sort-orders-alist))
(icicle-sort-comparer (if icicle-Info-only-rest-of-book-p
#'icicle-Info-book-order-p
icicle-sort-comparer)))
(list (icicle-Info-read-node-name "Go to node: " (consp current-prefix-arg))
current-prefix-arg)))
(icicle-Info-goto-node-1 nodename arg))
(defun icicle-Info-goto-node-1 (nodename &optional arg)
"Same as vanilla `Info-goto-node', but go up for `..' pseudo-node."
(if (and (string= nodename "..") (Info-check-pointer "up"))
(Info-up)
(if (> emacs-major-version 20)
(old-Info-goto-node nodename (and (not icicle-Info-only-rest-of-book-p) arg))
(old-Info-goto-node nodename))))
(defun icicle-Info-read-node-name (prompt &optional include-file-p)
"Read a node name, prompting with PROMPT.
Non-nil INCLUDE-FILE-P means include current Info file in the name.
You can use `C-x m' during completion to access Info bookmarks, if you
use library `Bookmark+'."
(let ((C-x-m (lookup-key minibuffer-local-completion-map "\C-xm")))
(when (and (require 'bookmark+ nil t) (fboundp 'icicle-bookmark-info-other-window))
(define-key minibuffer-local-completion-map (icicle-kbd "C-x m")
'icicle-bookmark-info-other-window))
(unwind-protect
(let* ((completion-ignore-case t)
(Info-read-node-completion-table (icicle-Info-build-node-completions include-file-p))
(nodename (completing-read prompt 'Info-read-node-name-1
nil nil)))
(if (equal nodename "") (icicle-Info-read-node-name prompt) nodename))
(define-key minibuffer-local-completion-map (icicle-kbd "C-x m") C-x-m))))
(defun icicle-Info-build-node-completions (&optional include-file-p)
"Build completions list for Info nodes.
This takes `icicle-Info-only-rest-of-book-p' into account.
Non-nil INCLUDE-FILE-P means include current Info file in the name."
(icicle-highlight-lighter)
(if (or (not icicle-Info-only-rest-of-book-p) (string= Info-current-node "Top"))
(icicle-Info-build-node-completions-1 include-file-p)
(reverse (cons '("..")
(member (list Info-current-node)
(reverse (icicle-Info-build-node-completions-1 include-file-p)))))))
(defun icicle-Info-build-node-completions-1 (&optional include-file-p)
"Helper function for `icicle-Info-build-node-completions'.
Use `Info-build-node-completions' to build node list for completion.
Non-nil INCLUDE-FILE-P means include current Info file in the name.
Remove pseudo-node `*'. (This just fixes a bug in Emacs 21 and 22.1.)"
(let ((comps (Info-build-node-completions)))
(when (equal (car comps) '("*")) (setq comps (cdr comps)))
(if include-file-p
(let ((file (concat "(" (cond ((stringp Info-current-file)
(replace-regexp-in-string
"%" "%%" (file-name-nondirectory Info-current-file)))
(Info-current-file (format "*%S*" Info-current-file))
(t ""))
")")))
(mapcar #'(lambda (node) (cons (concat file (car node)) (cdr node))) comps))
comps)))
;; Free vars here:
;; `icicle-info-buff' and `icicle-info-window' are bound in `icicle-Info-goto-node'.
;; `Info-read-node-completion-table' is bound in `info.el'.
(defun icicle-Info-goto-node-action (node)
"Completion action function for `icicle-Info-goto-node'."
(set-buffer icicle-info-buff)
(select-window icicle-info-window)
(icicle-Info-goto-node-1 node)
(when icicle-Info-only-rest-of-book-p
(setq Info-read-node-completion-table (icicle-Info-build-node-completions)
icicle-current-input "")
(icicle-complete-again-update)
(if (and (string= Info-current-node "Top") Info-history)
(let* ((hist Info-history)
(last (car (cdr (car hist)))))
(while (string= "Top" (car (cdr (car hist)))) (pop hist))
(setq icicle-candidate-nb
(1- (length (reverse (member (list (car (cdr (car hist))))
(icicle-Info-build-node-completions-1)))))))
(setq icicle-candidate-nb 1)) ; Skip `..'.
;; $$$$$$ Maybe factor this out. Same thing in several places. However, here we don't do
;; `icicle-maybe-sort-and-strip-candidates' at beginning of first clause.
(cond ((and icicle-completion-candidates (cdr icicle-completion-candidates)) ; > 1 left.
(message "Displaying completion candidates...")
(save-selected-window (icicle-display-candidates-in-Completions))
(with-current-buffer "*Completions*"
(goto-char (icicle-start-of-candidates-in-Completions))
(icicle-move-to-next-completion
(mod icicle-candidate-nb (length icicle-completion-candidates)))
(set-window-point (get-buffer-window "*Completions*" 0) (point))
(setq icicle-last-completion-candidate (icicle-current-completion-in-Completions))
(set-buffer-modified-p nil)))
(icicle-completion-candidates ; Single candidate left
(save-selected-window (icicle-remove-Completions-window))
(let ((completion (icicle-transform-multi-completion
(car icicle-completion-candidates))))
(select-window (active-minibuffer-window))
(with-current-buffer (window-buffer) ; Need if `*Completions*' redirected to minibuffer.
(goto-char (icicle-minibuffer-prompt-end))
(icicle-clear-minibuffer)
(insert (if (and (icicle-file-name-input-p) insert-default-directory
(or (not (member completion icicle-extra-candidates))
icicle-extra-candidates-dir-insert-p))
(icicle-file-name-directory-w-default icicle-current-input)
"")
completion))))
(t ; No candidates left
(select-window (active-minibuffer-window))
(with-current-buffer (window-buffer) ; Needed if `*Completions*' redirected to minibuffer.
(goto-char (icicle-minibuffer-prompt-end))
(icicle-clear-minibuffer)))))
(select-window (active-minibuffer-window)))
(defun icicle-Info-book-order-p (s1 s2)
"Non-nil if Info node S1 comes before node S2 in the book."
t) ; This just reverses the default order, which is reversed.
(when (> emacs-major-version 21)
(defun icicle-Info-virtual-book (nodeset)
"Open Info on a virtual book of saved Info nodes.
You need library `info+.el' to use this command.
With a prefix arg, you are prompted to choose a persistent saved
completion set from `icicle-saved-completion-sets'. The set you
choose should be a set of saved Info node names.
With no prefix arg, use `icicle-saved-completion-candidates', which
should be a set of Info node names. If that is empty, then use
`Info-saved-nodes'.
Non-interactively, argument NODESET is a list of Info node names."
(interactive
(progn (unless (and (require 'info+ nil t) (fboundp 'Info-virtual-book))
(error "You need library `info+.el' for this command"))
(list (if (not current-prefix-arg)
"Virtual Book"
(save-selected-window
(completing-read "Saved Info node set: " icicle-saved-completion-sets nil t nil
'icicle-completion-set-history))))))
(let ((nodes (and (consp nodeset) nodeset))) ; (), if interactive - NODESET is a string then.
(when (interactive-p)
(if (not current-prefix-arg)
(setq nodes icicle-saved-completion-candidates)
(let ((file-name (cdr (assoc nodeset icicle-saved-completion-sets))))
(unless (icicle-file-readable-p file-name)
(error "Cannot read cache file `%s'" file-name))
(let ((list-buf (find-file-noselect file-name 'nowarn 'raw)))
(unwind-protect
(condition-case icicle-Info-virtual-book
(when (listp (setq nodes (read list-buf)))
(message "Set `%s' read from file `%s'" nodeset file-name))
(error (error "Bad cache file. %s"
(error-message-string icicle-Info-virtual-book))))
(kill-buffer list-buf))
(unless (consp nodes) (error "Bad data in cache file `%s'" file-name))))))
(unless nodes (setq nodes Info-saved-nodes)) ; In `info+.el'.
(unless (and nodes (stringp (car nodes))) (error "No saved Info nodes")) ; Minimal check.
(unless (stringp nodeset) (setq nodeset "Virtual Book")) ; Non-interactive - NODESET is a list.
(Info-virtual-book nodeset nodes))))
;;;###autoload (autoload 'icicle-where-is "icicles-cmd2.el")
(icicle-define-command icicle-where-is ; Command name
"Show keyboard/menu/mouse sequences that invoke specified command.
This is a multi-command version of `where-is'.
With no prefix argument, only commands actually bound to keys are
completion candidates. With a prefix argument, all commands are
candidates. NOTE: This is a significant difference from vanilla
`where-is', which shows all commands as candidates, even those that
are not bound.
With a plain (non-numeric) prefix argument, `C-u', insert the message
in the current buffer. (This is the same for vanilla `where-is'.)
By default, Icicle mode remaps all key sequences that are normally
bound to `where-is' to `icicle-where-is'. If you do not want this
remapping, then customize option `icicle-top-level-key-bindings'." ; Doc string
(lambda (x) (let ((symb (intern-soft x))) ; Action function
(where-is symb (and pref-arg (consp pref-arg)))))
(if pref-arg "Where is command: " "Where is bound command: ")
obarray nil t nil nil ; `completing-read' args
(let ((fn (or (and (fboundp 'symbol-nearest-point) (symbol-nearest-point))
(function-called-at-point))))
(and fn (symbol-name fn)))
t
((pref-arg current-prefix-arg) ; Bindings
(icicle-must-pass-after-match-predicate
(if pref-arg
#'(lambda (c) (commandp (intern c)))
#'(lambda (c)
(setq c (intern c))
(with-current-buffer icicle-orig-buff
(and (commandp c) (where-is-internal c overriding-local-map 'non-ascii))))))
(icicle-candidate-help-fn
#'(lambda (c)
(with-current-buffer icicle-orig-buff
(let* ((keys (where-is-internal (intern-soft c) overriding-local-map))
(keys1 (mapconcat #'icicle-key-description keys ", ")))
(message (if (string= "" keys1)
(format "`%s' is not on any key" c)
(format "`%s' is on `%s'" c (icicle-propertize keys1 'face 'icicle-msg-emphasis))))
(sit-for 3)))))
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "command")))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "command")))))
;;;###autoload (autoload 'icicle-describe-option-of-type "icicles-cmd2.el")
(icicle-define-command icicle-describe-option-of-type ; Bound to `C-h C-o'. Command name
"Describe a user option that was defined with a given `defcustom' type.
Enter patterns for the OPTION name and TYPE definition in the
minibuffer, separated by `icicle-list-join-string', which is \"^G^J\",
by default. (`^G' here means the Control-g character, input using
`C-h C-g'. Likewise, for `^J'.)
OPTION is a regexp that is matched against option names.
Depending on the prefix arg, TYPE is interpreted as either of these:
- a regexp to match against the option type
- a definition acceptable for `defcustom' :type, or its first symbol,
for example, (choice (integer) (regexp)) or `choice'
In the second case, depending on the prefix arg, TYPE can be matched
against the option type, or it can be matched against either the
option type or one of its subtypes.
In the second case also, depending on the prefix arg, if TYPE does not
match some option's type, that option might still be a candidate, if
its current value satisfies TYPE.
In sum, the prefix arg determines the type-matching behavior, as
follows:
- None: OPTION is defined with TYPE or a subtype of TYPE.
TYPE is a regexp.
- `C-u': OPTION is defined with TYPE or a subtype of TYPE,
or its current value is compatible with TYPE.
TYPE is a type definition or its first symbol.
- Negative: OPTION is defined with TYPE (exact match).
TYPE is a regexp.
- Positive: OPTION is defined with TYPE,
or its current value is compatible with TYPE.
TYPE is a type definition or its first symbol.
- Zero: OPTION is defined with TYPE or a subtype of TYPE.
TYPE is a type definition or its first symbol.
- `C-u C-u': OPTION is defined with TYPE (exact match).
TYPE is a type definition or its first symbol.
You can change these prefix-arg key sequences by customizing option
`icicle-option-type-prefix-arg-list'. For example, if you tend to use
the matching defined here for `C-u', you might want to make that the
default behavior (no prefix arg). You can assign any of the six
behaviors to any of the prefix-arg keys.
If TYPE is nil, then *all* options that match OPTION are candidates.
Note that options defined in libraries that have not been loaded can
be candidates, but their type will appear as nil, since it is not
known before loading the option definition.
You can match your input against the option name or the type
definition or both. Use `C-M-j' (equivalent here to `C-q C-g C-j') to
input the default separator.
For example, to match all Icicles options whose type matches `string'
\(according to the prefix arg), use `S-TAB' with this input:
icicle.*^G
string$
If you instead want all Icicles options whose type definition contains
`string', as in (repeat string), then use this:
icicle.*^G
\[^^G]*string
Here, `[^^G]' matches any character except ^G, which includes newline.
If you use `.' here instead of `[^^G]', then only the first lines of
type definitions are searched for `string', because `.' matches any
character except a newline. (The first `^' in `[^^G]' is a circumflex
character. The second `^' is part of `^G', the printed representation
of a Control-g character.)
Remember that you can use `\\<minibuffer-local-completion-map>\
\\[icicle-cycle-incremental-completion] to toggle incremental completion." ; Doc string
icicle-describe-opt-action ; Action function
prompt ; `completing-read' args
'icicle-describe-opt-of-type-complete nil nil nil nil nil nil
((prompt "OPTION `C-M-j' TYPE: ") ; Bindings
(icicle-candidate-properties-alist '((1 (face icicle-candidate-part))))
;; Bind `icicle-apropos-complete-match-fn' to nil to prevent automatic input matching
;; in `icicle-unsorted-apropos-candidates' etc., because `icicle-describe-opt-of-type-complete'
;; does everything.
(icicle-apropos-complete-match-fn nil)
(icicle-candidate-help-fn 'icicle-describe-opt-action)
;; $$$ (icicle-highlight-input-completion-failure nil)
(icicle-pref-arg current-prefix-arg))
(progn (put-text-property 0 1 'icicle-fancy-candidates t prompt) ; First code
(icicle-highlight-lighter)
(message "Gathering user options and their types...")))
(defun icicle-describe-opt-action (opt+type)
"Action function for `icicle-describe-option-of-type'."
(let ((icicle-list-use-nth-parts '(1)))
(describe-variable (intern (icicle-transform-multi-completion opt+type)))))
;; Free var here: `icicle-pref-arg' - it is bound in `icicle-describe-option-of-type'.
(defun icicle-describe-opt-of-type-complete (strg pred completion-mode)
"Completion function for `icicle-describe-option-of-type'.
This is used as the value of `minibuffer-completion-table'."
(setq strg icicle-current-input)
;; Parse strg into its option part and its type part: OPS and TPS.
;; Make raw alist of all options and their types: ((a . ta) (b . tb)...).
(let* ((num-prefix (prefix-numeric-value icicle-pref-arg))
(mode (cond ((not icicle-pref-arg) ; No prefix arg
(nth 4 icicle-option-type-prefix-arg-list))
((and (consp icicle-pref-arg) (= 16 num-prefix)) ; C-u C-u
(nth 0 icicle-option-type-prefix-arg-list))
((consp icicle-pref-arg) (nth 2 icicle-option-type-prefix-arg-list)) ; C-u
((zerop num-prefix) (nth 1 icicle-option-type-prefix-arg-list)) ; C-0
((wholenump num-prefix) ; C-9
(nth 3 icicle-option-type-prefix-arg-list))
(t (nth 5 icicle-option-type-prefix-arg-list)))) ; C--
(ops (let ((icicle-list-use-nth-parts '(1)))
(icicle-transform-multi-completion strg)))
(tps (let ((icicle-list-use-nth-parts '(2)))
(icicle-transform-multi-completion strg)))
(tp (and (not (string= "" tps))
;; Use regexp if no prefix arg or negative; else use sexp.
(if (memq mode '(inherit-or-regexp direct-or-regexp)) tps (read tps))))
(result nil))
(mapatoms
#'(lambda (symb)
(when (if (fboundp 'custom-variable-p) (custom-variable-p symb) (user-variable-p symb))
(condition-case nil
(push (list symb (get symb 'custom-type)) result)
(error nil)))))
;; Keep only candidates that correspond to input.
(setq result
(let ((ops-re (if (memq icicle-current-completion-mode '(nil apropos))
ops
(concat "^" ops))))
(icicle-remove-if-not
#'(lambda (opt+typ)
(and (string-match ops-re (symbol-name (car opt+typ)))
(or (null tp)
(condition-case nil
(icicle-var-is-of-type-p (car opt+typ) (list tp)
(case mode
((inherit inherit-or-regexp) 'inherit)
((direct direct-or-regexp) 'direct)
(inherit-or-value 'inherit-or-value)
(direct-or-value 'direct-or-value)))
(error nil)))))
result)))
;; Change alist entries to multi-completions: "op^G^Jtp". Add short help for mode-line, tooltip.
(setq result
(mapcar #'(lambda (entry)
(let* ((opt+typ-string
;; $$$$$$ (concat (mapconcat #'(lambda (e) (pp-to-string e))
;; entry icicle-list-join-string)
;; icicle-list-end-string)) ; $$$$$$
(mapconcat #'(lambda (e) (pp-to-string e)) entry
icicle-list-join-string))
(doc ; Don't bother to look up doc, if user won't see it.
(and (or (> icicle-help-in-mode-line-delay 0)
(and (boundp 'tooltip-mode) tooltip-mode))
(documentation-property (car entry) 'variable-documentation t)))
(doc1 (and (stringp doc)
(string-match ".+$" doc) (match-string 0 doc))))
(when doc1 (icicle-candidate-short-help doc1 opt+typ-string))
opt+typ-string))
result))
(if completion-mode
result ; `all-completions', `test-completion'
(try-completion strg (mapcar #'list result) pred)))) ; `try-completion'
;;;###autoload (autoload 'icicle-vardoc "icicles-cmd2.el")
(icicle-define-command icicle-vardoc ; Command name
"Choose a variable description.
Each candidate for completion is a variable name plus its
documentation. They are separated by `icicle-list-join-string'
\(\"^G^J\", by default). You can match an input regexp against the
variable name or the documentation or both. Use `C-M-j' (equivalent
here to `C-q C-g C-j') to input the default separator.
For example, use input
\"dired.*^G
\[^^G]*list\"
with `S-TAB' to match all variables whose names contain \"dired\" and
whose documentation contains \"list\". Here, `[^^G]' matches any
character except ^G, which includes newline. If you use `.*' here,
instead, then only the first lines of doc strings are searched.
With a non-negative prefix argument, use the same documentation that
was gathered the last time `icicle-vardoc' was called. Use a
non-negative prefix arg to save the time that would be needed to
gather the documentation.
With a non-positive prefix arg, use only user variables (options) as
candidates.
Remember that you can use `\\<minibuffer-local-completion-map>\
\\[icicle-cycle-incremental-completion] to toggle incremental completion." ; Doc string
icicle-doc-action ; Action function
prompt ; `completing-read' args
(let* ((num-arg (prefix-numeric-value pref-arg))
(options-only-p (<= num-arg 0))
(result (and pref-arg (>= num-arg 0)
(if options-only-p
icicle-vardoc-last-initial-option-cand-set
icicle-vardoc-last-initial-cand-set))))
(unless result ; COLLECTION arg is an alist whose items are ((SYMB DOC)).
(mapatoms #'(lambda (symb) ; Each completion candidate is a list of strings.
(when (and (boundp symb)
(or (wholenump (prefix-numeric-value pref-arg))
(user-variable-p symb)))
(let ((doc (documentation-property symb 'variable-documentation)))
(when (icicle-non-whitespace-string-p doc)
(push (list (list (symbol-name symb) doc)) result))))))
(if options-only-p
(setq icicle-vardoc-last-initial-option-cand-set result)
(setq icicle-vardoc-last-initial-cand-set result)))
result)
nil nil nil 'icicle-doc-history nil nil
((prompt "VAR `C-M-j' DOC: ") ; Bindings
(icicle-candidate-properties-alist '((1 (face icicle-candidate-part))))
(icicle-list-use-nth-parts '(1))
(pref-arg current-prefix-arg))
(progn
(put-text-property 0 1 'icicle-fancy-candidates t prompt) ; First code
(icicle-highlight-lighter)
(message "Gathering variable descriptions...")))
;;; $$$$$$ (defun icicle-funvardoc-action (entry)
;;; "Action function for `icicle-vardoc', `icicle-fundoc', `icicle-plist'."
;;; (with-output-to-temp-buffer "*Help*" (princ entry)))
;;;###autoload (autoload 'icicle-fundoc "icicles-cmd2.el")
(icicle-define-command icicle-fundoc ; Command name
"Choose a function description.
Each candidate for completion is a function name plus its
documentation. They are separated by `icicle-list-join-string'
\(\"^G^J\", by default). You can match an input regexp against the
function name or the documentation or both. Use `C-M-j' (equivalent
here to `C-q C-g C-j') to input the default separator.
For example, use input
\"dired.*^G
\[^^G]*file\"
with `S-TAB' to match all functions whose names contain \"dired\" and
whose documentation contains \"file\". Here, `[^^G]' matches any
character except ^G, which includes newline. If you use `.*' here,
instead, then only the first lines of doc strings are searched.
With a prefix argument, use the same documentation that was gathered
the last time `icicle-fundoc' was called. Use a prefix arg to save
the time that would be needed to gather the documentation.
Remember that you can use `\\<minibuffer-local-completion-map>\
\\[icicle-cycle-incremental-completion] to toggle incremental completion." ; Doc string
icicle-doc-action ; Action function
prompt ; `completing-read' args
(let ((result (and pref-arg icicle-fundoc-last-initial-cand-set)))
(unless result ; COLLECTION arg is an alist whose items are ((symb doc)).
(mapatoms
#'(lambda (symb) ; Each completion candidate is a list of strings.
(when (fboundp symb)
;; Ignore symbols that produce errors. Example: In Emacs 20, `any', which is defalias'd
;; to `icicle-anything', raises this error: "Symbol's function definition is void: any".
;; This is caused by the `after' advice `ad-advised-docstring' that is defined by Emacs
;; itself for function `documentation'. It is not a problem for Emacs 22+.
(let ((doc (condition-case nil (documentation symb) (error nil))))
(when (and doc (icicle-non-whitespace-string-p (icicle-fn-doc-minus-sig doc)))
(push (list (list (symbol-name symb) doc)) result))))))
(setq icicle-fundoc-last-initial-cand-set result))
result)
nil nil nil 'icicle-doc-history nil nil
((prompt "FUNC `C-M-j' DOC: ") ; Bindings
(icicle-candidate-properties-alist '((1 (face icicle-candidate-part))))
(icicle-list-use-nth-parts '(1))
(pref-arg current-prefix-arg))
(progn
(put-text-property 0 1 'icicle-fancy-candidates t prompt) ; First code
(icicle-highlight-lighter)
(message "Gathering function descriptions...")))
(defun icicle-fn-doc-minus-sig (docstring)
"Return DOCSTRING minus the function signature (usage info)."
(let ((sig-p (string-match "\n\n(fn\\(\\( .*\\)?)\\)\\'" docstring)))
(if sig-p (substring docstring 0 (match-beginning 0)) docstring)))
;;;###autoload (autoload 'icicle-plist "icicles-cmd2.el")
(icicle-define-command icicle-plist ; Command name
"Choose a symbol and its property list.
Each candidate for completion is a symbol name plus its property list
\(as a string). They are separated by `icicle-list-join-string'
\(^G^J, by default). You can match an input regexp against the symbol
name or the property list or both. Use `C-M-j' (equivalent here to
`C-q C-g C-j') to input the default separator.
With a positive prefix argument, use the same initial set of
candidates that were gathered the last time `icicle-plist' was called.
Use a positive prefix arg to save the time that would be needed to
gather the plists.
With a negative prefix arg, do not pretty-print each property list, in
buffers `*Help* and `*Completions*'. Generation of the complete set
of candidates is about twice as fast when not pretty-printed, but the
time to match your input and display candidates is the same, and the
match-and-display time for empty input,is much longer than the
generation time.
The time to repeat (positive prefix arg) is the same, whether or not
candidates were pretty-printed the first time.
Note: Plists are never pretty-printed for Emacs 20, because that seems
to cause an Emacs crash.
Remember that you can use `\\<minibuffer-local-completion-map>\
\\[icicle-cycle-incremental-completion] to toggle incremental completion." ; Doc string
icicle-doc-action ; Action function
prompt ; `completing-read' args
(let ((result (and pref-arg (wholenump (prefix-numeric-value pref-arg))
icicle-plist-last-initial-cand-set)))
(unless result ; COLLECTION arg: an alist with items ((symb plist-string))
(mapatoms
#'(lambda (symb) ; Each completion candidate is a list of strings.
(condition-case nil ; Ignore symbols that produce errors.
(let ((plist (symbol-plist symb)))
(when plist
(push (list (list (symbol-name symb)
(if (or (< (prefix-numeric-value pref-arg) 0)
(< emacs-major-version 21)) ; Emacs 20 crash if pprint.
(format "%s" plist)
(pp-to-string plist))))
result)))
(error nil))))
(setq icicle-plist-last-initial-cand-set result))
result)
nil nil nil nil nil nil
((prompt "SYMB `C-M-j' PLIST: ") ; Bindings
(icicle-candidate-properties-alist '((1 (face icicle-candidate-part))))
(icicle-list-use-nth-parts '(1))
(pref-arg current-prefix-arg))
(progn
(put-text-property 0 1 'icicle-fancy-candidates t prompt) ; First code
(icicle-highlight-lighter)
(message "Gathering property lists...")))
;;;###autoload (autoload 'icicle-doc "icicles-cmd2.el")
(icicle-define-command icicle-doc ; Command name
"Choose documentation for a symbol.
Each candidate for completion is the description of a function,
variable, or face. Displays the documentation and returns the symbol.
Each candidate for completion is a symbol name plus its type
\(FUNCTION, VARIABLE, or FACE) and its documentation. These candidate
components are separated by `icicle-list-join-string' (\"^G^J\", by
default). You can match an input regexp against the symbol name,
type, or the documentation or any combination of the three. Use
`C-M-j' (equivalent here to `C-q C-g C-j') to input the default
separator.
With a prefix argument, use the same documentation that was gathered
the last time `icicle-doc' was called. Use a prefix arg to save the
time that would be needed to gather the documentation.
Remember that you can use \\<minibuffer-local-completion-map>\
`\\[icicle-cycle-incremental-completion]' to toggle incremental completion." ; Doc string
icicle-doc-action ; Action function: display the doc.
prompt ; `completing-read' args
(let ((result (and pref-arg icicle-doc-last-initial-cand-set))
doc) ; Each completion candidate is a list of strings.
(unless result ; COLLECTION arg is an alist with items (doc . symb).
(mapatoms
#'(lambda (symb)
(progn
(when (and (functionp symb) ; Function's doc.
;; Ignore symbols that produce errors. See comment for `icicle-fundoc'.
(setq doc (condition-case nil (documentation symb) (error nil)))
(setq doc (icicle-fn-doc-minus-sig doc))
(icicle-non-whitespace-string-p doc)
(setq doc (concat doc "\n\n")))
(push (cons (list (concat (symbol-name symb) icicle-list-join-string "FUNCTION") doc)
symb)
result))
(when (and (boundp symb) ; Variable's doc (and keymap var's bindings if remove nil)
(setq doc (documentation-property symb 'variable-documentation))
(icicle-non-whitespace-string-p doc))
(when (and nil ; $$$ Remove nil to get keymaps, but it slows things down.
(fboundp 'describe-keymap)
(keymapp (symbol-value symb)))
(setq doc (concat (symbol-name symb) ":\n" doc "\n\n" ; Keymap variable's doc.
(substitute-command-keys
(concat "\\{" (symbol-name symb) "}"))
"\n\n")))
(setq doc (concat doc "\n\n"))
(push (cons (list (concat (symbol-name symb) icicle-list-join-string "VARIABLE") doc)
symb)
result))
(when (and (facep symb)
(setq doc (documentation-property symb 'face-documentation)))
(push (cons (list (concat (symbol-name symb) icicle-list-join-string "FACE") doc)
symb)
result)))))
(setq icicle-doc-last-initial-cand-set result))
result)
nil nil nil 'icicle-doc-history nil nil
((prompt "Find doc using regexp: ") ; Bindings
(icicle-candidate-properties-alist '((1 (face icicle-candidate-part))))
(icicle-list-use-nth-parts '(1))
(icicle-transform-function 'icicle-remove-duplicates) ; Duplicates are due to `fset's.
(icicle-candidate-help-fn 'icicle-doc-action)
(pref-arg current-prefix-arg))
(progn
(put-text-property 0 1 'icicle-fancy-candidates t prompt) ; First code
(icicle-highlight-lighter)
(message "Gathering documentation...")))
(defun icicle-doc-action (entry)
"Completion action function for `icicle-doc': Display the doc."
(let ((symb (intern (icicle-transform-multi-completion entry))))
(cond ((fboundp symb) (describe-function symb))
;; $$$ This works fine, but it slows things down:
;; ((and (fboundp 'describe-keymap) (boundp symb) (keymapp (symbol-value symb)))
;; (describe-keymap symb))
((and symb (boundp symb)) (describe-variable symb))
((facep symb) (describe-face symb)))
symb))
;;;###autoload
(defun icicle-non-whitespace-string-p (string)
"Return non-nil if STRING is a string and contains a non-whitespace char.
The `standard-syntax-table' definition of whitespace is used."
(interactive "s")
(let ((orig-syntable (syntax-table)))
(unwind-protect
(progn
(set-syntax-table (standard-syntax-table))
(and (stringp string) (> (length string) 0) (string-match "\\S-" string)))
(set-syntax-table orig-syntable))))
;;;###autoload
(defun icicle-apropos (apropos-regexp &optional do-all)
"Like `apropos', but lets you see the list of matches (with `S-TAB').
Function names are highlighted using face `icicle-special-candidate'."
(interactive
(list
(unwind-protect
(progn
(mapatoms #'(lambda (symb) (when (fboundp symb) (put symb 'icicle-special-candidate t))))
(let ((icicle-fancy-candidates-p t)
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn
(icicle-alt-act-fn-for-type "symbol")))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn
(icicle-alt-act-fn-for-type "symbol"))))
(completing-read "Apropos symbol (regexp or words): " obarray
nil nil nil 'regexp-history)))
(mapatoms #'(lambda (symb) (put symb 'icicle-special-candidate nil))))
current-prefix-arg))
(apropos apropos-regexp do-all))
(cond
;; Use my versions of the `apropos*' commands, defined in `apropos-fn+var.el'.
;; Note that unlike my versions of `apropos-option' and `apropos-command', the `icicle-'
;; versions here do not respect `apropos-do-all': they always work with options and commands.
((fboundp 'apropos-option)
(defun icicle-apropos-variable (pattern)
"Show variables that match PATTERN.
This includes variables that are not user options.
User options are highlighted using face `icicle-special-candidate'.
You can see the list of matches with `S-TAB'.
See `apropos-variable' for a description of PATTERN."
(interactive
(list
(unwind-protect
(progn
(mapatoms #'(lambda (symb)
(when (user-variable-p symb) (put symb 'icicle-special-candidate t))))
(let ((icicle-fancy-candidates-p t)
(icicle-must-pass-after-match-predicate
#'(lambda (s)
(setq s (intern s))
(and (boundp s) (get s 'variable-documentation))))
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn
(icicle-alt-act-fn-for-type "variable")))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn
(icicle-alt-act-fn-for-type "variable"))))
(completing-read
(concat "Apropos variable (regexp" (and (>= emacs-major-version 22) " or words")
"): ")
obarray nil nil nil 'regexp-history)))
(mapatoms #'(lambda (symb) (put symb 'icicle-special-candidate nil))))))
(apropos-variable pattern))
(defun icicle-apropos-option (pattern)
"Show user options (variables) that match PATTERN.
You can see the list of matches with `S-TAB'.
See `apropos-option' for a description of PATTERN."
(interactive
(let ((icicle-must-pass-after-match-predicate #'(lambda (s) (user-variable-p (intern s)))))
(list (completing-read
(concat "Apropos user option (regexp" (and (>= emacs-major-version 22) " or words")
"): ") obarray nil nil nil 'regexp-history))))
(let ((apropos-do-all nil)
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "option")))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "option"))))
(apropos-option pattern)))
(defun icicle-apropos-function (pattern)
"Show functions that match PATTERN.
This includes functions that are not commands.
Command names are highlighted using face `icicle-special-candidate'.
You can see the list of matches with `S-TAB'.
See `apropos-function' for a description of PATTERN."
(interactive
(list
(unwind-protect
(progn
(mapatoms #'(lambda (symb)
(when (commandp symb) (put symb 'icicle-special-candidate t))))
(let ((icicle-fancy-candidates-p t)
(icicle-must-pass-after-match-predicate #'(lambda (s) (fboundp (intern s))))
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn
(icicle-alt-act-fn-for-type "function")))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn
(icicle-alt-act-fn-for-type "function"))))
(completing-read
(concat "Apropos function (regexp" (and (>= emacs-major-version 22) " or words")
"): ") obarray nil nil nil 'regexp-history)))
(mapatoms #'(lambda (symb) (put symb 'icicle-special-candidate nil))))))
(apropos-function pattern))
(defun icicle-apropos-command (pattern)
"Show commands (interactively callable functions) that match PATTERN.
You can see the list of matches with `S-TAB'.
See `apropos-command' for a description of PATTERN."
(interactive
(let ((icicle-must-pass-after-match-predicate #'(lambda (s) (commandp (intern s))))
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "command")))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "command"))))
(list (completing-read
(concat "Apropos command (regexp" (and (>= emacs-major-version 22) " or words")
"): ") obarray nil nil nil 'regexp-history))))
(let ((apropos-do-all nil)) (apropos-command pattern))))
;; My versions are not available. Use the vanilla Emacs versions of the `apropos...' commands.
(t
(defun icicle-apropos-variable (pattern &optional do-all)
"Show variables that match PATTERN.
You can see the list of matches with `S-TAB'.
See `apropos-variable' for a description of PATTERN.
By default, only user options are candidates. With optional prefix
DO-ALL, or if `apropos-do-all' is non-nil, all variables are
candidates. In that case, the user-option candidates are highlighted
using face `icicle-special-candidate'."
(interactive
(list
(unwind-protect
(progn
(unless (or (boundp 'apropos-do-all) (require 'apropos nil t))
(error "Library `apropos' not found"))
(when (or current-prefix-arg apropos-do-all)
(mapatoms #'(lambda (symb)
(when (user-variable-p symb) (put symb 'icicle-special-candidate t)))))
(let ((icicle-fancy-candidates-p (or current-prefix-arg apropos-do-all))
(icicle-must-pass-after-match-predicate
(if (or current-prefix-arg apropos-do-all)
#'(lambda (s)
(setq s (intern s))
(and (boundp s) (get s 'variable-documentation)))
#'(lambda (s) (user-variable-p (intern s)))))
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn
(icicle-alt-act-fn-for-type (if icicle-fancy-candidates-p
"variable"
"option"))))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn
(icicle-alt-act-fn-for-type (if icicle-fancy-candidates-p
"variable"
"option")))))
(completing-read
(concat "Apropos " (if (or current-prefix-arg apropos-do-all)
"variable" "user option")
" (regexp" (and (>= emacs-major-version 22) " or words") "): ")
obarray nil nil nil 'regexp-history)))
(when (or current-prefix-arg apropos-do-all)
(mapatoms #'(lambda (symb) (put symb 'icicle-special-candidate nil)))))
current-prefix-arg))
(apropos-variable pattern do-all))
(defun icicle-apropos-command (pattern &optional do-all var-predicate)
"Show commands (interactively callable functions) that match PATTERN.
You can see the list of matches with `S-TAB'.
See `apropos-command' for a description of PATTERN.
With \\[universal-argument] prefix, or if `apropos-do-all' is non-nil,
also show noninteractive functions. In that case, the command
candidates are highlighted using face `icicle-special-candidate'.
If VAR-PREDICATE is non-nil, show only variables, and only those that
satisfy the predicate VAR-PREDICATE."
(interactive
(list
(unwind-protect
(progn
(unless (boundp 'apropos-do-all)
(unless (require 'apropos nil t) (error "Library `apropos' not found")))
(when (or current-prefix-arg apropos-do-all)
(mapatoms #'(lambda (symb)
(when (commandp symb) (put symb 'icicle-special-candidate t)))))
(let ((icicle-fancy-candidates-p (or current-prefix-arg apropos-do-all))
(icicle-must-pass-after-match-predicate
(if current-prefix-arg
#'(lambda (s) (fboundp (intern s)))
#'(lambda (s) (commandp (intern s)))))
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn
(icicle-alt-act-fn-for-type (if icicle-fancy-candidates-p
"function"
"command"))))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn
(icicle-alt-act-fn-for-type (if icicle-fancy-candidates-p
"function"
"command")))))
(completing-read
(concat "Apropos " (if (or current-prefix-arg apropos-do-all)
"command or function" "command")
"(regexp" (and (>= emacs-major-version 22) " or words") "): ")
obarray nil nil nil 'regexp-history)))
(when (or current-prefix-arg apropos-do-all)
(mapatoms #'(lambda (symb) (put symb 'icicle-special-candidate nil)))))
current-prefix-arg))
(apropos-command pattern do-all var-predicate))))
;;;###autoload
(defun icicle-apropos-zippy (regexp)
"Show all Zippy quotes matching the regular-expression input REGEXP.
Return the list of matches."
(interactive (progn (unless (boundp 'yow-file)
(unless (require 'yow nil t) (error "Library `yow' not found")))
(cookie yow-file yow-load-message yow-after-load-message)
(let* ((case-fold-search t)
(cookie-table-symbol (intern yow-file cookie-cache))
(string-table (symbol-value cookie-table-symbol))
(table (nreverse (mapcar #'list string-table))))
(list (completing-read "Apropos Zippy (regexp): " table
nil nil nil 'regexp-history)))))
(let ((matches (apropos-zippy icicle-current-input)))
(when (interactive-p)
(with-output-to-temp-buffer "*Zippy Apropos*"
(while matches
(princ (car matches))
(setq matches (cdr matches))
(and matches (princ "\n\n")))))
matches)) ; Return matching Zippyisms.
;;;###autoload
(defalias 'icicle-map 'icicle-apply)
;;;###autoload
(defun icicle-apply (alist fn &optional nomsg predicate initial-input hist def inherit-input-method)
"Selectively apply a function to elements in an alist.
Argument ALIST is an alist such as can be used as the COLLECTION
argument for Icicles `completing-read'. Its elements can represent
multi-completions, for example. Interactively, COLLECTION is a
variable (a symbol) whose value is an alist.
Argument FN is a function.
Optional argument NOMSG non-nil means do not display an informative
message each time FN is applied. If nil, then a message shows the key
of the alist element that FN is applied to and the result of the
application.
The remaining arguments are optional. They are the arguments
PREDICATE, INITIAL-INPUT, HIST, DEF, and INHERIT-INPUT-METHOD for
`completing-read' (that is, all of the `completing-read' args other
than PROMPT, COLLECTION, and REQUIRE-MATCH). During `icicle-apply'
completion, a match is required (REQUIRE-MATCH is t).
Interactively, you are prompted for both arguments. Completion is
available for each. The completion list for ALIST candidates is the
set of variables whose value is a cons. With no prefix argument, the
names of these variables must end with \"alist\". With a prefix
argument, the first car of each variable value must itself be a cons.
After choosing the ALIST and FN, you are prompted to choose one or
more keys of the alist elements, and FN is applied to each element
that has a key that you choose. Multi-command completion is available
for choosing these candidates: you can apply FN to any number of
elements, any number of times.
Examples: If ALIST is `auto-mode-alist' and FN is `cdr', then the
completion candidates are the keys of the alist, and the result of
applying FN to an alist element is simply the value of that key. If
you choose, for example, candidate \"\\.el\\'\", then the result is
`cdr' applied to the alist element (\"\\.el\\'\" . emacs-lisp-mode),
which is the symbol `emacs-lisp-mode'. In this case, the function
performs simple lookup.
If FN were instead (lambda (x) (describe-function (cdr x))), then the
result of choosing candidate \"\\.el\\'\" would be to display the help
for function `emacs-lisp-mode'.
NOTE: `icicle-apply' does not, by itself, impose any particular sort
order. Neither does it inhibit sorting. If you call this function
from Lisp code and you want it to use a certain sort order or you want
no sorting, then bind `icicle-sort-comparer' accordingly.
During completion you can use multi-command keys. Each displays the
value of applying FN to an alist element whose key is a completion
candidate.
`C-RET' - Act on current completion candidate only
`C-down' - Move to next completion candidate and act
`C-up' - Move to previous completion candidate and act
`C-next' - Move to next apropos-completion candidate and act
`C-prior' - Move to previous apropos-completion candidate and act
`C-end' - Move to next prefix-completion candidate and act
`C-home' - Move to previous prefix-completion candidate and act
`C-!' - Act on *each* candidate (or each that is saved), in turn.
`M-!' - Act on the list of *all* candidates (or all saved).
Note that `M-!' applies FN to the *list* of chosen alist elements,
whereas `C-!' applies FN to each chosen element, in turn. For
example, if FN is `length' and your input is `\.el', then `M-!' displays
the result of applying `length' to the list of chosen elements:
((\"\\.el\\'\" . emacs-lisp-mode) (\"\\.elc'\" . emacs-lisp-mode))
which is 2.
When candidate action and cycling are combined (e.g. `C-next'), option
`icicle-act-before-cycle-flag' determines which occurs first.
With prefix `C-M-' instead of `C-', the same keys (`C-M-mouse-2',
`C-M-RET', `C-M-down', and so on) provide help about candidates.
Use `mouse-2', `RET', or `S-RET' to finally choose a candidate, or
`C-g' to quit. This is an Icicles command - see command
`icicle-mode'.
`icicle-apply' overrides `icicle-ignore-space-prefix-flag', binding it
to nil so that candidates with initial spaces can be matched."
(interactive
(list (symbol-value
(intern
(let ((icicle-must-pass-after-match-predicate
`(lambda (s)
(setq s (intern s))
(and (boundp s) (consp (symbol-value s))
,(if current-prefix-arg
'(consp (car (symbol-value s)))
'(string-match "alist$" (symbol-name s))))))
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn
(icicle-alt-act-fn-for-type "variable")))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn
(icicle-alt-act-fn-for-type "variable"))))
(completing-read "Alist (variable): " obarray nil t nil
(if (boundp 'variable-name-history)
'variable-name-history
'icicle-variable-name-history)))))
(read
(let ((icicle-must-pass-after-match-predicate #'(lambda (s) (functionp (intern s))))
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn
(icicle-alt-act-fn-for-type "function")))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn
(icicle-alt-act-fn-for-type "function"))))
(completing-read "Function: " obarray nil nil nil (if (boundp 'function-name-history)
'function-name-history
'icicle-function-name-history))))))
(setq icicle-candidate-entry-fn fn) ; Save in global variable - used by `icicle-apply-action'.
(let ((icicle-candidate-action-fn 'icicle-apply-action)
(icicle-all-candidates-list-action-fn 'icicle-apply-list-action)
(icicle-ignore-space-prefix-flag nil)
(icicle-apply-nomsg nomsg)
(enable-recursive-minibuffers t))
(icicle-explore
#'(lambda ()
(setq icicle-candidates-alist ; Ensure that keys of ALIST are strings or conses.
(mapcar #'(lambda (key+val)
(if (consp (car key+val))
key+val ; Multi-completion candidate: (("aaa" "bbb") . ccc)
(cons (format "%s" (car key+val)) (cdr key+val))))
alist)))
#'(lambda ()
(let ((result (funcall icicle-candidate-entry-fn icicle-explore-final-choice-full)))
(unless nomsg
(message "Key: %s, Result: %s"
(icicle-propertize (car icicle-explore-final-choice-full)
'face 'icicle-msg-emphasis)
(icicle-propertize result 'face 'icicle-msg-emphasis)))
result)) ; Return result.
nil nil nil "Choose an occurrence: " predicate t initial-input hist def inherit-input-method)))
(defun icicle-apply-action (string)
"Completion action function for `icicle-apply'."
(unwind-protect
(icicle-condition-case-no-debug icicle-apply-action
(progn
(icicle-highlight-candidate-in-Completions)
;; Apply function to candidate element and display it.
(let* ((key+value (funcall icicle-get-alist-candidate-function string))
(result (funcall icicle-candidate-entry-fn key+value)))
(unless icicle-apply-nomsg
(icicle-msg-maybe-in-minibuffer
"Key: %s, Result: %s"
(icicle-propertize (car key+value) 'face 'icicle-msg-emphasis)
(icicle-propertize result 'face 'icicle-msg-emphasis))))
nil) ; Return nil for success.
(error "%s" (error-message-string icicle-apply-action))) ; Return error msg.
(select-window (minibuffer-window))
(select-frame-set-input-focus (selected-frame))))
(defun icicle-apply-list-action (strings)
"Completion action list function for `icicle-apply'."
(unwind-protect
(icicle-condition-case-no-debug icicle-apply-list-action
(progn ; Apply function to candidate element and display it.
(icicle-msg-maybe-in-minibuffer
"Result: %s"
(icicle-propertize
(funcall icicle-candidate-entry-fn (mapcar icicle-get-alist-candidate-function strings))
'face 'icicle-msg-emphasis))
nil) ; Return nil for success.
(error "%s" (error-message-string icicle-apply-list-action))) ; Return error msg.
(select-window (minibuffer-window))
(select-frame-set-input-focus (selected-frame))))
;;;###autoload
(defun icicle-goto-marker-or-set-mark-command (arg) ; Bound to `C-@', `C-SPC'.
"With prefix arg < 0, `icicle-goto-marker'; else `set-mark-command'.
By default, Icicle mode remaps all key sequences that are normally
bound to `set-mark-command' to
`icicle-goto-marker-or-set-mark-command'. If you do not want this
remapping, then customize option `icicle-top-level-key-bindings'."
(interactive "P")
(if (not (wholenump (prefix-numeric-value arg)))
(icicle-goto-marker)
(setq this-command 'set-mark-command) ; Let `C-SPC C-SPC' activate if not `transient-mark-mode'.
(set-mark-command arg)))
;;;###autoload
(defun icicle-goto-global-marker-or-pop-global-mark (arg) ; Bound to `C-x C-@', `C-x C-SPC'.
"With prefix arg < 0, `icicle-goto-global-marker'; else `pop-global-mark'.
By default, Icicle mode remaps all key sequences that are normally
bound to `pop-global-mark' to
`icicle-goto-global-marker-or-pop-global-mark'. If you do not want
this remapping, then customize option
`icicle-top-level-key-bindings'."
(interactive "P")
(if (wholenump (prefix-numeric-value arg))
(pop-global-mark)
(icicle-goto-global-marker)))
;;;###autoload
(defun icicle-goto-marker () ; Bound to `C-- C-@', `C-- C-SPC'.
"Go to a marker in this buffer, choosing it by the line that includes it.
If `crosshairs.el' is loaded, then the target position is highlighted.
By default, candidates are sorted in marker order, that is, with
respect to their buffer positions. Use `C-M-,' or `C-,' to change the
sort order.
During completion you can use these keys:
`C-RET' - Goto marker named by current completion candidate
`C-down' - Goto marker named by next completion candidate
`C-up' - Goto marker named by previous completion candidate
`C-next' - Goto marker named by next apropos-completion candidate
`C-prior' - Goto marker named by previous apropos-completion candidate
`C-end' - Goto marker named by next prefix-completion candidate
`C-home' - Goto marker named by previous prefix-completion candidate
`S-delete' - Delete marker named by current completion candidate
When candidate action and cycling are combined (e.g. `C-next'), option
`icicle-act-before-cycle-flag' determines which occurs first.
With prefix `C-M-' instead of `C-', the same keys (`C-M-mouse-2',
`C-M-RET', `C-M-down', and so on) provide help about candidates.
Use `mouse-2', `RET', or `S-RET' to choose a candidate as the final
destination, or `C-g' to quit. This is an Icicles command - see
command `icicle-mode'."
(interactive)
(let ((icicle-sort-orders-alist (cons '("by position" . icicle-cdr-lessp)
icicle-sort-orders-alist))
(icicle-sort-comparer 'icicle-cdr-lessp))
(icicle-goto-marker-1 mark-ring)))
;;;###autoload
(defun icicle-goto-global-marker () ; Bound to `C-- C-x C-@', `C-- C-x C-SPC'.
"Like `icicle-goto-marker', but visits global, not local, markers.
If user option `icicle-show-multi-completion-flag' is non-nil, then
each completion candidate is annotated (prefixed) with the name of the
marker's buffer, to facilitate orientation."
(interactive)
(let ((icicle-list-nth-parts-join-string "\t")
(icicle-list-join-string "\t")
;; $$$$$$ (icicle-list-end-string "")
(icicle-sort-orders-alist
(cons '("by buffer, then by position" . icicle-part-1-cdr-lessp)
icicle-sort-orders-alist))
(icicle-sort-comparer 'icicle-part-1-cdr-lessp)
(icicle-candidate-properties-alist (and icicle-show-multi-completion-flag
'((1 (face icicle-candidate-part))))))
(icicle-goto-marker-1 global-mark-ring)))
(defun icicle-goto-marker-1 (ring)
"Helper function for `icicle-goto-marker', `icicle-goto-global-marker'.
RING is the marker ring to use."
(unwind-protect
(let* ((global-ring-p
(memq this-command '(icicle-goto-global-marker
icicle-goto-global-marker-or-pop-global-mark)))
(markers
(if (and (not global-ring-p) (marker-buffer (mark-marker)))
(cons (mark-marker) (icicle-markers ring))
(icicle-markers ring)))
(icicle-delete-candidate-object
#'(lambda (cand)
(let ((mrkr+txt (funcall icicle-get-alist-candidate-function cand)))
(move-marker (cdr mrkr+txt) nil))))
(icicle-alternative-sort-comparer nil)
(icicle-last-sort-comparer nil)
(icicle-orig-buff (current-buffer)))
(unless (consp markers)
(error (if global-ring-p "No global markers" "No markers in this buffer")))
(cond ((cdr markers)
(icicle-apply (mapcar #'(lambda (mrkr) (icicle-marker+text mrkr global-ring-p))
markers)
#'icicle-goto-marker-1-action
'nomsg
(lambda (cand)
(marker-buffer (cdr cand)))))
((= (point) (car markers)) (message "Already at marker: %d" (point)))
(t
(icicle-goto-marker-1-action (icicle-marker+text (car markers) global-ring-p)))))
(when (fboundp 'crosshairs-unhighlight) (crosshairs-unhighlight 'even-if-frame-switch))))
(defun icicle-goto-marker-1-action (cand)
"Action function for `icicle-goto-marker-1'."
(pop-to-buffer (marker-buffer (cdr cand)))
(select-frame-set-input-focus (selected-frame))
(goto-char (cdr cand))
(unless (pos-visible-in-window-p) (recenter icicle-recenter))
(when (fboundp 'crosshairs-highlight) (crosshairs-highlight)))
(defun icicle-marker+text (marker &optional globalp)
"Cons of text line that includes MARKER with MARKER itself.
If the marker is on an empty line, then text \"<EMPTY LINE>\" is used.
If both optional argument GLOBALP and option
`icicle-show-multi-completion-flag' are non-nil, then the text is
prefixed by MARKER's buffer name."
(with-current-buffer (marker-buffer marker)
(save-excursion
(goto-char marker)
(let ((line (let ((inhibit-field-text-motion t)) ; Just to be sure, for `line-end-position'.
(buffer-substring-no-properties (line-beginning-position) (line-end-position))))
(buff (and globalp icicle-show-multi-completion-flag (buffer-name)))
(help (and (or (> icicle-help-in-mode-line-delay 0) ; Get it only if user will see it.
(and (boundp 'tooltip-mode) tooltip-mode))
(format "Line: %d, Char: %d" (line-number-at-pos) (point)))))
(when (string= "" line) (setq line "<EMPTY LINE>"))
(when help
(icicle-candidate-short-help help line)
(when (and globalp icicle-show-multi-completion-flag)
(icicle-candidate-short-help help buff)))
(if (and globalp icicle-show-multi-completion-flag)
(cons (list buff line) marker)
(cons line marker))))))
(defun icicle-markers (ring)
"Marks in mark RING that are in live buffers other than a minibuffer."
(let ((markers ()))
(dolist (mkr ring)
(when (and (buffer-live-p (marker-buffer mkr))
(not (string-match "\\` \\*Minibuf-[0-9]+\\*\\'"
(buffer-name (marker-buffer mkr)))))
(push mkr markers)))
markers))
;;;###autoload
(defun icicle-exchange-point-and-mark (&optional arg) ; Bound to `C-x C-x'.
"`exchange-point-and-mark' or save a region or select a saved region.
With no prefix arg, invoke `exchange-point-and-mark'.
If you use library `Bookmark+', then you can use a prefix arg.
* Plain `C-u': select (activate) one or more bookmarked regions.
* Numeric prefix arg: bookmark (save) the active region using
`icicle-bookmark-cmd'.
Arg < 0: Prompt for the bookmark name.
Arg > 0: Do not prompt for the bookmark name. Use the buffer name
plus a prefix of the region text as the bookmark name.
Arg = 0: Same as > 0, except do not overwrite any existing bookmark
with the same name.
By default, Icicle mode remaps all key sequences that are normally
bound to `exchange-point-and-mark' to
`icicle-exchange-point-and-mark'. If you do not want this remapping,
then customize option `icicle-top-level-key-bindings'."
(interactive "P")
(let ((bplus (featurep 'bookmark+)))
(if (not arg)
(call-interactively #'exchange-point-and-mark)
(unless bplus (error "You must load library `Bookmark+' to use a prefix arg"))
(cond ((atom arg)
(unless (and transient-mark-mode mark-active (not (eq (mark) (point))))
(error "Cannot bookmark inactive region: you must activate it first"))
(icicle-bookmark-cmd (and (natnump (prefix-numeric-value arg)) 9)))
(t
(bookmark-maybe-load-default-file)
(unless (consp (bmkp-region-alist-only)) (error "No bookmarked regions"))
(call-interactively #'icicle-select-bookmarked-region))))))
;;;###autoload
(defun icicle-search-generic () ; Bound to `C-c `'.
"Run `icicle-search-command'. By default, this is `icicle-search'.
In Compilation and Grep modes, this is `icicle-compilation-search'.
In Comint, Shell, GUD, and Inferior Lisp modes, this is
`icicle-comint-search'."
(interactive)
(call-interactively icicle-search-command))
;;;###autoload
(defun icicle-search (beg end scan-fn-or-regexp require-match ; Bound to `M-s M-s M-s', `C-c `'.
&optional where &rest args)
"Search for matches, with completion, cycling, and hit replacement.
Search a set of contexts, which are defined interactively by
specifying a regexp (followed by `RET').
After specifying the regexp that defines the search contexts, type
input (e.g. regexp or other pattern) to match within the contexts.
The contexts that match your input are available as completion
candidates. You can use `M-*' to further narrow the candidates,
typing additional patterns to match.
By default, candidates are in order of buffer occurrence, but you can
sort them in various ways using `C-,'.
You can replace individual matches with another string, as in
`query-replace' or `query-replace-regexp'. See the Icicles Search doc
for more info.
Non-interactively, search can be for regexp matches or any other kind
of matches. Argument SCAN-FN-OR-REGEXP is the regexp to match, or it
is a function that defines an alist of buffer zones to search. You
can navigate among the matching buffer zones (defined either as regexp
matches or via function), called search \"contexts\", and you can
match another regexp against the text in a search context. See the
end of this description for information about the other arguments.
If the search-context regexp contains regexp subgroups, that is,
subexpressions of the form `\(...\)', then you are prompted for the
subgroup to use to define the search contexts. Subgroup 0 means the
context is whatever matches the whole regexp. Subgroup 1 means the
context is whatever matches the first subgroup, and so on. The
subgroup number is the number of occurrences of `\(', starting at the
beginning of the regexp.
Search respects `icicle-regexp-quote-flag' and
`icicle-search-whole-word-flag'. You can toggle these during search,
by using `C-`' and `M-q', respectively. If `icicle-regexp-quote-flag'
is non-nil, then regexp special characters are quoted, so that they
become non-special. If `icicle-search-whole-word-flag' is non-nil,
then whole-word searching is done. (You can also use `M-s M-s w' to
perform word search.)
For each of the predefined Icicles search commands, including for
`icicle-search' itself, you can alternatively choose to search, not
the search contexts as you define them, but the non-contexts, that is,
the buffer text that is outside (in between) the search contexts as
defined. For example, if you use `icicle-search-thing' and you define
sexps as the search contexts, then this feature lets you search the
zones of text that are not within a sexp.
To do this, use `C-M-~' (`icicle-toggle-search-complementing-domain')
during completion to turn on `icicle-search-complement-domain-p'.
\(This is a toggle, and it affects only future search commands, not
the current one.)
Optional Behaviors: Prefix Argument
-----------------------------------
By default, search only the current buffer. Search the active region,
or, if there is none, then search the entire buffer.
With a prefix argument, you can search multiple buffers, files, or
bookmarks, as follows:
- With a plain prefix arg (`C-u'), search bookmarks. This is the
same as command `icicle-search-bookmarks-together'. (To search
bookmarks one at a time instead of together, use multi-command
`icicle-search-bookmark'.)
- With a positive numeric prefix arg, search multiple buffers
completely. You are prompted for the buffers to search - all of each
buffer is searched. Any existing buffers can be chosen. If the
prefix arg is 99, then only buffers visiting files are candidates.
This is the same as command `icicle-search-buffer'.
- With a negative numeric prefix arg, search multiple files
completely. You are prompted for the files to search - all of each
file is searched. Any existing files in the current directory can be
chosen. This is the same as command `icicle-search-file'.
- With a zero (0) prefix arg, search contexts that are determined in a
context-dependent way. For example:
. in Dired, search the marked files
. in a `buffer-menu' or `ibuffer' buffer, search the marked buffers
. in a bookmark list buffer, search the marked bookmarks
Navigation and Help
-------------------
The use of completion for this command is special. It is not unusual
in this context to have multiple completion candidates that are
identical - only the positions of their occurrences in the search
buffer(s) differ. In that case, you cannot choose one simply by
completing it in the minibuffer, because the destination would be
ambiguous. That is, simply completing your input and entering the
completion with `RET' will not take you to its occurrence in the
search buffer, unless it is unique.
Instead, choose search hits to visit using any of the candidate-action
keys: `C-RET', `C-mouse-2', `C-down', `C-up', `C-next', `C-prior',
`C-end', and `C-home'. All but the first two of these cycle among the
search hits. The current candidate in `*Completions*' corresponds to
the current location visited (it is not off by one, as is usually the
case in Icicles).
As always, the `C-M-' keys provide help on individual candidates:
`C-M-RET', `C-M-mouse-2', `C-M-down', `C-M-up', `C-M-next',
`C-M-prior', `C-M-end', and `C-M-home'. For `icicle-search', they
indicate the buffer and position of the search hit.
You can cycle among candidates without moving to their occurrences in
the search buffer, using `down', `up', `next', `prior', `end', or
`home' (no `C-' modifier).
Highlighting
------------
In the search buffer (that is, where the hits are), `icicle-search'
does the following:
- Highlights the current match (buffer zone) for the initial (context)
regexp, using face `icicle-search-main-regexp-current'.
- Highlights the first `icicle-search-highlight-threshold' context
matches (or all, if the option value is `t'), using face
`icicle-search-main-regexp-others'.
- Highlights 1-8 context levels, within each search context. This
happens only if your initial (context) regexp has \\(...\\) groups
and option `icicle-search-highlight-context-levels-flag' is non-nil.
- Highlights the match for your current input, using face
`icicle-search-current-input'. Highlights all such matches if
option `icicle-search-highlight-all-current-flag' is non-nil;
otherwise, highlights just the currently visited match.
You can toggle this option using `C-^'.
If user option `icicle-search-cleanup-flag' is non-nil (the default),
then all search highlighting is removed from the search buffer when
you are finished searching. If it is nil, then you can remove this
highlighting later using command `icicle-search-highlight-cleanup'.
You can toggle `icicle-search-cleanup-flag' during Icicles search
using `C-.' in the minibuffer.
`*Completions*' Display
-----------------------
In buffer `*Completions*', in addition to eliding the common match
\(option `icicle-hide-common-match-in-Completions-flag', toggled
anytime using `C-x .' - no prefix arg), you can elide all lines of a
multi-line candidate that do not match your current minibuffer input.
This hiding is governed by option
`icicle-hide-non-matching-lines-flag', which you can toggle anytime
during completion using `C-u C-x .' (this is not specfic to Icicles
search). This can be useful when candidates are very long, as can be
the case for instance for the `icicle-imenu-*-full' commands.
Search and Replace
------------------
You can replace the current search match by using any of the
alternative action keys: `C-S-RET', `C-S-mouse-2' (in
`*Completions*'), `C-S-down', `C-S-up', `C-S-next', `C-S-prior',
`C-S-end', and `C-S-home'. You can use `M-|' to replace all matches
at once. (And remember that you can activate the region to limit the
search-and-replace space.)
At the first use of any of these, you are prompted for the replacement
string; it is used thereafter, or until you use `M-,'
\(`icicle-search-define-replacement') to change it (anytime).
Unlike `query-replace', you need not visit search matches successively
or exhaustively. You can visit and replace selected matches in any
order.
What is meant here by a \"search match\"? It can be either an entire
search context or just a part of the context that your current
minibuffer input matches.
`C-,' toggles option `icicle-search-replace-whole-candidate-flag'. By
default, the entire current search context is replaced, that is,
whatever matches the context regexp that you entered initially using
`RET'. However, you can use `C-,' anytime during searching to toggle
between this default behavior and replacement of whatever your current
minibuffer input matches.
Remember this:
- If `icicle-search-replace-whole-candidate-flag' is non-nil, then
the granularity of replacement is a complete search context. In
this case, replacement behaves similarly to `query-replace-regexp'.
You can still use minibuffer input to filter the set of search
contexts, but replacement is on a whole-context basis.
- If `icicle-search-replace-whole-candidate-flag' is nil, then you
can replace multiple input matches separately within a search
context (using `C-S-RET'). This behavior is unique to Icicles.
You cannot, however skip over one input match and replace the next
one in the same context - `C-S-RET' always replaces the first
available match.
If `icicle-search-replace-whole-candidate-flag' is non-nil, then you
can use the navigational alternative action keys, `C-S-down',
`C-S-up', `C-S-next', `C-S-prior', `C-S-end', and `C-S-home',
repeatedly to replace successive search contexts. At the buffer
limits, these commands wraps around to the other buffer limit (last
search context to first, and vice versa).
Search traversal using these go-to-next-context-and-replace keys is
always by search context, not by individual input match. This means
that you cannot use these keys to replace input matches within a
search context (except for the first such match, if
`icicle-search-replace-whole-candidate-flag' is nil).
If your input matches multiple parts of a search context, and you want
to replace these in order, then use `C-S-RET' repeatedly. You can
traverse all matches of your input in the order they appear in the
buffer by repeating `C-S-RET' (provided the replacement text does not
also match your input - see below). At the buffer limits, repeating
`C-S-RET' wraps around too.
`C-S-RET' always replaces the first input match in the current search
context or, if there are no matches, then the first input match in the
next context. This behavior has these important consequences:
* If you repeat `C-S-RET' and the previous replacement no longer
matches your input, then `C-S-RET' moves on to the next input match
(which is now the first one) and replaces that. This is why you can
usually just repeat `C-S-RET' to successively replaces matches of
your input, including from one context to the next.
* If, on the other hand, after replacement the text still matches your
input, then repeating `C-S-RET' will just replace that match.
For example, if you replace the input match `ab' by `abcd', then
repeating `C-S-RET' produces `abcd', then `abcdcd', then `abcdcd'...
* You cannot replace an input match, skip the next match, and then
replace the following one, all in the same context. You can,
however, replace some matches and then skip (e.g. `C-next') to the
next context.
What your input matches, hence what gets replaced if
`icicle-search-replace-whole-candidate-flag' is nil, depends on a few
Icicles options:
- `icicle-regexp-quote-flag' determines whether to use regexp
matching or literal matching.
- `icicle-search-highlight-all-current-flag',
`icicle-expand-input-to-common-match-flag' and
`icicle-search-replace-common-match-flag' together determine
whether to replace exactly what your input matches in the current
search hit or the expanded common match (ECM) of your input among
all search hits. If any of these options is nil, then your exact
input match is replaced; if they are all non-nil, then the ECM is
replaced.
Finally, the replacement string can be nearly anything that is allowed
as a replacement by `query-replace-regexp'. In Emacs 22 or later,
this includes Lisp sexp evaluation via `\,' and constructs such as
`\#' and `\N' (back references). You can also use `\?', but it is not
very useful - you might as well use `M-,' instead, to change the
replacement text.
Using Regexps
-------------
At any time, you can use `\\<minibuffer-local-completion-map>\
\\[icicle-insert-string-from-variable]' (command
`icicle-insert-string-from-variable') to insert text (e.g. a regexp)
from a variable into the minibuffer. For example, you can search for
ends of sentences by using `C-u \\[icicle-insert-string-from-variable]' and choosing variable
`sentence-end' as the variable. And you can use
`\\[icicle-save-string-to-variable]' to save a string to a variable
for later use by `\\[icicle-insert-string-from-variable]'.
When employed with useful regexps, `\\<minibuffer-local-completion-map>\
\\[icicle-insert-string-from-variable]' can turn `icicle-search' into
a general navigator or browser of code, mail messages, and many other
types of buffer. Imenu regexps work fine, for example - command
`icicle-imenu' simply uses `icicle-search' this way. See
`icicle-insert-string-from-variable' for more tips on inserting
regexps from variables.
Additional Information
----------------------
If user option `icicle-show-multi-completion-flag' is non-nil, then
each candidate is annotated with the name of the buffer where the
search hit occurs, to facilitate orientation. Note that even when the
value is nil, you can use `C-M-mouse-2' and so on to see the buffer
name, as well as the position of the hit in the buffer.
Completion is lax if `icicle-show-multi-completion-flag' is non-nil;
otherwise, it is strict.
After you visit a completion candidate, the hooks in variable
`icicle-search-hook' are run.
`icicle-search' overrides `icicle-ignore-space-prefix-flag', binding
it to nil, so that candidates with initial spaces can be matched.
`icicle-search' sets `icicle-search-final-choice' to the final user
choice, which might not be one of the search candidates if
REQUIRE-MATCH is nil.
Non-Interactive Use
-------------------
Function `icicle-search' is not only a powerful command, it is also a
building block for creating your own Icicles search-and-replace
commands. When called non-interactively, these are the
`icicle-search' arguments:
BEG is the beginning of the region to search; END is the end.
SCAN-FN-OR-REGEXP: Regexp or function that determines the set of
initial candidates (match zones). If a function, it is passed, as
arguments, the buffer to search, the beginning and end of the search
region in that buffer, and ARGS.
REQUIRE-MATCH is passed to `completing-read'.
Optional arg WHERE is a list of bookmarks, buffers, or files to be
searched. If nil, then search only the current buffer or region.
(To search bookmarks you must also use library `Bookmark+').
ARGS are arguments that are passed to function SCAN-FN-OR-REGEXP.
Note that if SCAN-FN-OR-REGEXP is a regexp string, then function
`icicle-search-regexp-scan' is used to determine the set of match
zones. You can limit hits to regexp matches that also satisfy a
predicate, by using `(PREDICATE)' as ARGS: PREDICATE is then passed to
`icicle-search-regexp-scan' as its PREDICATE argument.
This command is intended for use only in Icicle mode."
(interactive `(,@(icicle-region-or-buffer-limits)
,(if icicle-search-whole-word-flag
(icicle-search-read-word)
(icicle-search-read-context-regexp))
,(not icicle-show-multi-completion-flag)
,(icicle-search-where-arg)))
(setq icicle-search-context-regexp (and (stringp scan-fn-or-regexp) scan-fn-or-regexp))
(let ((icicle-candidate-action-fn (or icicle-candidate-action-fn
'icicle-search-action))
(icicle-candidate-help-fn 'icicle-search-help)
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn 'icicle-search-replace-all-search-hits))
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn 'icicle-search-replace-search-hit))
(icicle-scan-fn-or-regexp scan-fn-or-regexp) ; Used free in `M-,'.
(icicle-update-input-hook (list 'icicle-search-highlight-all-input-matches))
(icicle-search-ecm nil)
(icicle-searching-p t)
(icicle-search-replacement nil)
(icicle-current-input "")
(icicle-list-nth-parts-join-string "\t")
(icicle-list-join-string "\t")
;; $$$$$$ (icicle-list-end-string "")
(icicle-list-use-nth-parts '(1))
(icicle-sort-comparer nil)
;; Alternative: If we used `icicle-search-replace-cand-in-alist', then we would inhibit
;; sorting, because we would be depending on the alist order.
;; (icicle-inhibit-sort-p t)
(icicle-no-match-hook icicle-no-match-hook)
(completion-ignore-case case-fold-search)
(replace-count 0)) ; Defined in `replace.el'. Used for replacement.
(add-hook 'icicle-no-match-hook (lambda () (when (overlayp icicle-search-current-overlay)
(delete-overlay icicle-search-current-overlay))))
(setq icicle-search-final-choice
(icicle-explore #'(lambda () (icicle-search-define-candidates beg end scan-fn-or-regexp
require-match where args))
#'icicle-search-final-act #'icicle-search-quit-or-error
#'icicle-search-quit-or-error #'icicle-search-cleanup
"Choose an occurrence: " nil require-match nil 'icicle-search-history))))