Update upstream source from tag 'upstream/4.14'
Update to upstream version '4.14'
with Debian dir 1f4cb39cf031c8bf0d938874af749f945ac473e5
Lev Lamberov
1 year, 11 months ago
0 | language: generic | |
1 | dist: trusty | |
2 | sudo: false | |
3 | ||
4 | env: | |
5 | matrix: | |
6 | - EMACS_VERSION=emacs-24.4 | |
7 | - EMACS_VERSION=emacs-24.5 | |
8 | - EMACS_VERSION=emacs-25.1 | |
9 | - EMACS_VERSION=emacs-25.2 | |
10 | - EMACS_VERSION=emacs-25.3 | |
11 | - EMACS_VERSION=emacs-26.1 | |
12 | - EMACS_VERSION=emacs-git-snapshot | |
13 | - EMACS_VERSION=remacs-git-snapshot | |
14 | ||
15 | matrix: | |
16 | allow_failures: | |
17 | - env: EMACS_VERSION=remacs-git-snapshot | |
18 | - env: EMACS_VERSION=emacs-git-snapshot | |
19 | ||
20 | before_script: | |
21 | # Install evm | |
22 | - git clone https://github.com/rejeep/evm.git ~/.evm | |
23 | - export PATH="$HOME/.evm/bin:$PATH" | |
24 | - evm config path /tmp | |
25 | - evm list | |
26 | # use this version of emacs for tests | |
27 | - evm install "${EMACS_VERSION}-travis" --use --skip | |
28 | - evm list | |
29 | - emacs --version | |
30 | # Install cask | |
31 | - curl -fsSkL https://raw.github.com/cask/cask/master/go | python | |
32 | - export PATH="$HOME/.cask/bin:$PATH" | |
33 | # Fix cask (See https://github.com/cask/cask/issues/399#issuecomment-331640427) | |
34 | - perl -ibak -lape 's{#!/usr/bin/env python}{#!/usr/bin/python}' "$(which cask)" | |
35 | # Check that cask is finding the right emacs | |
36 | - cask emacs --version | |
37 | # Install elisp dependencies | |
38 | - cask install | |
39 | ||
40 | script: | |
41 | - make compile | |
42 | # Don't send redundant coverage info | |
43 | - UNDERCOVER_CONFIG='((:send-report nil))' make test | |
44 | # For some reason emacs-git-snapshot hangs forever on this step | |
45 | - if [ "$EMACS_VERSION" != emacs-git-snapshot ]; then make test-with-flx; fi |
0 | (source gnu) | |
1 | (source melpa) | |
2 | ||
3 | (package-file "ido-completing-read+.el") | |
4 | ||
5 | (depends-on "s") | |
6 | (depends-on "memoize" "1.1") | |
7 | ||
8 | (development | |
9 | (depends-on "flx-ido") | |
10 | (depends-on "with-simulated-input" "2.2") | |
11 | (depends-on "buttercup" "1.9") | |
12 | (depends-on "undercover")) |
0 | 2021-03-30 Ryan C. Thompson <rct@thompsonclan.org> | |
1 | ||
2 | * ido-completing-read+.el (ido-cr+-disable-list): Rename from | |
3 | ido-cr+-function-blacklist. Related functions and variables are | |
4 | likewise renamed. | |
5 | (ido-cr+-allow-list): Rename from ido-cr+-function-whitelist. | |
6 | Related functions and variables are likewise renamed. | |
7 | ||
8 | 2021-02-06 Ryan C. Thompson <rct@thompsonclan.org> | |
9 | ||
10 | * ido-completing-read+.el (ido-cr+-function-blacklist): Disable | |
11 | ido completion in org-olpath-completing-read | |
12 | * ido-completing-read+.el: General bug fixes | |
13 | ||
0 | 14 | 2019-07-18 Ryan C. Thompson <rct@thompsonclan.org> |
1 | 15 | |
2 | 16 | * ido-completing-read+.el (ido-completing-read+): Disable |
0 | ;; -*- mode: emacs-lisp; lexical-binding: t; no-byte-compile: t -*- | |
1 | ||
2 | (setq eldev-main-fileset "./*.el") | |
3 | ||
4 | (eldev-use-plugin 'undercover) | |
5 | (eldev-use-plugin 'autoloads) | |
6 | ||
7 | (eldev-use-package-archive 'gnu) | |
8 | (eldev-use-package-archive 'melpa-unstable) | |
9 | ||
10 | (setq eldev-test-framework 'buttercup) | |
11 | ||
12 | (eldev-add-extra-dependencies | |
13 | 'test | |
14 | 'flx-ido | |
15 | 's | |
16 | '(:package with-simulated-input | |
17 | :version "3.0")) | |
18 | ||
19 | ;; Tell checkdoc not to demand two spaces after a period. | |
20 | (setq sentence-end-double-space nil) |
0 | ;; -*- mode: emacs-lisp; lexical-binding: t; no-byte-compile: t -*- | |
1 | ||
2 | ;; This file is meant to be loaded with `eldev -S' to run the flx-ido | |
3 | ;; tests instead of the regular ones. | |
4 | (setq eldev-test-fileset '("./tests-with-flx-ido/" "./tests/")) |
0 | ELISP_FILES := $(shell cask files) | |
1 | ELC_FILES := $(patsubst %.el,%.elc,$(ELISP_FILES)) | |
2 | ||
3 | .PHONY: test compile clean | |
4 | .INTERMEDIATE: .compile.intermediate | |
5 | ||
6 | all: test | |
7 | ||
8 | # We run clean-elc first because undercover.el doesn't support elc | |
9 | # files. We run the tests first without loading flx-ido, and then with | |
10 | # it. We only send the coverage report when running the full test | |
11 | # suite. | |
12 | test: clean | |
13 | cask exec buttercup -L . tests | |
14 | ||
15 | test-with-flx: clean | |
16 | cask exec buttercup -l tests/setup-undercover.el -L . tests tests-with-flx-ido | |
17 | ||
18 | all-tests: test test-with-flx | |
19 | ||
20 | compile: $(ELC_FILES) | |
21 | ||
22 | $(ELC_FILES): .compile.intermediate | |
23 | .compile.intermediate: $(ELISP_FILES) | |
24 | cask build | |
25 | ||
26 | clean: | |
27 | cask clean-elc |
1 | 1 | |
2 | 2 | [![MELPA Stable](https://stable.melpa.org/packages/ido-completing-read+-badge.svg)](https://stable.melpa.org/#/ido-completing-read%2B) |
3 | 3 | [![Join the chat at https://gitter.im/DarwinAwardWinner/ido-ubiquitous](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/DarwinAwardWinner/ido-ubiquitous?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) |
4 | [![Build Status](https://travis-ci.org/DarwinAwardWinner/ido-completing-read-plus.svg?branch=master)](https://travis-ci.org/DarwinAwardWinner/ido-completing-read-plus) | |
5 | [![Coverage Status](https://coveralls.io/repos/github/DarwinAwardWinner/ido-completing-read-plus/badge.svg?branch=master)](https://coveralls.io/github/DarwinAwardWinner/ido-completing-read-plus?branch=master) | |
4 | [![Coverage Status](https://coveralls.io/repos/github/DarwinAwardWinner/ido-completing-read-plus/badge.svg?branch=main)](https://coveralls.io/github/DarwinAwardWinner/ido-completing-read-plus?branch=main) | |
6 | 5 | |
7 | 6 | This package replaces stock emacs completion with ido completion |
8 | 7 | wherever it is possible to do so without breaking things (i.e. what |
18 | 17 | of both packages. The distinction between "new" and "old" default |
19 | 18 | selection styles has been eliminated and replaced by a new variable |
20 | 19 | `ido-cr+-nil-def-alternate-behavior-list` (see [FAQ][1] for details), |
21 | and the override system has been accordingly simplified into just a | |
22 | blacklist and a whitelist. If you have previously customized any | |
20 | and the override system has been accordingly simplified into just an | |
21 | allow list and a disable list. If you have previously customized any | |
23 | 22 | ido-ubiquitous options, be sure to check out |
24 | 23 | |
25 | 24 | `M-x customize-group ido-completing-read+` |
43 | 42 | ## Ido itself ## |
44 | 43 | |
45 | 44 | First, enable `ido-mode` and `ido-everywhere`. |
45 | ||
46 | 46 | ```elisp |
47 | 47 | (ido-mode 1) |
48 | 48 | (ido-everywhere 1) |
49 | 49 | ``` |
50 | ||
50 | 51 | ## ido-completing-read+ (this package) ## |
51 | 52 | |
52 | Install this package [from MELPA](http://melpa.org/#/ido-completing-read+) | |
53 | Install this package [from MELPA](https://melpa.org/#/ido-completing-read+) | |
53 | 54 | and then turn on `ido-ubiquitous-mode`: |
55 | ||
54 | 56 | ```elisp |
55 | 57 | (require 'ido-completing-read+) |
56 | 58 | (ido-ubiquitous-mode 1) |
57 | 59 | ``` |
58 | ## Smex ## | |
59 | ||
60 | Smex allows you to use ido for completion of commands in M-x, with | |
61 | enhancements like putting your most-used commands at the front of the | |
62 | list. First install the [smex](https://github.com/nonsequitur/smex) | |
63 | package, then follow the directions to load it and replace your normal | |
64 | M-x key-binding with smex: | |
65 | ```elisp | |
66 | (require 'smex) ; Not needed if you use package.el | |
67 | (smex-initialize) ; Can be omitted. This might cause a (minimal) delay | |
68 | ; when Smex is auto-initialized on its first run. | |
69 | (global-set-key (kbd "M-x") 'smex) | |
70 | (global-set-key (kbd "M-X") 'smex-major-mode-commands) | |
71 | ;; This is your old M-x. | |
72 | (global-set-key (kbd "C-c C-c M-x") 'execute-extended-command) | |
73 | ``` | |
74 | (These directions are the same ones given in the smex README file.) | |
60 | ||
61 | ## Amx ## | |
62 | ||
63 | Amx, another of my packages, allows you to use alternate completion | |
64 | systems like ido for commands in M-x, with enhancements like putting | |
65 | your most-used commands at the front of the list. First install | |
66 | [amx](https://melpa.org/#/amx) from MELPA, then turn on `amx-mode`: | |
67 | ||
68 | ```elisp | |
69 | (require 'amx) | |
70 | (amx-mode 1) | |
71 | ``` | |
75 | 72 | |
76 | 73 | ## ido-yes-or-no ## |
77 | 74 | |
78 | 75 | If you want to use ido for yes-or-no questions, even though it's |
79 | 76 | massive overkill, install my [ido-yes-or-no package from MELPA](http://melpa.org/#/ido-yes-or-no), and then enable the mode: |
77 | ||
80 | 78 | ```elisp |
81 | 79 | (require 'ido-yes-or-no) |
82 | 80 | (ido-yes-or-no-mode 1) |
83 | 81 | ``` |
82 | ||
84 | 83 | ## ido for `describe-face` and certain other commands ## |
85 | 84 | |
86 | 85 | Some commands, such as `describe-face`, use `completing-read-multiple` |
91 | 90 | the [crm-custom](https://github.com/DarwinAwardWinner/crm-custom) |
92 | 91 | package [from MELPA](http://melpa.org/#/crm-custom), then enable the |
93 | 92 | mode: |
93 | ||
94 | 94 | ```elisp |
95 | 95 | (require 'crm-custom) |
96 | 96 | (crm-custom-mode 1) |
97 | 97 | ``` |
98 | ||
98 | 99 | Make sure to read and understand the FAQ entry below about the empty |
99 | 100 | entry at the beginning of the completion list before using this mode, |
100 | 101 | or using it will likely be very confusing. |
116 | 117 | called `icomplete-mode` that integrates with standard emacs completion |
117 | 118 | and adds some ido-like behavior. It is built in to emacs, so no |
118 | 119 | installation is necessary. Just load the file and enable the mode: |
120 | ||
119 | 121 | ```elisp |
120 | 122 | (require 'icomplete) |
121 | 123 | (icomplete-mode 1) |
122 | 124 | ``` |
125 | ||
123 | 126 | # Frequently asked questions # |
124 | 127 | |
125 | 128 | ## How does ido-ubiquitous-mode decide when to replace `completing-read`? <br/> Why don't some commands use ido completion? ## |
134 | 137 | call to `completing-read`. Furthermore, it's not always possible to |
135 | 138 | detect based on the arguments to `completing-read` whether such |
136 | 139 | ido-incompatible features are being used or not, so |
137 | ido-completing-read+ also comes with a blacklist of functions that are | |
138 | known not to work with ido. You can inspect this blacklist using | |
139 | ||
140 | `M-x describe-variable ido-cr+-function-blacklist` | |
140 | ido-completing-read+ also comes with a list of functions that are | |
141 | known not to work with ido. You can inspect this list using | |
142 | ||
143 | M-x describe-variable ido-cr+-disable-list | |
141 | 144 | |
142 | 145 | If you want to know why a certain command isn't getting ido |
143 | 146 | completion, you can enable `ido-cr+-debug-mode` and then run the |
193 | 196 | prompt appears, make a selection to complete the process. Then, |
194 | 197 | examine the Messages buffer, where ido-completing-read+ will explain |
195 | 198 | which mode of operation it selected and why. Based on this, you can |
196 | add an entry to `ido-cr+-function-blacklist`, or take some other | |
199 | add an entry to `ido-cr+-disable-list`, or take some other | |
197 | 200 | appropriate action. |
198 | 201 | |
199 | Updates to ido-completing-read+ may include new blacklist entries, but | |
200 | Emacs will not edit your override variables if you have already | |
202 | Updates to ido-completing-read+ may include new disable list entries, | |
203 | but Emacs will not edit your override variables if you have already | |
201 | 204 | customized them. So, if you have recently upgraded |
202 | ido-completing-read+, remember to invoke `ido-cr+-update-blacklist` to | |
203 | add in any new overrides. By default, ido-completing-read+ will remind | |
204 | you to do this whenever a new version adds to the blacklist. For more | |
205 | information, see: | |
206 | ||
207 | M-x describe-variable ido-cr+-auto-update-blacklist | |
205 | ido-completing-read+, remember to invoke `ido-cr+-update-disable-list` | |
206 | to add in any new overrides. By default, ido-completing-read+ will | |
207 | remind you to do this whenever a new version adds to the list. For | |
208 | more information, see: | |
209 | ||
210 | M-x describe-variable ido-cr+-auto-update-disable-list | |
208 | 211 | |
209 | 212 | ## Where can I report bugs? ## |
210 | 213 | |
211 | If you end up adding any blacklist entries, please report them at | |
214 | If you end up adding any disable list entries, please report them at | |
212 | 215 | https://github.com/DarwinAwardWinner/ido-ubiquitous/issues so I can |
213 | 216 | incorporate them into the defaults for future versions. You can also |
214 | 217 | report any bugs you find in ido-completing-read+. |
231 | 234 | |
232 | 235 | ## What is the "bleeding-edge" branch? ## |
233 | 236 | |
234 | All users should just use the master branch, or better yet, install | |
235 | from MELPA. The bleeding-edge branch is where I test experimental and | |
237 | All users should just use the main branch, or better yet, install from | |
238 | MELPA. The bleeding-edge branch is where I test experimental and | |
236 | 239 | unfinished features. Because ido-completing-read+ hooks deeply into |
237 | 240 | the bowels of Emacs, a bug in ido-completing-read+ could easily freeze |
238 | 241 | or crash Emacs entirely. Additionally, some bug only show up when |
239 | 242 | ido-completing-read+ is installed and compiled as a package. So I test |
240 | 243 | every new feature myself for some time on this branch before pushing |
241 | to the master branch. If you report a bug, I might develop a fix for | |
242 | it on the bleeding edge branch and ask then you to try this branch. | |
244 | to the main branch. If you report a bug, I might develop a fix for it | |
245 | on the bleeding edge branch and ask then you to try this branch. | |
243 | 246 | Otherwise, normal users don't need to think about this branch. |
244 | 247 | |
245 | 248 | ## Running the tests |
246 | 249 | |
247 | 250 | This package comes with a test suite. If you want to run it yourself, |
248 | first install the [cask](http://cask.readthedocs.io/en/latest/) | |
249 | dependency manager. Then, from the package directory, run `cask | |
250 | install` to install all the development dependencies, in | |
251 | particular | |
252 | [buttercup](https://github.com/jorgenschaefer/emacs-buttercup). | |
253 | Finally, to run the tests, execute `cask exec buttercup -L .`. Please | |
254 | run this test suite before submitting any pull requests, and note in | |
255 | the pull request whether any of the tests fail. | |
251 | first install the [Eldev](https://github.com/doublep/eldev), then use | |
252 | `eldev test` to run the tests. Please run this test suite before | |
253 | submitting any pull requests, and note in the pull request whether any | |
254 | of the tests fail. |
2 | 2 | ;; Copyright (C) 2011-2017 Ryan C. Thompson |
3 | 3 | |
4 | 4 | ;; Filename: ido-completing-read+.el |
5 | ;; Author: Ryan Thompson | |
5 | ;; Author: Ryan C. Thompson <rct@thompsonclan.org> | |
6 | 6 | ;; Created: Sat Apr 4 13:41:20 2015 (-0700) |
7 | ;; Version: 4.13 | |
8 | ;; Package-Requires: ((emacs "24.4") (cl-lib "0.5") (s "0.1") (memoize "1.1")) | |
7 | ;; Version: 4.14 | |
8 | ;; Package-Requires: ((emacs "24.4") (seq "0.5") (memoize "1.1")) | |
9 | 9 | ;; URL: https://github.com/DarwinAwardWinner/ido-completing-read-plus |
10 | 10 | ;; Keywords: ido, completion, convenience |
11 | 11 | |
47 | 47 | ;; this mode is enabled. Some other functions have ido disabled in |
48 | 48 | ;; them because their packages already provide support for ido via |
49 | 49 | ;; other means (for example, magit). See `M-x describe-variable |
50 | ;; ido-cr+-function-blacklist' for more information. | |
50 | ;; ido-cr+-disable-list' for more information. | |
51 | 51 | |
52 | 52 | ;; ido-completing-read+ version 4.0 is a major update. The formerly |
53 | 53 | ;; separate package ido-ubiquitous has been subsumed into |
76 | 76 | ;; |
77 | 77 | ;;; Code: |
78 | 78 | |
79 | (defconst ido-completing-read+-version "4.13" | |
79 | (defconst ido-completing-read+-version "4.14" | |
80 | 80 | "Currently running version of ido-completing-read+. |
81 | 81 | |
82 | 82 | Note that when you update ido-completing-read+, this variable may |
83 | 83 | not be updated until you restart Emacs.") |
84 | 84 | |
85 | (require 'nadvice) | |
85 | 86 | (require 'ido) |
87 | (require 'seq) | |
86 | 88 | (require 'minibuf-eldef) |
87 | 89 | (require 'cl-lib) |
88 | 90 | (require 'cus-edit) |
89 | (require 's) | |
90 | 91 | |
91 | 92 | ;; Optional dependency, only needed for optimization |
92 | 93 | (require 'memoize nil t) |
102 | 103 | "If non-nil, ido-cr+ will print debug info. |
103 | 104 | |
104 | 105 | Debug info is printed to the *Messages* buffer." |
105 | nil | |
106 | :init-value nil | |
106 | 107 | :global t |
107 | 108 | :group 'ido-completing-read-plus) |
108 | 109 | |
109 | 110 | (defsubst ido-cr+--debug-message (format-string &rest args) |
111 | "Emit a debug message for ido-cr+. | |
112 | ||
113 | This only has an effect when `ido-cr+-debug-mode' is non-nil. | |
114 | Arguments are identical to `message'." | |
110 | 115 | (when ido-cr+-debug-mode |
111 | 116 | (apply #'message (concat "ido-completing-read+: " format-string) args))) |
112 | 117 | |
116 | 121 | ;; silence byte-compiler warnings, despite already being declared in |
117 | 122 | ;; ido.el. |
118 | 123 | |
119 | (defmacro define-ido-internal-var (symbol &optional initvalue docstring) | |
120 | "Declare and initialize an ido internal variable. | |
124 | (defmacro ido-cr+-define-ido-internal-var (symbol &optional initvalue docstring) | |
125 | "Declare and initialize SYMBOL an ido internal variable. | |
121 | 126 | |
122 | 127 | This is used to suppress byte-compilation warnings about |
123 | 128 | reference to free variables when ido-cr+ attempts to access |
138 | 143 | should be, because ido always let-binds this variable before |
139 | 144 | using it, so the initial value shouldn't matter."))) |
140 | 145 | |
141 | (define-ido-internal-var ido-context-switch-command) | |
142 | (define-ido-internal-var ido-cur-list) | |
143 | (define-ido-internal-var ido-cur-item) | |
144 | (define-ido-internal-var ido-require-match) | |
145 | (define-ido-internal-var ido-process-ignore-lists) | |
146 | (ido-cr+-define-ido-internal-var ido-context-switch-command) | |
147 | (ido-cr+-define-ido-internal-var ido-cur-list) | |
148 | (ido-cr+-define-ido-internal-var ido-cur-item) | |
149 | (ido-cr+-define-ido-internal-var ido-require-match) | |
150 | (ido-cr+-define-ido-internal-var ido-process-ignore-lists) | |
146 | 151 | |
147 | 152 | ;; Vars and functions from flx-ido package |
148 | 153 | (defvar flx-ido-mode) |
153 | 158 | "Minibuffer depth of the most recent ido-cr+ activation. |
154 | 159 | |
155 | 160 | If this equals the current minibuffer depth, then the minibuffer |
156 | is currently being used by ido-cr+, and ido-cr+ feature will be | |
161 | is currently being used by ido-cr+, and ido-cr+ features will be | |
157 | 162 | active. Otherwise, something else is using the minibuffer and |
158 | 163 | ido-cr+ features will be deactivated to avoid interfering with |
159 | 164 | the other command. |
193 | 198 | "Idle timer for updating dynamic completion list.") |
194 | 199 | |
195 | 200 | (defvar ido-cr+-exhibit-pending nil |
196 | "This is non-nil after calling `ido-tidy' until the next call to `ido-exhibit'. | |
201 | "This is non-nil between calling `ido-tidy' and `ido-exhibit'. | |
197 | 202 | |
198 | 203 | Typically this is non-nil while any command is running and nil at all |
199 | 204 | other times, since those two functions are in `pre-command-hook' |
228 | 233 | Each element is a cons cell of (REMOVEP . TEXT), where REMOVEP is |
229 | 234 | the prefix argument to `ido-restrict-to-matches' and TEXT is the |
230 | 235 | pattern used to restrict.") |
236 | ||
237 | (defvar ido-cr+-need-bug27807-workaround | |
238 | (cl-letf* | |
239 | ((ido-exit ido-exit) | |
240 | ((symbol-function 'read-from-minibuffer) | |
241 | (lambda (_prompt &optional initial-contents &rest _remaining-args) | |
242 | (setq ido-exit 'takeprompt) ; Emulate pressing C-j in ido | |
243 | (if (consp initial-contents) | |
244 | (substring (car initial-contents) 0 (1- (cdr initial-contents))) | |
245 | initial-contents))) | |
246 | ;; Need to get the unadvised original of `ido-completing-read' | |
247 | ;; because the advice is autoloaded, so calling it while | |
248 | ;; loading the package will trigger a recursive load. | |
249 | ((symbol-function 'ido-completing-read) | |
250 | (advice--cd*r (symbol-function 'ido-completing-read))) | |
251 | (input-before-point | |
252 | (ido-completing-read "Pick: " '("aaa" "aab" "aac") nil nil '("aa" . 1)))) | |
253 | ;; If an initial position of 1 yields a 0-length string, then this | |
254 | ;; Emacs does not have the bug fix and requires the workaround. | |
255 | (= (length input-before-point) 0)) | |
256 | "If non-nil, enable the workaround for Emacs bug #27807. | |
257 | ||
258 | This variable is normally set when ido-cr+ is loaded, and should | |
259 | not need to be modified by users.") | |
231 | 260 | |
232 | 261 | (defgroup ido-completing-read-plus nil |
233 | 262 | "Extra features and compatibility for `ido-completing-read'." |
247 | 276 | ido-ubiquitous-completing-read)) |
248 | 277 | 'completing-read-default |
249 | 278 | completing-read-function) |
250 | "Alternate completing-read function to use when ido is not wanted. | |
279 | "Alternate `completing-read-function' to use when ido is not wanted. | |
251 | 280 | |
252 | 281 | This will be used for functions that are incompatible with ido |
253 | 282 | or if ido cannot handle the completion arguments. It will also be |
277 | 306 | widget))))) |
278 | 307 | :group 'ido-completing-read-plus) |
279 | 308 | |
280 | (defcustom ido-cr+-function-blacklist | |
309 | (define-obsolete-variable-alias | |
310 | 'ido-cr+-function-blacklist | |
311 | 'ido-cr+-disable-list | |
312 | "ido-completing-read+ 4.14") | |
313 | ||
314 | (defcustom ido-cr+-disable-list | |
281 | 315 | '(read-file-name-internal |
282 | 316 | read-buffer |
317 | internal-complete-buffer | |
283 | 318 | ;; https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues/60 |
284 | 319 | todo-add-category |
285 | 320 | ;; Gnus already supports ido on its own |
301 | 336 | ffap-read-file-or-url-internal |
302 | 337 | ;; https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues/161 |
303 | 338 | sly-read-symbol-name |
339 | org-olpath-completing-read | |
304 | 340 | ) |
305 | 341 | "Functions & commands for which ido-cr+ should be disabled. |
306 | 342 | |
309 | 345 | expression means to fall back for any function whose name matches |
310 | 346 | that regular expression. When ido-cr+ is called through |
311 | 347 | `completing-read', if any function in the call stack of the |
312 | current command matches any of the blacklist entries, ido-cr+ | |
348 | current command matches any of the disable list entries, ido-cr+ | |
313 | 349 | will be disabled for that command. Additionally, if the |
314 | collection in the call to `completing-read' matches any of the | |
315 | blacklist entries, ido-cr+ will be disabled. | |
350 | collection in the call to `completing-read' is a function name | |
351 | that matches any of the entries, ido-cr+ will be disabled. | |
316 | 352 | |
317 | 353 | Note that using specific function names is generally preferable |
318 | 354 | to regular expressions, because the associated function |
323 | 359 | :type '(repeat (choice (symbol :tag "Function or command name") |
324 | 360 | (string :tag "Regexp")))) |
325 | 361 | |
326 | (defcustom ido-cr+-function-whitelist | |
362 | (define-obsolete-variable-alias | |
363 | 'ido-cr+-function-whitelist | |
364 | 'ido-cr+-allow-list | |
365 | "ido-completing-read+ 4.14") | |
366 | ||
367 | (defcustom ido-cr+-allow-list | |
327 | 368 | nil |
328 | "Functions & commands for which ido-cr+ should be enabled. | |
329 | ||
330 | If this variable is nil, the whitelist will not be used, and | |
331 | ido-cr+ will be allowed in all functions/commands not listed in | |
332 | `ido-cr+-function-backlist'. | |
333 | ||
334 | If this variable is non-nil, ido-cr+'s whitelisting mode will be | |
369 | "If non-nil, limit ido-cr+ only to the specified commands & functions. | |
370 | ||
371 | If this variable is nil, the ido-cr+ will be enabled for all | |
372 | commands and functions not specified in all commands/functions | |
373 | not specified in `ido-cr+-function-backlist'. | |
374 | ||
375 | If this variable is non-nil, ido-cr+'s limited mode will be | |
335 | 376 | enabled, and ido-cr+ will be disabled for *all* functions unless |
336 | they match one of the entries. Matching is done in the same | |
337 | manner as `ido-cr+-function-blacklist', and blacklisting takes | |
338 | precedence over whitelisting." | |
377 | they match one of the entries in this variable. Matching is done | |
378 | in the same manner as `ido-cr+-disable-list', and the disable | |
379 | list also takes precedence over the allow list." | |
339 | 380 | :group 'ido-completing-read-plus |
340 | 381 | :type '(repeat (choice (symbol :tag "Function or command name") |
341 | 382 | (string :tag "Regexp")))) |
383 | ||
384 | (defvaralias 'ido-cr+-nil-def-wall-of-shame | |
385 | 'ido-cr+-nil-def-alternate-behavior-list | |
386 | "Functions and commands that use `completing-read' improperly. | |
387 | ||
388 | Many functions that call `completing-read' are written with the | |
389 | assumption that the setting the REQUIRE-MATCH argument of | |
390 | `completing-read' to t means it is required to return a match. | |
391 | While that would make logical sense, it's wrong. the docstring | |
392 | for `completing-read' describes the correct behavior. | |
393 | ||
394 | > If the input is null, ‘completing-read’ returns DEF, or the | |
395 | > first element of the list of default values, or an empty string | |
396 | > if DEF is nil, regardless of the value of REQUIRE-MATCH. | |
397 | ||
398 | This can be avoided by passing an element of COLLECTION as DEF | |
399 | instead of leaving it as nil.") | |
342 | 400 | |
343 | 401 | (defcustom ido-cr+-nil-def-alternate-behavior-list |
344 | 402 | '("\\`describe-\\(function\\|variable\\)\\'" |
362 | 420 | ) |
363 | 421 | "Functions & commands with alternate behavior when DEF is nil. |
364 | 422 | |
365 | This variable has the same format as | |
366 | `ido-cr+-function-blacklist'. When `ido-completing-read+` is | |
367 | called through `completing-read' by/with any command, function, | |
368 | or collection matched by entries in this list, it will behave | |
369 | differently when DEF is nil. Instead of using the empty string as | |
370 | the default value, it will use the first element of COLLECTION. | |
423 | This variable has the same format as `ido-cr+-disable-list'. When | |
424 | `ido-completing-read+` is called through `completing-read' | |
425 | by/with any command, function, or collection matched by entries | |
426 | in this list, it will behave differently when DEF is nil. Instead | |
427 | of using the empty string as the default value, it will use the | |
428 | first element of COLLECTION. | |
371 | 429 | |
372 | 430 | This is needed for optimal compatibility with commands written |
373 | under the assumption that REQUIRE-MATCH means that a match is | |
374 | required." | |
431 | under the reasonable but wrong assumption that REQUIRE-MATCH | |
432 | means that a match is required." | |
375 | 433 | :group 'ido-completing-read-plus |
376 | 434 | :type '(repeat (choice (symbol :tag "Function or command name") |
377 | 435 | (string :tag "Regexp")))) |
378 | ||
379 | (defvaralias 'ido-cr+-nil-def-wall-of-shame 'ido-cr+-nil-def-alternate-behavior-list | |
380 | "Functions and commands whose authors need to read the docstring for `completing-read'. | |
381 | ||
382 | Many functions that call `completing-read' are written with the | |
383 | assumption that the setting the REQUIRE-MATCH argument of | |
384 | `completing-read' to t means it is required to return a match. | |
385 | While that would make logical sense, it's wrong. the docstring | |
386 | for `completing-read' describes the correct behavior. | |
387 | ||
388 | > If the input is null, ‘completing-read’ returns DEF, or the | |
389 | > first element of the list of default values, or an empty string | |
390 | > if DEF is nil, regardless of the value of REQUIRE-MATCH. | |
391 | ||
392 | This can be avoided by passing an element of COLLECTION as DEF | |
393 | instead of leaving it as nil.") | |
394 | 436 | |
395 | 437 | ;;;###autoload |
396 | 438 | (defcustom ido-cr+-replace-completely nil |
406 | 448 | (define-error 'ido-cr+-fallback "ido-cr+-fallback") |
407 | 449 | |
408 | 450 | (defsubst ido-cr+--explain-fallback (arg) |
409 | ;; This function accepts a string, or an ido-cr+-fallback | |
410 | ;; signal. | |
451 | "Emit a debug message explaining the reason for falling back. | |
452 | ||
453 | ARG can be a string or an ido-cr+-fallback signal. In the latter | |
454 | case, the DATA part of the signal is used as the message." | |
411 | 455 | (when ido-cr+-debug-mode |
412 | 456 | (when (and (listp arg) |
413 | 457 | (eq (car arg) 'ido-cr+-fallback)) |
414 | 458 | (setq arg (cadr arg))) |
415 | (ido-cr+--debug-message "Falling back to `%s' because %s." | |
416 | ido-cr+-fallback-function arg))) | |
459 | (ido-cr+--debug-message | |
460 | "Falling back to `%s' because %s." | |
461 | (if (symbolp ido-cr+-fallback-function) | |
462 | ido-cr+-fallback-function | |
463 | "ido-cr+-fallback-function") | |
464 | arg))) | |
417 | 465 | |
418 | 466 | ;;;###autoload |
419 | 467 | (defsubst ido-cr+-active () |
420 | "Returns non-nil if ido-cr+ is currently using the minibuffer." | |
468 | "Return non-nil if ido-cr+ is currently using the minibuffer." | |
421 | 469 | (>= ido-cr+-minibuffer-depth (minibuffer-depth))) |
422 | 470 | |
423 | 471 | (defun ido-cr+--called-from-completing-read () |
424 | "Returns non-nil if the most recent call to ido-cr+ was from `completing-read'." | |
472 | "Return non-nil if the most recent call to ido-cr+ was from `completing-read'." | |
425 | 473 | (equal (cadr (backtrace-frame 1 'ido-completing-read+)) |
426 | 474 | 'completing-read)) |
427 | 475 | |
428 | 476 | (defmacro ido-cr+-function-is-in-list (fun fun-list &optional list-name) |
429 | 477 | "Return non-nil if FUN matches an entry in FUN-LIST. |
430 | 478 | |
431 | This is used to check for matches to `ido-cr+-function-blacklist' | |
432 | and `ido-cr+-function-whitelist'. Read those docstrings to see | |
433 | how the matching is done. | |
479 | This is used to check for matches to `ido-cr+-disable-list' and | |
480 | `ido-cr+-allow-list'. Read those docstrings to see how | |
481 | the matching is done. | |
434 | 482 | |
435 | 483 | This is declared as macro only in order to extract the variable |
436 | 484 | name used for the second argument so it can be used in a debug |
437 | message. It should be called as if it were a normal function." | |
485 | message. It should be called as if it were a normal function. The | |
486 | optional 3rd argument LIST-NAME can be used to provide this | |
487 | information manually if it is known." | |
438 | 488 | (when (null list-name) |
439 | 489 | (if (symbolp fun-list) |
440 | 490 | (setq list-name (symbol-name fun-list)) |
460 | 510 | ((stringp entry) |
461 | 511 | (and (symbolp ,fun) |
462 | 512 | (string-match-p entry (symbol-name ,fun)))) |
463 | ;; Anything else: invalid blacklist entry | |
513 | ;; Anything else: invalid list entry | |
464 | 514 | (t |
465 | 515 | (ido-cr+--debug-message "Ignoring invalid entry in %s: `%S'" ,list-name entry) |
466 | 516 | nil)) |
467 | 517 | return entry |
468 | ;; If no blacklist entry matches, return nil | |
518 | ;; If no list entry matches, return nil | |
469 | 519 | finally return nil)) |
470 | 520 | |
471 | (defun ido-cr+-function-is-blacklisted (fun) | |
472 | "Return non-nil if FUN is blacklisted. | |
473 | ||
474 | See `ido-cr+-function-blacklist'." | |
475 | (ido-cr+-function-is-in-list fun ido-cr+-function-blacklist)) | |
476 | ||
477 | (defun ido-cr+-function-is-whitelisted (fun) | |
478 | "Return non-nil if FUN is whitelisted. | |
479 | ||
480 | See `ido-cr+-function-whitelist'." | |
481 | (or (null ido-cr+-function-whitelist) | |
482 | (ido-cr+-function-is-in-list fun ido-cr+-function-whitelist))) | |
521 | (define-obsolete-function-alias | |
522 | 'ido-cr+-function-is-blacklisted | |
523 | 'ido-cr+-disabled-in-function-p | |
524 | "ido-completing-read+ 4.14") | |
525 | ||
526 | (defsubst ido-cr+-disabled-in-function-p (fun) | |
527 | "Return non-nil if ido-cr+ is disabled for FUN. | |
528 | ||
529 | See `ido-cr+-disable-list'." | |
530 | (ido-cr+-function-is-in-list fun ido-cr+-disable-list)) | |
531 | ||
532 | (define-obsolete-function-alias | |
533 | 'ido-cr+-function-is-whitelisted | |
534 | 'ido-cr+-allowed-in-function-p | |
535 | "ido-completing-read+ 4.14") | |
536 | ||
537 | (defsubst ido-cr+-allowed-in-function-p (fun) | |
538 | "Return non-nil if ido-cr+ is allowed for FUN. | |
539 | ||
540 | See `ido-cr+-allow-list'." | |
541 | (or (null ido-cr+-allow-list) | |
542 | (ido-cr+-function-is-in-list fun ido-cr+-allow-list))) | |
483 | 543 | |
484 | 544 | ;;;###autoload |
485 | 545 | (defun ido-completing-read+ (prompt collection &optional predicate |
486 | 546 | require-match initial-input |
487 | 547 | hist def inherit-input-method) |
488 | "ido-based method for reading from the minibuffer with completion. | |
548 | "Ido-based method for reading from the minibuffer with completion. | |
489 | 549 | |
490 | 550 | See `completing-read' for the meaning of the arguments. |
491 | 551 | |
492 | 552 | This function is a wrapper for `ido-completing-read' designed to |
493 | 553 | be used as the value of `completing-read-function'. Importantly, |
494 | 554 | it detects edge cases that ido cannot handle and uses normal |
495 | completion for them." | |
555 | completion for them. | |
556 | ||
557 | See `completing-read' for the meaning of the arguments." | |
496 | 558 | (let* (;; Save the original arguments in case we need to do the |
497 | 559 | ;; fallback |
498 | 560 | (ido-cr+-orig-completing-read-args |
533 | 595 | (if (and ido-cr+-dynamic-collection (featurep 'memoize)) |
534 | 596 | (memoize (indirect-function 'all-completions)) |
535 | 597 | 'all-completions)) |
536 | ;; If the whitelist is empty, everything is whitelisted | |
537 | (whitelisted (not ido-cr+-function-whitelist)) | |
598 | ;; If the allow list is empty, everything is allowed | |
599 | (ido-cr+-allowed (not ido-cr+-allow-list)) | |
538 | 600 | ;; If non-nil, we need alternate nil DEF handling |
539 | 601 | (alt-nil-def nil)) |
540 | 602 | (condition-case sig |
544 | 606 | (signal 'ido-cr+-fallback |
545 | 607 | '("ido cannot handle alternate input methods"))) |
546 | 608 | |
547 | ;; Check for black/white-listed collection function | |
609 | ;; Check for allow/disable-listed collection function | |
548 | 610 | (when (functionp collection) |
549 | ;; Blacklist | |
550 | (when (ido-cr+-function-is-blacklisted collection) | |
611 | ;; Disable list | |
612 | (when (ido-cr+-disabled-in-function-p collection) | |
551 | 613 | (if (symbolp collection) |
552 | 614 | (signal 'ido-cr+-fallback |
553 | (list (format "collection function `%S' is blacklisted" collection))) | |
615 | (list (format "collection function `%S' is disabled" collection))) | |
554 | 616 | (signal 'ido-cr+-fallback |
555 | (list "collection function is blacklisted")))) | |
556 | ;; Whitelist | |
557 | (when (and (not whitelisted) | |
558 | (ido-cr+-function-is-whitelisted collection)) | |
617 | (list "collection function is disabled")))) | |
618 | ;; Allow list | |
619 | (when (and (not ido-cr+-allowed) | |
620 | (ido-cr+-allowed-in-function-p collection)) | |
559 | 621 | (ido-cr+--debug-message |
560 | 622 | (if (symbolp collection) |
561 | (format "Collection function `%S' is whitelisted" collection) | |
562 | "Collection function is whitelisted")) | |
563 | (setq whitelisted t)) | |
623 | (format "Collection function `%S' is allowed" collection) | |
624 | "Collection function is allowed")) | |
625 | (setq ido-cr+-allowed t)) | |
564 | 626 | ;; nil DEF list |
565 | 627 | (when (and |
566 | 628 | require-match (null def) |
593 | 655 | ido-cr+-max-items)))) |
594 | 656 | |
595 | 657 | ;; If called from `completing-read', check for |
596 | ;; black/white-listed commands/callers | |
658 | ;; disabled/allowed commands/callers | |
597 | 659 | (when (ido-cr+--called-from-completing-read) |
598 | 660 | ;; Check calling command and `ido-cr+-current-command' |
599 | 661 | (cl-loop |
600 | 662 | for cmd in (list this-command ido-cr+-current-command) |
601 | 663 | |
602 | if (ido-cr+-function-is-blacklisted cmd) | |
664 | if (ido-cr+-disabled-in-function-p cmd) | |
603 | 665 | do (signal 'ido-cr+-fallback |
604 | (list "calling command `%S' is blacklisted" cmd)) | |
605 | ||
606 | if (and (not whitelisted) | |
607 | (ido-cr+-function-is-whitelisted cmd)) | |
666 | (list "calling command `%S' is disabled" cmd)) | |
667 | ||
668 | if (and (not ido-cr+-allowed) | |
669 | (ido-cr+-allowed-in-function-p cmd)) | |
608 | 670 | do (progn |
609 | (ido-cr+--debug-message "Command `%S' is whitelisted" cmd) | |
610 | (setq whitelisted t)) | |
671 | (ido-cr+--debug-message "Command `%S' is allowed" cmd) | |
672 | (setq ido-cr+-allowed t)) | |
611 | 673 | |
612 | 674 | if (and |
613 | 675 | require-match (null def) (not alt-nil-def) |
632 | 694 | '(internal--funcall-interactively |
633 | 695 | (indirect-function 'call-interactively)))) |
634 | 696 | |
635 | if (ido-cr+-function-is-blacklisted caller) | |
697 | if (ido-cr+-disabled-in-function-p caller) | |
636 | 698 | do (signal 'ido-cr+-fallback |
637 | 699 | (list (if (symbolp caller) |
638 | (format "calling function `%S' is blacklisted" caller) | |
639 | "a calling function is blacklisted"))) | |
640 | ||
641 | if (and (not whitelisted) | |
642 | (ido-cr+-function-is-whitelisted caller)) | |
700 | (format "calling function `%S' is disabled" caller) | |
701 | "a calling function is disabled"))) | |
702 | ||
703 | if (and (not ido-cr+-allowed) | |
704 | (ido-cr+-allowed-in-function-p caller)) | |
643 | 705 | do (progn |
644 | 706 | (ido-cr+--debug-message |
645 | 707 | (if (symbolp caller) |
646 | (format "Calling function `%S' is whitelisted" caller) | |
647 | "A calling function is whitelisted")) | |
648 | (setq whitelisted t)) | |
708 | (format "Calling function `%S' is allowed" caller) | |
709 | "A calling function is allowed")) | |
710 | (setq ido-cr+-allowed t)) | |
649 | 711 | |
650 | 712 | if (and require-match (null def) (not alt-nil-def) |
651 | 713 | (ido-cr+-function-is-in-list |
657 | 719 | "Using alternate nil DEF handling for a calling function")) |
658 | 720 | (setq alt-nil-def t)))) |
659 | 721 | |
660 | (unless whitelisted | |
722 | (unless ido-cr+-allowed | |
661 | 723 | (signal 'ido-cr+-fallback |
662 | (list "no functions or commands matched the whitelist for this call"))) | |
724 | (list "no functions or commands matched the allow list for this call"))) | |
663 | 725 | |
664 | 726 | (when (and require-match (null def)) |
665 | 727 | ;; Replace nil with "" for DEF if match is required, unless |
695 | 757 | '("ido cannot handle the empty string as an option when `ido-enable-dot-prefix' is non-nil; see https://debbugs.gnu.org/cgi/bugreport.cgi?bug=26997"))) |
696 | 758 | |
697 | 759 | ;; Fix ido's broken handling of cons-style INITIAL-INPUT on |
698 | ;; Emacsen older than 27.1. | |
760 | ;; Emacsen older than 27. See Emacs bug #27807. | |
699 | 761 | (when (and (consp initial-input) |
700 | (version< emacs-version "27.1")) | |
762 | ido-cr+-need-bug27807-workaround) | |
701 | 763 | ;; `completing-read' uses 0-based index while |
702 | 764 | ;; `read-from-minibuffer' uses 1-based index. |
703 | 765 | (cl-incf (cdr initial-input))) |
812 | 874 | #'ido-select-text@ido-cr+-fix-require-match) |
813 | 875 | |
814 | 876 | (defun ido-tidy@ido-cr+-set-exhibit-pending (&rest _args) |
877 | "Advice to manage the value of `ido-cr+-exhibit-pending'." | |
815 | 878 | (setq ido-cr+-exhibit-pending t)) |
816 | 879 | (advice-add 'ido-tidy :after 'ido-tidy@ido-cr+-set-exhibit-pending) |
817 | 880 | |
818 | 881 | (defun ido-exhibit@ido-cr+-clear-exhibit-pending (&rest _args) |
882 | "Advice to manage the value of `ido-cr+-exhibit-pending'." | |
819 | 883 | (setq ido-cr+-exhibit-pending nil)) |
820 | 884 | (advice-add 'ido-exhibit :before 'ido-exhibit@ido-cr+-clear-exhibit-pending) |
821 | 885 | |
842 | 906 | for i from 0 upto (length string) |
843 | 907 | append (funcall |
844 | 908 | ido-cr+-all-completions-memoized |
845 | (s-left i string) | |
909 | (substring string 0 i) | |
846 | 910 | collection |
847 | 911 | predicate) |
848 | 912 | into completion-list |
887 | 951 | filtered-collection))) |
888 | 952 | |
889 | 953 | (defun ido-cr+-cyclicp (x) |
890 | "Returns non-nill if X is a list containing a circular reference." | |
954 | "Return non-nill if X is a list containing a circular reference." | |
891 | 955 | (cl-loop |
892 | 956 | for tortoise on x |
893 | 957 | for hare on (cdr x) by #'cddr |
907 | 971 | ;; If current `ido-text' is equal to or a prefix of the previous |
908 | 972 | ;; one, a dynamic update is not needed. |
909 | 973 | (when (or (null ido-cr+-last-dynamic-update-text) |
910 | (not (s-prefix? ido-text ido-cr+-last-dynamic-update-text))) | |
974 | (not (string-prefix-p ido-text ido-cr+-last-dynamic-update-text))) | |
911 | 975 | (ido-cr+--debug-message "Doing a dynamic update because `ido-text' changed from %S to %S" |
912 | 976 | ido-cr+-last-dynamic-update-text ido-text) |
913 | 977 | (setq ido-cr+-last-dynamic-update-text ido-text) |
922 | 986 | ;; If `ido-text' is a prefix of `first-match', then we |
923 | 987 | ;; only need to check `first-match' |
924 | 988 | ((and first-match |
925 | (s-prefix? ido-text first-match)) | |
989 | (string-prefix-p ido-text first-match)) | |
926 | 990 | (list first-match)) |
927 | 991 | ;; Otherwise we need to check both |
928 | 992 | (t |
1002 | 1066 | #'ido-cr+-update-dynamic-collection))))) |
1003 | 1067 | |
1004 | 1068 | (defun ido-cr+-minibuffer-setup () |
1005 | "set up minibuffer `post-command-hook' for ido-cr+ " | |
1069 | "Set up minibuffer `post-command-hook' for ido-cr+." | |
1006 | 1070 | (when (ido-cr+-active) |
1007 | 1071 | (add-hook 'post-command-hook |
1008 | 1072 | 'ido-cr+-schedule-dynamic-collection-update))) |
1034 | 1098 | ;; dynamically-added completions are also properly restricted. |
1035 | 1099 | (defun ido-restrict-to-matches@ido-cr+-record-restriction |
1036 | 1100 | (&optional removep) |
1037 | "Record the restriction criterion for ido-cr+" | |
1101 | "Record the restriction criterion for ido-cr+." | |
1038 | 1102 | (ido-cr+--debug-message "Appending restriction %S to `ido-cr+-active-restrictions'" |
1039 | 1103 | (cons removep ido-text)) |
1040 | 1104 | (add-to-list 'ido-cr+-active-restrictions (cons removep ido-text) t)) |
1045 | 1109 | ;; default when the input is empty and the empty string is the |
1046 | 1110 | ;; selected choice |
1047 | 1111 | (defun minibuf-eldef-update-minibuffer@ido-cr+-compat (orig-fun &rest args) |
1048 | "This advice allows minibuffer-electric-default-mode to work with ido-cr+." | |
1112 | "This advice allows `minibuffer-electric-default-mode' to work with ido-cr+." | |
1049 | 1113 | (if (ido-cr+-active) |
1050 | 1114 | (unless (eq minibuf-eldef-showing-default-in-prompt |
1051 | 1115 | (and (string= (car ido-cur-list) "") |
1065 | 1129 | |
1066 | 1130 | If this mode causes problems for a function, you can customize |
1067 | 1131 | when ido completion is or is not used by customizing |
1068 | `ido-cr+-function-blacklist'." | |
1069 | nil | |
1132 | `ido-cr+-disable-list'." | |
1133 | :init-value nil | |
1070 | 1134 | :global t |
1071 | 1135 | :group 'ido-completing-read-plus |
1072 | 1136 | ;; Actually enable/disable the mode by setting |
1076 | 1140 | #'ido-completing-read+ |
1077 | 1141 | ido-cr+-fallback-function))) |
1078 | 1142 | |
1079 | (defcustom ido-cr+-auto-update-blacklist 'notify | |
1143 | (defcustom ido-cr+-auto-update-disable-list 'notify | |
1080 | 1144 | "Whether to add new overrides when updating ido-cr+. |
1081 | 1145 | |
1082 | 1146 | This variable has 3 possible values, with the following meanings: |
1083 | 1147 | |
1084 | `t': Auto-update the blacklist | |
1148 | t: Auto-update the disable list | |
1085 | 1149 | `notify': Notify you about updates but do not apply them |
1086 | `nil': Ignore all blacklist updates | |
1087 | ||
1088 | Ido-cr+ comes with a default blacklist for commands that are | |
1089 | known to be incompatible with ido completion. New versions of | |
1090 | ido-cr+ may come with updates to this blacklist as more | |
1091 | incompatible commands are discovered. However, customizing your | |
1092 | own overrides would normally prevent you from receiving these | |
1093 | updates, since Emacs will not overwrite your customizations. | |
1094 | ||
1095 | To resolve this problem, you can set this variable to `t', and | |
1096 | then ido-cr+ can automatically add any new built-in overrides | |
1097 | whenever it is updated. (Actually, the update will happen the | |
1098 | next time Emacs is restarted after the update.) This allows you | |
1099 | to add your own overrides but still receive updates to the | |
1100 | default set. | |
1101 | ||
1102 | If you want ido-cr+ to just notify you about new default | |
1103 | overrides instead of adding them itself, set this variable to | |
1104 | `notify'. If you don't want this auto-update behavior at all, set | |
1105 | it to `nil'. | |
1106 | ||
1107 | (Note that having this option enabled effectively prevents you | |
1108 | from removing any of the built-in default blacklist entries, | |
1109 | since they will simply be re-added the next time Emacs starts.)" | |
1150 | nil: Ignore all disable list updates | |
1151 | ||
1152 | Ido-cr+ comes with a default list of commands that are known to | |
1153 | be incompatible with ido completion. New versions of ido-cr+ may | |
1154 | come with updates to this \"disable list\" as more incompatible | |
1155 | commands are discovered. However, customizing your own overrides | |
1156 | would normally prevent you from receiving these updates, since | |
1157 | Emacs will not overwrite your customizations. | |
1158 | ||
1159 | To resolve this problem, you can set this variable to t, and then | |
1160 | ido-cr+ can automatically add any new built-in overrides whenever | |
1161 | it is updated. (Actually, the update will happen the next time | |
1162 | Emacs is restarted after the update.) This allows you to add your | |
1163 | own overrides but still receive updates to the default set. | |
1164 | ||
1165 | If you want ido-cr+ to just notify you about new defaults instead | |
1166 | of adding them itself, set this variable to `notify'. If you | |
1167 | don't want this auto-update behavior at all, set it to nil. | |
1168 | ||
1169 | \(Note that having this option enabled effectively prevents you | |
1170 | from removing any of the built-in default entries, since they | |
1171 | will simply be re-added the next time Emacs starts.)" | |
1110 | 1172 | :type '(choice :tag "When new overrides are available:" |
1111 | 1173 | (const :menu-tag "Auto-add" |
1112 | 1174 | :tag "Add them automatically" |
1119 | 1181 | nil)) |
1120 | 1182 | :group 'ido-completing-read-plus) |
1121 | 1183 | |
1122 | (defun ido-cr+-update-blacklist (&optional save quiet) | |
1123 | "Re-add any missing default blacklist entries. | |
1184 | (define-obsolete-function-alias | |
1185 | 'ido-cr+-update-blacklist | |
1186 | 'ido-cr+-update-disable-list | |
1187 | "ido-completing-read+ 4.14") | |
1188 | ||
1189 | (defun ido-cr+-update-disable-list (&optional save quiet) | |
1190 | "Re-add any missing default entries to `ido-cr+-disable-list'. | |
1124 | 1191 | |
1125 | 1192 | This is useful after an update of ido-ubiquitous that adds new |
1126 | default overrides. See `ido-cr+-auto-update-blacklist' for more | |
1127 | information. | |
1128 | ||
1129 | If SAVE is non-nil, also save the new blacklist to the user's | |
1193 | default overrides. See `ido-cr+-auto-update-disable-list' for | |
1194 | more information. | |
1195 | ||
1196 | If SAVE is non-nil, also save the new disable list to the user's | |
1130 | 1197 | Custom file (but only if it was already customized beforehand). |
1131 | 1198 | When called interactively, a prefix argument triggers a save. |
1132 | 1199 | |
1200 | Unless QUIET is non-nil, this function produces messages indicating | |
1201 | all changes that were made. | |
1202 | ||
1133 | 1203 | When called from Lisp code, this function returns non-nil if the |
1134 | blacklist was modified." | |
1204 | disable list was modified." | |
1135 | 1205 | (interactive "P") |
1136 | (let* ((var-state (custom-variable-state 'ido-cr+-function-blacklist | |
1137 | ido-cr+-function-blacklist)) | |
1138 | (curval ido-cr+-function-blacklist) | |
1139 | (defval (eval (car (get 'ido-cr+-function-blacklist 'standard-value)))) | |
1206 | (let* ((var-state (custom-variable-state 'ido-cr+-disable-list | |
1207 | ido-cr+-disable-list)) | |
1208 | (curval ido-cr+-disable-list) | |
1209 | (defval (eval (car (get 'ido-cr+-disable-list 'standard-value)))) | |
1140 | 1210 | (newval (delete-dups (append defval curval))) |
1141 | 1211 | (new-entries (cl-set-difference defval curval :test #'equal)) |
1142 | 1212 | (modified nil) |
1145 | 1215 | (cl-case var-state |
1146 | 1216 | (standard |
1147 | 1217 | ;; Var is not customized, just set the new default |
1148 | (ido-cr+--debug-message "Blacklist was not customized, so it has been updated to the new default value.") | |
1149 | (setq ido-cr+-function-blacklist defval | |
1218 | (ido-cr+--debug-message "Disable list was not customized, so it has been updated to the new default value.") | |
1219 | (setq ido-cr+-disable-list defval | |
1150 | 1220 | modified new-entries)) |
1151 | 1221 | ((saved set changed) |
1152 | 1222 | ;; Var has been customized and saved by the user, so set the |
1153 | 1223 | ;; new value and maybe save it |
1154 | (ido-cr+--debug-message "Updating user-customized blacklist with new default entries.") | |
1155 | (setq ido-cr+-function-blacklist newval | |
1224 | (ido-cr+--debug-message "Updating user-customized disable list with new default entries.") | |
1225 | (setq ido-cr+-disable-list newval | |
1156 | 1226 | modified t) |
1157 | 1227 | (when (and save (eq var-state 'saved)) |
1158 | (ido-cr+--debug-message "Saving new blacklist value to Custom file.") | |
1159 | (customize-save-variable 'ido-cr+-function-blacklist ido-cr+-function-blacklist) | |
1228 | (ido-cr+--debug-message "Saving new disable list value to Custom file.") | |
1229 | (customize-save-variable 'ido-cr+-disable-list ido-cr+-disable-list) | |
1160 | 1230 | (setq saved t))) |
1161 | 1231 | (otherwise |
1162 | (ido-cr+--debug-message "Customization status of blacklist is unknown. Not modifying it."))) | |
1232 | (ido-cr+--debug-message "Customization status of disable list is unknown. Not modifying it."))) | |
1163 | 1233 | (if (and modified (not quiet)) |
1164 | 1234 | (progn |
1165 | (push (format "Added the following entries to `ido-cr+-function-blacklist': %S" new-entries) | |
1235 | (push (format "Added the following entries to `ido-cr+-disable-list': %S" new-entries) | |
1166 | 1236 | message-lines) |
1167 | 1237 | (if saved |
1168 | (push "Saved the new value of `ido-cr+-function-blacklist' to your Custom file." | |
1238 | (push "Saved the new value of `ido-cr+-disable-list' to your Custom file." | |
1169 | 1239 | message-lines) |
1170 | (push "However, the new value of `ido-cr+-function-blacklist' has not yet been saved for future sessions. To save it. re-run this command with a prefix argument: `C-u M-x ido-cr+-update-blacklist'; or else manually inspect and save the value using `M-x customize-variable ido-cr+-function-blacklist'." | |
1240 | (push "However, the new value of `ido-cr+-disable-list' has not yet been saved for future sessions. To save it. re-run this command with a prefix argument: `C-u M-x ido-cr+-update-disable-list'; or else manually inspect and save the value using `M-x customize-variable ido-cr+-disable-list'." | |
1171 | 1241 | message-lines))) |
1172 | (push "No updates were required to `ido-cr+-function-blacklist'." message-lines)) | |
1242 | (push "No updates were required to `ido-cr+-disable-list'." message-lines)) | |
1173 | 1243 | (unless quiet |
1174 | 1244 | (message (mapconcat #'identity (nreverse message-lines) "\n"))) |
1175 | 1245 | modified)) |
1176 | 1246 | |
1177 | (defun ido-cr+-maybe-update-blacklist () | |
1178 | "Maybe call `ico-cr+-update-blacklist. | |
1179 | ||
1180 | See `ido-cr+-auto-update-blacklist' for more information." | |
1181 | (if ido-cr+-auto-update-blacklist | |
1182 | (let* ((curval ido-cr+-function-blacklist) | |
1183 | (defval (eval (car (get 'ido-cr+-function-blacklist 'standard-value)))) | |
1247 | (define-obsolete-function-alias | |
1248 | 'ido-cr+-maybe-update-blacklist | |
1249 | 'ido-cr+-maybe-update-disable-list | |
1250 | "ido-completing-read+ 4.14") | |
1251 | ||
1252 | (defun ido-cr+-maybe-update-disable-list () | |
1253 | "Maybe call `ico-cr+-update-disable-list. | |
1254 | ||
1255 | See `ido-cr+-auto-update-disable-list' for more information." | |
1256 | (if ido-cr+-auto-update-disable-list | |
1257 | (let* ((curval ido-cr+-disable-list) | |
1258 | (defval (eval (car (get 'ido-cr+-disable-list 'standard-value)))) | |
1184 | 1259 | (new-entries (cl-set-difference defval curval :test #'equal))) |
1185 | 1260 | (if new-entries |
1186 | (if (eq ido-cr+-auto-update-blacklist 'notify) | |
1187 | (display-warning 'ido-completing-read+ (format "There are %s new blacklist entries available. Use `M-x ido-cr+-update-blacklist' to install them. (See `ido-cr+-auto-update-blacklist' for more information.)" (length new-entries))) | |
1188 | (ido-cr+--debug-message "Initiating blacklist update.") | |
1189 | (ido-cr+-update-blacklist t)) | |
1190 | (ido-cr+--debug-message "No blacklist updates available."))) | |
1191 | (ido-cr+--debug-message "Skipping blacklist update by user request."))) | |
1192 | ||
1193 | (ido-cr+-maybe-update-blacklist) | |
1261 | (if (eq ido-cr+-auto-update-disable-list 'notify) | |
1262 | (display-warning 'ido-completing-read+ (format "There are %s new disable list entries available. Use `M-x ido-cr+-update-disable-list' to install them. (See `ido-cr+-auto-update-disable-list' for more information.)" (length new-entries))) | |
1263 | (ido-cr+--debug-message "Initiating disable list update.") | |
1264 | (ido-cr+-update-disable-list t)) | |
1265 | (ido-cr+--debug-message "No disable list updates available."))) | |
1266 | (ido-cr+--debug-message "Skipping disable list update by user request."))) | |
1267 | ||
1268 | (ido-cr+-maybe-update-disable-list) | |
1194 | 1269 | |
1195 | 1270 | (provide 'ido-completing-read+) |
1196 | 1271 |
0 | ;;; ido-ubiquitous.el --- Use ido (nearly) everywhere. -*- lexical-binding: t -*- | |
1 | ||
2 | ;; Copyright (C) 2011-2017 Ryan C. Thompson | |
3 | ||
4 | ;; Author: Ryan C. Thompson | |
5 | ;; URL: https://github.com/DarwinAwardWinner/ido-ubiquitous | |
6 | ;; Version: 4.13 | |
7 | ;; Created: 2011-09-01 | |
8 | ;; Keywords: convenience, completion, ido | |
9 | ;; EmacsWiki: InteractivelyDoThings | |
10 | ;; Package-Requires: ((ido-completing-read+ "4.13") (cl-lib "0.5")) | |
11 | ;; Filename: ido-ubiquitous.el | |
12 | ||
13 | ;; This file is NOT part of GNU Emacs. | |
14 | ||
15 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
16 | ;; | |
17 | ;;; Commentary: | |
18 | ||
19 | ;; Previously a separate package, ido-ubiquitous has now been subsumed | |
20 | ;; into ido-completing-read+. You should update your config to install that instead. | |
21 | ||
22 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
23 | ;; | |
24 | ;; This program is free software: you can redistribute it and/or modify | |
25 | ;; it under the terms of the GNU General Public License as published by | |
26 | ;; the Free Software Foundation, either version 3 of the License, or (at | |
27 | ;; your option) any later version. | |
28 | ;; | |
29 | ;; This program is distributed in the hope that it will be useful, but | |
30 | ;; WITHOUT ANY WARRANTY; without even the implied warranty of | |
31 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
32 | ;; General Public License for more details. | |
33 | ;; | |
34 | ;; You should have received a copy of the GNU General Public License | |
35 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |
36 | ;; | |
37 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
38 | ;; | |
39 | ;;; Code: | |
40 | ||
41 | (defconst ido-ubiquitous-version "4.13" | |
42 | "Currently running version of ido-ubiquitous. | |
43 | ||
44 | Note that when you update ido-ubiquitous, this variable may not | |
45 | be updated until you restart Emacs.") | |
46 | ||
47 | (require 'ido-completing-read+) | |
48 | ||
49 | (display-warning 'ido-ubiquitous "The ido-ubiquitous package is now redundant. All functionality, including ido-ubiquitous-mode, has been merged into the ido-completing-read+ package. You should replace ido-ubiquitous with ido-completing-read+ in your Emacs config. For more information, see: | |
50 | https://github.com/DarwinAwardWinner/ido-ubiquitous#version-40-changes") | |
51 | ||
52 | (define-obsolete-function-alias 'completing-read-ido-ubiquitous 'ido-completing-read+ | |
53 | "ido-completing-read+ 4.0") | |
54 | (define-obsolete-function-alias 'ido-ubiquitous-update-overrides 'ido-cr+-update-blacklist | |
55 | "ido-completing-read+ 4.0") | |
56 | (define-obsolete-function-alias 'ido-ubiquitous--maybe-update-overrides 'ido-cr+-maybe-update-blacklist | |
57 | "ido-completing-read+ 4.0") | |
58 | (define-obsolete-variable-alias 'ido-ubiquitous-auto-update-overrides 'ido-cr+-auto-update-blacklist | |
59 | "ido-completing-read+ 4.0") | |
60 | ||
61 | (make-obsolete-variable | |
62 | 'ido-ubiquitous-default-state | |
63 | "For the new variables to control which commands have ido completion, see `ido-cr+-function-blacklist' and `ido-cr+-function-whitelist'. For information on what happened to \"old-style\" default selection, See the FAQ." | |
64 | "ido-completing-read+ 4.0") | |
65 | (make-obsolete-variable | |
66 | 'ido-ubiquitous-command-overrides | |
67 | "For the new variables to control which commands have ido completion, see `ido-cr+-function-blacklist' and `ido-cr+-function-whitelist'. For information on what happened to \"old-style\" default selection, See the FAQ." | |
68 | "ido-completing-read+ 4.0") | |
69 | (make-obsolete-variable | |
70 | 'ido-ubiquitous-function-overrides | |
71 | "For the new variables to control which commands have ido completion, see `ido-cr+-function-blacklist' and `ido-cr+-function-whitelist'. For information on what happened to \"old-style\" default selection, See the FAQ." | |
72 | "ido-completing-read+ 4.0") | |
73 | (make-obsolete-variable | |
74 | 'ido-ubiquitous-allow-on-functional-collection | |
75 | "Ido-cr+ now works with most dynamic completion tables (i.e. \"functional collections\"), so this variable is no longer necessary. If a specific command uses a dynamic completion table that conflicts with ido-cr+, add it to `ido-cr+-function-blacklist' instead." | |
76 | "ido-completing-read+ 4.0") | |
77 | ||
78 | (provide 'ido-ubiquitous) | |
79 | ||
80 | ;; Local Variables: | |
81 | ;; indent-tabs-mode: nil | |
82 | ;; End: | |
83 | ;;; ido-ubiquitous.el ends here |
6 | 6 | -e "s/((?:defconst|defvar|setq).*-version\s+)\"[0-9.]+\"/\${1}\"$TARGET_VERSION\"/g;" \ |
7 | 7 | -e "s/(Package-Requires.*\(ido-completing-read\+\s+)\"[0-9.]+\"\)/\${1}\"${TARGET_VERSION}\")/g;" \ |
8 | 8 | -e "s/\(package \"ido-ubiquitous\" \"[0-9.]+\"/(package \"ido-ubiquitous\" \"${TARGET_VERSION}\"/g" \ |
9 | *.el Cask | |
9 | *.el | |
10 | 10 | else |
11 | 11 | echo "Usage: $0 VERSION_NUMBER" |
12 | 12 | fi |
5 | 5 | (require 'buttercup) |
6 | 6 | (require 'cl-lib) |
7 | 7 | (require 'with-simulated-input) |
8 | (require 's) | |
8 | 9 | |
9 | 10 | ;; Note: Currently unused, but potentially useful in the future |
10 | 11 | (defun ido-cr+-maybe-chop (items elem) |
142 | 143 | ((ido-mode t) |
143 | 144 | (ido-ubiquitous-mode t) |
144 | 145 | (ido-cr+-debug-mode t) |
145 | ido-cr+-auto-update-blacklist | |
146 | ido-cr+-auto-update-disable-list | |
146 | 147 | ido-cr+-fallback-function |
147 | 148 | ido-cr+-max-items |
148 | ido-cr+-function-blacklist | |
149 | ido-cr+-function-whitelist | |
149 | ido-cr+-disable-list | |
150 | ido-cr+-allow-list | |
150 | 151 | ido-cr+-nil-def-alternate-behavior-list |
151 | 152 | ido-cr+-replace-completely |
152 | 153 | ido-confirm-unique-completion |
206 | 207 | (let ((eldef-was-showing nil)) |
207 | 208 | ;; No REQUIRE-MATCH, so electric default should not show |
208 | 209 | (with-simulated-input |
209 | '("blu DEL DEL DEL" | |
210 | (setq eldef-was-showing minibuf-eldef-showing-default-in-prompt) | |
211 | "RET") | |
210 | ("blu DEL DEL DEL" | |
211 | (setq eldef-was-showing minibuf-eldef-showing-default-in-prompt) | |
212 | "RET") | |
212 | 213 | (ido-completing-read+ "Prompt (default green): " '("blue" "yellow" "green"))) |
213 | 214 | (expect eldef-was-showing :not :to-be-truthy) |
214 | 215 | ;; With REQUIRE-MATCH, so electric default should show |
215 | 216 | (with-simulated-input |
216 | '("blu DEL DEL DEL" | |
217 | (setq eldef-was-showing minibuf-eldef-showing-default-in-prompt) | |
218 | "RET") | |
217 | ("blu DEL DEL DEL" | |
218 | (setq eldef-was-showing minibuf-eldef-showing-default-in-prompt) | |
219 | "RET") | |
219 | 220 | (ido-completing-read+ "Prompt (default green): " '("blue" "yellow" "green") nil t)) |
220 | 221 | (expect eldef-was-showing :to-be-truthy))) |
221 | 222 | |
313 | 314 | (with-simulated-input "C-j" |
314 | 315 | (ido-completing-read+ |
315 | 316 | "Prompt: " |
316 | '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t)) | |
317 | '("bluebird" "blues" "bluegrass" "blueberry" "yellow" "green") nil t)) | |
317 | 318 | :to-equal "")) |
318 | 319 | ;; "C-j" should NOT be allowed to return an empty string if |
319 | 320 | ;; require-match and default are both non-nil. |
320 | (it "should not alow exiting with an empty string if DEF is non-nil" | |
321 | (it "should not allow exiting with an empty string if DEF is non-nil" | |
321 | 322 | (expect |
322 | 323 | (with-simulated-input "C-j" |
323 | 324 | (ido-completing-read+ |
324 | 325 | "Prompt: " |
325 | '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t nil nil "yellow")) | |
326 | '("bluebird" "blues" "bluegrass" "blueberry" "yellow" "green") nil t nil nil "yellow")) | |
326 | 327 | :to-throw)) |
327 | 328 | |
328 | 329 | (it "shouldn't allow C-j to select an ambiguous match" |
330 | ;; Make this a no-op to avoid end-of-buffer errors, which are | |
331 | ;; irrelevant to this test. | |
332 | (spy-on 'scroll-other-window) | |
329 | 333 | (expect |
330 | 334 | (with-simulated-input "b C-j C-j C-j" |
331 | 335 | (ido-completing-read+ |
332 | 336 | "Prompt: " |
333 | '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t)) | |
337 | '("bluebird" "blues" "bluegrass" "blueberry" "yellow" "green") nil t)) | |
334 | 338 | :to-throw) |
335 | 339 | ;; First press of C-j should complete to "blue" after the |
336 | 340 | ;; first b, but then get stuck on the choice for the second b. |
354 | 358 | (with-simulated-input "b l u e g C-j" |
355 | 359 | (ido-completing-read+ |
356 | 360 | "Prompt: " |
357 | '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t)) | |
361 | '("bluebird" "blues" "bluegrass" "blueberry" "yellow" "green") nil t)) | |
358 | 362 | :to-equal "bluegrass")) |
359 | 363 | |
360 | 364 | (it "should require an extra C-j to exit when `ido-confirm-unique-completion' is non-nil" |
365 | 369 | (with-simulated-input "b l u e g C-j" |
366 | 370 | (ido-completing-read+ |
367 | 371 | "Prompt: " |
368 | '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t)) | |
372 | '("bluebird" "blues" "bluegrass" "blueberry" "yellow" "green") nil t)) | |
369 | 373 | :to-throw) |
370 | 374 | ;; The first "C-j" should complete to "bluegrass", and the second |
371 | 375 | ;; should return. |
373 | 377 | (with-simulated-input "b l u e g C-j C-j" |
374 | 378 | (ido-completing-read+ |
375 | 379 | "Prompt: " |
376 | '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t)) | |
380 | '("bluebird" "blues" "bluegrass" "blueberry" "yellow" "green") nil t)) | |
377 | 381 | :to-equal "bluegrass")) |
378 | 382 | |
379 | 383 | ;; Finally, a test for the expected wrong behavior without |
384 | 388 | (with-simulated-input "b C-j" |
385 | 389 | (ido-completing-read |
386 | 390 | "Prompt: " |
387 | '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t)) | |
391 | '("bluebird" "blues" "bluegrass" "blueberry" "yellow" "green") nil t)) | |
388 | 392 | :to-equal "b"))) |
389 | 393 | |
390 | 394 | (describe "when INHERIT-INPUT-METHOD is non-nil" |
506 | 510 | (it "should do a dynamic update when idle" |
507 | 511 | (expect |
508 | 512 | (with-simulated-input |
509 | '("h" | |
510 | (wsi-simulate-idle-time (1+ ido-cr+-dynamic-update-idle-time)) | |
511 | "-ld RET") | |
513 | ("h" | |
514 | (wsi-simulate-idle-time (1+ ido-cr+-dynamic-update-idle-time)) | |
515 | "-ld RET") | |
512 | 516 | (ido-completing-read+ "Say something: " my-dynamic-collection)) |
513 | 517 | :to-equal |
514 | 518 | "hello-world") |
526 | 530 | |
527 | 531 | (it "should not exit with a unique match if new matches are dynamically added" |
528 | 532 | (expect |
529 | (with-simulated-input '("hell TAB -ld RET") | |
533 | (with-simulated-input ("hell TAB -ld RET") | |
530 | 534 | (ido-completing-read+ "Say something: " my-dynamic-collection)) |
531 | 535 | :to-equal |
532 | 536 | "hello-world") |
535 | 539 | |
536 | 540 | (it "should exit with a match that is still unique after dynamic updating" |
537 | 541 | (expect |
538 | (with-simulated-input '("helic TAB") | |
542 | (with-simulated-input ("helic TAB") | |
539 | 543 | (ido-completing-read+ "Say something: " my-dynamic-collection)) |
540 | 544 | :to-equal |
541 | 545 | "helicopter") |
555 | 559 | ;; was not being debugged. |
556 | 560 | (debug-on-error nil)) |
557 | 561 | (expect |
558 | (with-simulated-input '("hell TAB RET") | |
562 | (with-simulated-input ("hell TAB RET") | |
559 | 563 | (ido-completing-read+ "Say something: " collection)) |
560 | 564 | :to-equal |
561 | 565 | "hello"))) |
600 | 604 | (with-simulated-input "eee C-SPC aaa C-u C-SPC ccc C-u C-SPC ggg RET" |
601 | 605 | (ido-completing-read+ |
602 | 606 | "Pick: " (collection-as-function collection) nil t nil nil (car collection))) |
603 | :to-equal "bbb-eee-ggg")))) | |
607 | :to-equal "bbb-eee-ggg"))) | |
608 | ||
609 | ;; It turns out that even `completing-read' can't handle this | |
610 | ;; ridiculousness, so I'm not going to worry about it unless it | |
611 | ;; becomes a problem in practice. | |
612 | (xit "should allow exiting with a match that is only detected by `test-completion'" | |
613 | (let* ((real-collection '("blue" "yellow" "brown")) | |
614 | ;; A special dynamic collection function that always | |
615 | ;; returns nil except for `test-completion'. | |
616 | (special-collection-function | |
617 | (lambda (string predicate action) | |
618 | (pcase action | |
619 | ('metadata nil) | |
620 | (`(boundaries . _) nil) | |
621 | ;; `try-completion' | |
622 | ('nil nil) | |
623 | ;; `all-completions' | |
624 | ('t nil) | |
625 | ;; `test-completion' | |
626 | (_ (test-completion string real-collection predicate)))))) | |
627 | ;; Verify that the collection exhibits the desired | |
628 | ;; pathological behavior | |
629 | (expect | |
630 | (all-completions "" special-collection-function) | |
631 | :to-equal nil) | |
632 | (expect | |
633 | (all-completions "yellow" special-collection-function) | |
634 | :to-equal nil) | |
635 | (expect | |
636 | (try-completion "yellow" special-collection-function) | |
637 | :to-equal nil) | |
638 | (expect | |
639 | (test-completion "yellow" special-collection-function) | |
640 | :to-equal t) | |
641 | (expect | |
642 | ;; Unambiguous input, but the collection function only | |
643 | ;; accepts exact matches, so this should fail. | |
644 | (with-simulated-input "yel RET RET RET" | |
645 | (ido-completing-read+ "Pick: " special-collection-function nil t)) | |
646 | :to-throw 'error) | |
647 | (expect | |
648 | (with-simulated-input "yellow RET" | |
649 | (ido-completing-read+ "Pick: " special-collection-function nil t)) | |
650 | :to-equal "yellow")))) | |
604 | 651 | |
605 | 652 | (describe "with unusual inputs" |
606 | (it "should accept a COLLECTION of symbols" | |
653 | (it "should accept symbols in COLLECTION" | |
607 | 654 | (expect |
608 | 655 | (with-simulated-input "g RET" |
609 | 656 | (ido-completing-read+ "Prompt: " '(blue yellow green))) |
677 | 724 | (command-execute 'test-command))) |
678 | 725 | :to-equal "g")) |
679 | 726 | |
680 | (describe "with `ido-cr+-function-blacklist'" | |
727 | (describe "with `ido-cr+-disable-list'" | |
681 | 728 | (before-all |
682 | (setf (symbol-function 'blacklisted-command) | |
729 | (setf (symbol-function 'disabled-command) | |
683 | 730 | (lambda (arg) |
684 | 731 | (interactive (list (completing-read "Prompt: " '("blue" "yellow" "green")))) |
685 | 732 | arg) |
686 | (symbol-function 'blacklisted-function) | |
733 | (symbol-function 'disabled-function) | |
687 | 734 | (lambda () |
688 | 735 | (completing-read "Prompt: " '("blue" "yellow" "green"))) |
689 | (symbol-function 'cmd-that-calls-blacklisted-function) | |
736 | (symbol-function 'cmd-that-calls-disabled-function) | |
690 | 737 | (lambda () |
691 | 738 | (interactive) |
692 | (funcall 'blacklisted-function)) | |
693 | (symbol-function 'blacklisted-collection) | |
739 | (funcall 'disabled-function)) | |
740 | (symbol-function 'disabled-collection) | |
694 | 741 | (collection-as-function '("blue" "yellow" "green")))) |
695 | 742 | |
696 | 743 | (after-all |
697 | (setf (symbol-function 'blacklisted-command) nil | |
698 | (symbol-function 'blacklisted-function) nil | |
699 | (symbol-function 'cmd-that-calls-blacklisted-function) nil | |
700 | (symbol-function 'blacklisted-collection) nil)) | |
701 | ;; First verify that they work normally before blacklisting them | |
702 | (describe "when the specified functions are not blacklisted" | |
703 | ||
704 | (it "should not affect a non-blacklisted command" | |
705 | (expect | |
706 | (with-simulated-input "g RET" | |
707 | (call-interactively 'blacklisted-command)) | |
744 | (setf (symbol-function 'disabled-command) nil | |
745 | (symbol-function 'disabled-function) nil | |
746 | (symbol-function 'cmd-that-calls-disabled-function) nil | |
747 | (symbol-function 'disabled-collection) nil)) | |
748 | ;; First verify that they work normally before disabling them | |
749 | (describe "when the specified functions are not disabled" | |
750 | ||
751 | (it "should not affect a non-disabled command" | |
752 | (expect | |
753 | (with-simulated-input "g RET" | |
754 | (call-interactively 'disabled-command)) | |
708 | 755 | :to-equal "green")) |
709 | 756 | |
710 | (it "should not affect a non-blacklisted function" | |
711 | (expect | |
712 | (with-simulated-input "g RET" | |
713 | (call-interactively 'cmd-that-calls-blacklisted-function)) | |
757 | (it "should not affect a non-disabled function" | |
758 | (expect | |
759 | (with-simulated-input "g RET" | |
760 | (call-interactively 'cmd-that-calls-disabled-function)) | |
714 | 761 | :to-equal "green")) |
715 | 762 | |
716 | (it "should not affect a non-blacklisted collection" | |
717 | (expect | |
718 | (with-simulated-input "g RET" | |
719 | (ido-completing-read+ "Prompt: " 'blacklisted-collection)) | |
763 | (it "should not affect a non-disabled collection" | |
764 | (expect | |
765 | (with-simulated-input "g RET" | |
766 | (ido-completing-read+ "Prompt: " 'disabled-collection)) | |
720 | 767 | :to-equal "green"))) |
721 | 768 | |
722 | (describe "when the specified functions are blacklisted" | |
769 | (describe "when the specified functions are disabled" | |
723 | 770 | (before-each |
724 | (setq ido-cr+-function-blacklist | |
725 | (append '(blacklisted-command | |
726 | blacklisted-function | |
727 | blacklisted-collection) | |
728 | ido-cr+-function-blacklist))) | |
729 | ||
730 | (it "should prevent ido in a blacklisted command" | |
731 | (expect | |
732 | (with-simulated-input "g RET" | |
733 | (call-interactively 'blacklisted-command)) | |
771 | (setq ido-cr+-disable-list | |
772 | (append '(disabled-command | |
773 | disabled-function | |
774 | disabled-collection) | |
775 | ido-cr+-disable-list))) | |
776 | ||
777 | (it "should prevent ido in a disabled command" | |
778 | (expect | |
779 | (with-simulated-input "g RET" | |
780 | (call-interactively 'disabled-command)) | |
734 | 781 | :to-equal "g")) |
735 | 782 | |
736 | (it "should prevent ido in a blacklisted function" | |
737 | (expect | |
738 | (with-simulated-input "g RET" | |
739 | (call-interactively 'cmd-that-calls-blacklisted-function)) | |
783 | (it "should prevent ido in a disabled function" | |
784 | (expect | |
785 | (with-simulated-input "g RET" | |
786 | (call-interactively 'cmd-that-calls-disabled-function)) | |
740 | 787 | :to-equal "g")) |
741 | 788 | |
742 | (it "should prevent ido with a blacklisted collection" | |
743 | (expect | |
744 | (with-simulated-input "g RET" | |
745 | (ido-completing-read+ "Prompt: " 'blacklisted-collection)) | |
789 | (it "should prevent ido with a disabled collection" | |
790 | (expect | |
791 | (with-simulated-input "g RET" | |
792 | (ido-completing-read+ "Prompt: " 'disabled-collection)) | |
746 | 793 | :to-equal "g"))) |
747 | 794 | |
748 | 795 | (describe "when updating ido-cr+" |
749 | 796 | |
750 | 797 | (before-each |
751 | (spy-on 'ido-cr+-update-blacklist :and-call-through)) | |
752 | ||
753 | (it "should update the blacklist when `ido-cr+-auto-update-blacklist' is t" | |
754 | (assume ido-cr+-function-blacklist) | |
755 | (let ((orig-blacklist ido-cr+-function-blacklist)) | |
756 | (customize-set-variable 'ido-cr+-auto-update-blacklist t) | |
757 | (customize-set-variable 'ido-cr+-function-blacklist nil) | |
758 | (ido-cr+-maybe-update-blacklist) | |
759 | (expect 'ido-cr+-update-blacklist :to-have-been-called) | |
760 | (expect ido-cr+-function-blacklist :to-have-same-items-as orig-blacklist))) | |
761 | (it "should not update the blacklist when `ido-cr+-auto-update-blacklist' is nil" | |
762 | (assume ido-cr+-function-blacklist) | |
763 | (let ((orig-blacklist ido-cr+-function-blacklist)) | |
764 | (customize-set-variable 'ido-cr+-auto-update-blacklist nil) | |
765 | (customize-set-variable 'ido-cr+-function-blacklist nil) | |
766 | (ido-cr+-maybe-update-blacklist) | |
767 | (expect 'ido-cr+-update-blacklist :not :to-have-been-called) | |
768 | (expect ido-cr+-function-blacklist :to-have-same-items-as nil))) | |
769 | ||
770 | (it "should notify about blacklist updates when `ido-cr+-auto-update-blacklist' is `notify'" | |
771 | (assume ido-cr+-function-blacklist) | |
798 | (spy-on 'ido-cr+-update-disable-list :and-call-through)) | |
799 | ||
800 | (it "should update the disable list when `ido-cr+-auto-update-disable-list' is t" | |
801 | (assume ido-cr+-disable-list) | |
802 | (let ((orig-disable-list ido-cr+-disable-list)) | |
803 | (customize-set-variable 'ido-cr+-auto-update-disable-list t) | |
804 | (customize-set-variable 'ido-cr+-disable-list nil) | |
805 | (ido-cr+-maybe-update-disable-list) | |
806 | (expect 'ido-cr+-update-disable-list :to-have-been-called) | |
807 | (expect ido-cr+-disable-list :to-have-same-items-as orig-disable-list))) | |
808 | (it "should not update the disable list when `ido-cr+-auto-update-disable-list' is nil" | |
809 | (assume ido-cr+-disable-list) | |
810 | (let ((orig-disable-list ido-cr+-disable-list)) | |
811 | (customize-set-variable 'ido-cr+-auto-update-disable-list nil) | |
812 | (customize-set-variable 'ido-cr+-disable-list nil) | |
813 | (ido-cr+-maybe-update-disable-list) | |
814 | (expect 'ido-cr+-update-disable-list :not :to-have-been-called) | |
815 | (expect ido-cr+-disable-list :to-have-same-items-as nil))) | |
816 | ||
817 | (it "should notify about disable list updates when `ido-cr+-auto-update-disable-list' is `notify'" | |
818 | (assume ido-cr+-disable-list) | |
772 | 819 | (spy-on 'display-warning) |
773 | (let ((orig-blacklist ido-cr+-function-blacklist)) | |
774 | (customize-set-variable 'ido-cr+-auto-update-blacklist 'notify) | |
775 | (customize-set-variable 'ido-cr+-function-blacklist nil) | |
776 | (ido-cr+-maybe-update-blacklist) | |
777 | (expect 'ido-cr+-update-blacklist :not :to-have-been-called) | |
820 | (let ((orig-disable-list ido-cr+-disable-list)) | |
821 | (customize-set-variable 'ido-cr+-auto-update-disable-list 'notify) | |
822 | (customize-set-variable 'ido-cr+-disable-list nil) | |
823 | (ido-cr+-maybe-update-disable-list) | |
824 | (expect 'ido-cr+-update-disable-list :not :to-have-been-called) | |
778 | 825 | (expect 'display-warning :to-have-been-called) |
779 | (expect ido-cr+-function-blacklist :to-have-same-items-as nil))))) | |
780 | ||
781 | (describe "with `ido-cr+-function-whitelist'" | |
826 | (expect ido-cr+-disable-list :to-have-same-items-as nil))))) | |
827 | ||
828 | (describe "with `ido-cr+-allow-list'" | |
782 | 829 | (before-all |
783 | (setf (symbol-function 'whitelisted-command) | |
830 | (setf (symbol-function 'allowed-command) | |
784 | 831 | (lambda (arg) |
785 | 832 | (interactive |
786 | 833 | (list |
787 | 834 | (completing-read "Prompt: " '("blue" "yellow" "green")))) |
788 | 835 | arg) |
789 | (symbol-function 'whitelisted-function) | |
836 | (symbol-function 'allowed-function) | |
790 | 837 | (lambda () |
791 | 838 | (completing-read "Prompt: " '("blue" "yellow" "green"))) |
792 | (symbol-function 'cmd-that-calls-whitelisted-function) | |
839 | (symbol-function 'cmd-that-calls-allowed-function) | |
793 | 840 | (lambda () |
794 | 841 | (interactive) |
795 | (funcall 'whitelisted-function)) | |
796 | (symbol-function 'whitelisted-collection) | |
842 | (funcall 'allowed-function)) | |
843 | (symbol-function 'allowed-collection) | |
797 | 844 | (lambda (string pred action) |
798 | 845 | (complete-with-action action '("blue" "yellow" "green") string pred)))) |
799 | 846 | |
800 | 847 | (after-all |
801 | (setf (symbol-function 'whitelisted-command) nil | |
802 | (symbol-function 'whitelisted-function) nil | |
803 | (symbol-function 'cmd-that-calls-whitelisted-function) nil | |
804 | (symbol-function 'whitelisted-collection) nil)) | |
805 | ||
806 | (describe "when the whitelist is inactive (i.e. everything is whitelisted)" | |
848 | (setf (symbol-function 'allowed-command) nil | |
849 | (symbol-function 'allowed-function) nil | |
850 | (symbol-function 'cmd-that-calls-allowed-function) nil | |
851 | (symbol-function 'allowed-collection) nil)) | |
852 | ||
853 | (describe "when the allow list is inactive (i.e. everything is allowed)" | |
807 | 854 | (before-each |
808 | (setq ido-cr+-function-whitelist nil)) | |
855 | (setq ido-cr+-allow-list nil)) | |
809 | 856 | |
810 | 857 | (it "should enable ido in a command" |
811 | 858 | (expect |
812 | 859 | (with-simulated-input "g RET" |
813 | (call-interactively 'whitelisted-command)) | |
860 | (call-interactively 'allowed-command)) | |
814 | 861 | :to-equal "green")) |
815 | 862 | |
816 | 863 | (it "should enable ido in a function" |
817 | 864 | (expect |
818 | 865 | (with-simulated-input "g RET" |
819 | (call-interactively 'cmd-that-calls-whitelisted-function)) | |
866 | (call-interactively 'cmd-that-calls-allowed-function)) | |
820 | 867 | :to-equal "green")) |
821 | 868 | |
822 | 869 | (it "should enable ido for a collection" |
823 | 870 | (expect |
824 | 871 | (with-simulated-input "g RET" |
825 | (ido-completing-read+ "Prompt: " 'whitelisted-collection)) | |
872 | (ido-completing-read+ "Prompt: " 'allowed-collection)) | |
826 | 873 | :to-equal "green"))) |
827 | 874 | |
828 | (describe "when the specified functions are whitelisted" | |
875 | (describe "when the specified functions are allowed" | |
829 | 876 | (before-each |
830 | (setq ido-cr+-function-whitelist | |
831 | (append '(whitelisted-command | |
832 | whitelisted-function | |
833 | whitelisted-collection) | |
834 | ido-cr+-function-whitelist))) | |
835 | ||
836 | (it "should enable ido in a whitelisted command" | |
837 | (expect | |
838 | (with-simulated-input "g RET" | |
839 | (call-interactively 'whitelisted-command)) | |
877 | (setq ido-cr+-allow-list | |
878 | (append '(allowed-command | |
879 | allowed-function | |
880 | allowed-collection) | |
881 | ido-cr+-allow-list))) | |
882 | ||
883 | (it "should enable ido in an allowed command" | |
884 | (expect | |
885 | (with-simulated-input "g RET" | |
886 | (call-interactively 'allowed-command)) | |
840 | 887 | :to-equal "green")) |
841 | 888 | |
842 | (it "should enable ido in a whitelisted function" | |
843 | (expect | |
844 | (with-simulated-input "g RET" | |
845 | (call-interactively 'cmd-that-calls-whitelisted-function)) | |
889 | (it "should enable ido in an allowed function" | |
890 | (expect | |
891 | (with-simulated-input "g RET" | |
892 | (call-interactively 'cmd-that-calls-allowed-function)) | |
846 | 893 | :to-equal "green")) |
847 | 894 | |
848 | (it "should enable ido for a whitelisted collection" | |
849 | (expect | |
850 | (with-simulated-input "g RET" | |
851 | (ido-completing-read+ "Prompt: " 'whitelisted-collection)) | |
895 | (it "should enable ido for an allowed collection" | |
896 | (expect | |
897 | (with-simulated-input "g RET" | |
898 | (ido-completing-read+ "Prompt: " 'allowed-collection)) | |
852 | 899 | :to-equal "green"))) |
853 | 900 | |
854 | (describe "when the whitelist is active but empty (i.e. nothing whitelisted)" | |
901 | (describe "when the allow list is active but empty (i.e. nothing allowed)" | |
855 | 902 | (before-each |
856 | (setq ido-cr+-function-whitelist (list nil))) | |
903 | (setq ido-cr+-allow-list (list nil))) | |
857 | 904 | |
858 | 905 | (it "should prevent ido in a command" |
859 | 906 | (expect |
860 | 907 | (with-simulated-input "g RET" |
861 | (call-interactively 'whitelisted-command)) | |
908 | (call-interactively 'allowed-command)) | |
862 | 909 | :to-equal "g")) |
863 | 910 | |
864 | 911 | (it "should prevent ido in a function" |
865 | 912 | (expect |
866 | 913 | (with-simulated-input "g RET" |
867 | (call-interactively 'cmd-that-calls-whitelisted-function)) | |
914 | (call-interactively 'cmd-that-calls-allowed-function)) | |
868 | 915 | :to-equal "g")) |
869 | 916 | |
870 | 917 | (it "should prevent ido for a collection" |
871 | 918 | (expect |
872 | 919 | (with-simulated-input "g RET" |
873 | (ido-completing-read+ "Prompt: " 'whitelisted-collection)) | |
920 | (ido-completing-read+ "Prompt: " 'allowed-collection)) | |
874 | 921 | :to-equal "g")))) |
875 | 922 | |
876 | 923 | (describe "with `ido-cr+-nil-def-alternate-behavior-list'" |
971 | 1018 | :not :to-throw))) |
972 | 1019 | |
973 | 1020 | (describe "regressions should not occur for" |
974 | (it "issue #151: should not hang or error when cycling matches in `Info-menu'" | |
1021 | ;; Disabled because I think the nix CI emacs has no info pages, so | |
1022 | ;; the completion for `Info-menu' has nothing to do. However, this | |
1023 | ;; should be thoroughly fixed by now. | |
1024 | (xit "issue #151: should not hang or error when cycling matches in `Info-menu'" | |
975 | 1025 | (expect |
976 | 1026 | (progn |
977 | 1027 | (ido-ubiquitous-mode 1) |
978 | 1028 | (with-temp-info-buffer |
979 | (with-simulated-input | |
980 | '("emacs" | |
981 | (ido-next-match) | |
982 | (wsi-simulate-idle-time 5) | |
983 | (ido-next-match) | |
984 | (wsi-simulate-idle-time 5) | |
985 | (ido-next-match) | |
986 | (wsi-simulate-idle-time 5) | |
987 | (ido-next-match) | |
988 | (wsi-simulate-idle-time 5) | |
989 | "RET") | |
990 | (command-execute 'Info-menu)))) | |
1029 | (with-simulated-input | |
1030 | '((ido-next-match) | |
1031 | (wsi-simulate-idle-time 5) | |
1032 | (ido-next-match) | |
1033 | (wsi-simulate-idle-time 5) | |
1034 | (ido-next-match) | |
1035 | (wsi-simulate-idle-time 5) | |
1036 | (ido-next-match) | |
1037 | (wsi-simulate-idle-time 5) | |
1038 | "RET") | |
1039 | (command-execute 'Info-menu)))) | |
991 | 1040 | :not :to-throw)) |
992 | 1041 | |
993 | 1042 | (it "issue #153: should preserve the selected item when doing a deferred dynamic update" |
994 | 1043 | (expect |
995 | 1044 | (with-simulated-input |
996 | '("Emacs" | |
997 | (ido-next-match) | |
998 | (wsi-simulate-idle-time 5) | |
999 | "RET") | |
1045 | ("Emacs" | |
1046 | (ido-next-match) | |
1047 | (wsi-simulate-idle-time 5) | |
1048 | "RET") | |
1000 | 1049 | (ido-completing-read+ |
1001 | 1050 | "Choose: " |
1002 | 1051 | (collection-as-function '("Emacs" "Emacs A" "Emacs B" "Emacs C")))) |
14 | 14 | (require 'buttercup) |
15 | 15 | (require 'cl-lib) |
16 | 16 | (require 'with-simulated-input) |
17 | (require 's) | |
18 | ||
19 | (defvar my-dynamic-collection nil) | |
17 | 20 | |
18 | 21 | (defun collection-as-function (collection) |
19 | 22 | "Return a function equivalent to COLLECTION. |
126 | 129 | ((ido-mode t) |
127 | 130 | (ido-ubiquitous-mode t) |
128 | 131 | (ido-cr+-debug-mode t) |
129 | ido-cr+-auto-update-blacklist | |
132 | ido-cr+-auto-update-disable-list | |
130 | 133 | ido-cr+-fallback-function |
131 | 134 | ido-cr+-max-items |
132 | ido-cr+-function-blacklist | |
133 | ido-cr+-function-whitelist | |
135 | ido-cr+-disable-list | |
136 | ido-cr+-allow-list | |
134 | 137 | ido-cr+-nil-def-alternate-behavior-list |
135 | 138 | ido-cr+-replace-completely |
136 | 139 | ido-confirm-unique-completion |
205 | 208 | (it "should do a dynamic update when idle" |
206 | 209 | (expect |
207 | 210 | (with-simulated-input |
208 | '("h" | |
209 | (wsi-simulate-idle-time (1+ ido-cr+-dynamic-update-idle-time)) | |
210 | "-ld RET") | |
211 | ("h" | |
212 | (wsi-simulate-idle-time (1+ ido-cr+-dynamic-update-idle-time)) | |
213 | "-ld RET") | |
211 | 214 | (ido-completing-read+ "Say something: " my-dynamic-collection)) |
212 | 215 | :to-equal |
213 | 216 | "hello-world") |
225 | 228 | |
226 | 229 | (it "should not exit with a unique match if new matches are dynamically added" |
227 | 230 | (expect |
228 | (with-simulated-input '("hell TAB -ld RET") | |
231 | (with-simulated-input ("hell TAB -ld RET") | |
229 | 232 | (ido-completing-read+ "Say something: " my-dynamic-collection)) |
230 | 233 | :to-equal |
231 | 234 | "hello-world") |
234 | 237 | |
235 | 238 | (it "should exit with a match that is still unique after dynamic updating" |
236 | 239 | (expect |
237 | (with-simulated-input '("helic TAB") | |
240 | (with-simulated-input ("helic TAB") | |
238 | 241 | (ido-completing-read+ "Say something: " my-dynamic-collection)) |
239 | 242 | :to-equal |
240 | 243 | "helicopter") |