Codebase list ido-ubiquitous / ca425aa
New upstream version 4.5 Lev Lamberov 6 years ago
10 changed file(s) with 2022 addition(s) and 2089 deletion(s). Raw diff Collapse all Expand all
0 language: generic
1
2 env:
3 matrix:
4 - EMACS_VERSION=emacs-24.4
5 - EMACS_VERSION=emacs-24.5
6 - EMACS_VERSION=emacs-25.1
7 - EMACS_VERSION=emacs-25.2
8 - EMACS_VERSION=emacs-git-snapshot
9 - EMACS_VERSION=remacs-git-snapshot
10
11 matrix:
12 allow_failures:
13 - env: EMACS_VERSION=remacs-git-snapshot
14
15 before_script:
16 # Install evm
17 - git clone https://github.com/rejeep/evm.git ~/.evm
18 - export PATH="$HOME/.evm/bin:$PATH"
19 - evm config path /tmp
20 - evm list
21 # use this version of emacs for tests
22 - evm install "${EMACS_VERSION}-travis" --use --skip
23 - evm list
24 - emacs --version
25 # Install cask
26 - curl -fsSkL https://raw.github.com/cask/cask/master/go | python
27 - export PATH="$HOME/.cask/bin:$PATH"
28 # Install elisp dependencies
29 - cask install
30
31 script:
32 cask exec buttercup -L .
00 ;; -*- mode: emacs-lisp -*-
11
2 (source gnu)
23 (source melpa)
34
4 (package "ido-ubiquitous" "3.8" "Use ido (nearly) everywhere.")
5 (package-file "ido-completing-read+.el")
6
7 (depends-on "s")
8 (depends-on "memoize" "1.1")
59
610 (development
7 (depends-on "f")
8 (depends-on "ert-runner"))
11 (depends-on "with-simulated-input"
12 :git "https://github.com/DarwinAwardWinner/with-simulated-input.git"
13 :files ("*.el"))
14 (depends-on "buttercup"
15 :git "https://github.com/DarwinAwardWinner/emacs-buttercup.git"
16 :branch "expect-closures"
17 :files ("*.el"
18 ("bin" "bin/*"))))
0 2017-08-13 Ryan C. Thompson <rct@thompsonclan.org>
1
2 * ido-completing-read+.el (ido-cr+-apply-restrictions): Make
3 "ido-restrict-to-matches" work with dynamic completion tables.
4
5 (ido-cr+-update-dynamic-collection): Make behavior on dynamic
6 completion tables more deterministic. The set of offered
7 completions now only depends on the current input, not the precise
8 sequence of insertions and deletions the user used to end up
9 there. ido-completing-read+ now depends on the memoize package.
10
11 2017-08-07 Ryan C. Thompson <rct@thompsonclan.org>
12
13 * ido-completing-read+.el: Declare missing dependency on "s"
14 pacakge.
15
16 (ido-completing-read+): Allow DEF to be a string (or list of
17 strings).
18
19 (ido-cr+-nil-def-alternate-behavior-list): Support commands that
20 behave badly when "require-match" is non-nil and "def" is nil.
21
22 (ido-select-text@ido-cr+-fix-require-match): If the collection is
23 dynamic, use "try-completion" as an alternative way to check for a
24 match.
25
26 2017-07-24 Ryan C. Thompson <rct@thompsonclan.org>
27
28 * ido-completing-read+.el: Further improvements to handling of
29 dynamic completion tables. Among other things, flex matching is
30 now supported for dynamic tables, and idle timers are used to
31 avoid recalculating the list of completions between every
32 keystroke.
33
34 2017-07-08 Ryan C. Thompson <rct@thompsonclan.org>
35
36 * ido-completing-read+.el: Internal change: switch to the new
37 "nadvice" system for all function advice.
38
39 2017-07-05 Ryan C. Thompson <rct@thompsonclan.org>
40
41 * ido-completing-read+.el (ido-completing-read+): Massive
42 refactor. The "overrides" system has been completely reworked.
43 There is no longer a distinction between "old" and "new" default
44 styles; commands and functions are no longer treated differently;
45 and ido-cr+ is now enabled for dynamic completion tables. Users
46 should read the FAQ, which explains the minor user-visible
47 changes.
48
49 * ido-ubiquitous.el: Refactor entire package into ido-cr+. The
50 current ido-ubiquitous.el is just a stub that loads ido-cr+ and
51 displays a deprecation warning.
52
53 2017-06-01 Ryan C. Thompson <rct@thompsonclan.org>
54
55 * ido-completing-read+.el (ido-completing-read+): Don't use ido if
56 the collection is empty, since doing so would be pointless.
57
58 * ido-ubiquitous.el (ido-ubiquitous-default-command-overrides):
59 Update some overrides
60
61 * ido-describe-fns.el (ido-descfns-maybe-load-prefixes): Add
62 support for the auto-loading feature of describe-variable and
63 similar commands.
64
065 2017-03-13 Ryan C. Thompson <rct@thompsonclan.org>
166
267 * ido-ubiquitous.el (ido-cr+--explain-fallback): Fix
0 # ido-ubiquitous #
1
0 # ido-completing-read+ (formerly ido-ubiquitous) #
1
2 [![Build Status](https://travis-ci.org/DarwinAwardWinner/ido-completing-read-plus.svg?branch=master)](https://travis-ci.org/DarwinAwardWinner/ido-completing-read-plus)
23 [![MELPA Stable](https://stable.melpa.org/packages/ido-ubiquitous-badge.svg)](https://stable.melpa.org/#/ido-ubiquitous)
34 [![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)
45
67 completion with ido completion wherever it is possible to do so
78 without breaking things.
89
9 Get it from MELPA: https://stable.melpa.org/#/ido-ubiquitous
10
11 ## Version 3.0 changes ##
12
13 Long-time users should know that ido-ubiquitous version 3.0 is a major
14 update, including a split into two packages, and some of the
15 configuration options have changed in non-backwards-compatible ways.
16 If you have customized any options ido-ubiquitous, be sure to check
17 out `M-x customize-group ido-ubiquitous` and `M-x customize-group
18 ido-completing-read+` after updating to 3.0 and make sure the new
19 settings are to your liking.
10 Get it from MELPA: https://stable.melpa.org/#/ido-completing-read+
11
12 ## Version 4.0 changes ##
13
14 Long-time users should know that ido-completing-read+ version 4.0 is a
15 major update. The previously separate ido-ubiquitous package has been
16 merged into ido-completing-read+, which now provides all the features
17 of both packages. The distinction between "new" and "old" default
18 selection styles has been eliminated and replaced by a new variable
19 `ido-cr+-no-default-action` (see [FAQ][1] for details), and the
20 override system has been accordingly simplified into just a blacklist
21 and a whitelist. If you have previously customized any ido-ubiquitous
22 options, be sure to check out
23
24 `M-x customize-group ido-completing-read+`
25
26 after updating to 4.0 and make sure the new settings are to your
27 liking.
28
29 This short-lived ido-describe-fns package has likewise been subsumed
30 into this one.
31
32 [1]: #why-does-ret-sometimes-not-select-the-first-completion-on-the-list--why-is-there-an-empty-entry-at-the-beginning-of-the-completion-list--what-happened-to-old-style-default-selection
2033
2134 # How to enable ido in as many places as possible #
2235
3346 (ido-mode 1)
3447 (ido-everywhere 1)
3548
36 ## ido-ubiquitous (this package) ##
37
38 Install this package [from MELPA](http://melpa.org/#/ido-ubiquitous)
49 ## ido-completing-read+ (this package) ##
50
51 Install this package [from MELPA](http://melpa.org/#/ido-completing-read+)
3952 and then turn on `ido-ubiquitous-mode`:
4053
41 (require 'ido-ubiquitous)
54 (require 'ido-completing-read+)
4255 (ido-ubiquitous-mode 1)
4356
4457 ## Smex ##
8194 (require 'crm-custom)
8295 (crm-custom-mode 1)
8396
84 Remember that when using this mode, completion for affected commands
85 will continue to read additional items until you use C-j to enter an
86 empty input, which terminates the completion. (Due to this quirk, I do
87 not find this mode to be very useful in conjunction with ido, but it
88 does work.)
97 Make sure to read and understand the FAQ entry below about the empty
98 entry at the beginning of the completion list before using this mode,
99 or using it will likely be very confusing.
89100
90101 ## Packages with built-in ido support ##
91102
92103 Lastly, some packages already provide their own interfaces to ido, so
93 ido-ubiquitous specifically avoids interfering with these. If you use
94 any of the following packages, you need to enable ido for each of them
95 separately.
96
97 * Magit: `(setq magit-completing-read-function 'magit-ido-completing-read)`
98 * Gnus: `(setq gnus-completing-read-function 'gnus-ido-completing-read)`
104 ido-completing-read+ specifically avoids interfering with these. If
105 you use any of the following packages, you need to enable ido for each
106 of them separately.
107
108 * [Magit](https://magit.vc/): `(setq magit-completing-read-function 'magit-ido-completing-read)`
109 * [Gnus](http://www.gnus.org/): `(setq gnus-completing-read-function 'gnus-ido-completing-read)`
110 * [ESS](https://ess.r-project.org/): `(setq ess-use-ido t)`
111
112 ## icomplete-mode ##
113
114 For any case where ido cannot be used, there is another older mode
115 called `icomplete-mode` that integrates with standard emacs completion
116 and adds some ido-like behavior. It is built in to emacs, so no
117 installation is necessary. Just load the file and enable the mode:
118
119 (require 'icomplete)
120 (icomplete-mode 1)
99121
100122 # Frequently asked questions #
101123
102 ## How does ido-ubiquitous decide when to replace `completing-read`? <br/> Why don't some commands use ido completion? ##
103
104 Emacs' `completing-read` is a complex function with many advanced
105 features and some quirks that are only maintained for backwards
106 compatibility. Not all of these features are supported by ido, so it
107 is impossible to always replace `completing-read` with ido completion.
108 Trying to use ido when these features are requested can completely
109 break the completion system. So, by default ido-ubiquitous tries to
110 get out of the way whenever it detects that these features might be
111 used by a given call to `completing-read`. Furthermore, it's not
112 always possible to detect based on the arguments to `completing-read`
113 whether such ido-incompatible features are being used or not.
114 ido-ubiquitous uses a series of heuristics to determine whether
115 unsupported features *might* be used, and also supports an override
116 feature to correct it when the heuristics get things wrong.
117
118 Each time a function invokes `completing-read`, ido-ubiquitous selects
119 one of 3 modes:
120
121 * `enable`: use ido completion;
122 * `enable-old`: use ido completion, but with a compatibility fix for
123 old-style default selection; and
124 * `disable`: no ido completion.
125
126 The following describes in detail how ido-ubiquitous selects the
127 appropriate mode, and what to do when you think it is making the wrong
128 choice.
129
130 ### Disabling ido completion when the collection is very large ###
131
132 Ido can get slow on very large collections, so by default
133 ido-ubiquitous disables itself for collections with more than 30,000
134 items in them. This rule takes precedence over anything else, even
135 overrides that explicitly enable ido completion for a command.
136
137 You can change the large collection threshold by customizing
138 `ido-cr+-max-items`.
139
140 ### Disabling ido completion when the collection is a function ###
141
142 One feature of `completing-read` is that the collection argument can
143 be a function. This function could simply return a list of all
144 possible completions, in which case it would be safe to use ido, or it
145 could implement a completely new completion system, in which case
146 using ido would interfere with this new completion system (for an
147 example of this, see the `tmm` command). But ido-ubiquitous cannot
148 tell by looking at the function which kind it is, so it errs on the
149 side of caution and disables itself whenever the collection is a
150 function, unless an override exists telling it that the command is
151 safe for ido completion. You can turn off this safeguard by
152 customizing `ido-ubiquitous-allow-on-functional-collection`. Be aware
153 that enabling this will likely break completion entirely in any
154 command that uses this feature to implement non-standard completion.
155
156 If you run across a command that unexpectedly uses normal Emacs
157 completion instead of ido completion, it's likely that either this or
158 the previous option is to blame.
159
160 ### Disabling or enabling ido completion by overrides ###
161
162 If ido-ubiquitous is not running for a command where is should be due
163 to the functional collection rule, you can add an override for that
164 command by using `M-x customize-variable
165 ido-ubiquitous-command-overrides`. Conversely, if ido completion
166 causes problems for a command, you can also use this to disable
167 ido-ubiquitous for that command.
168
169 ## What is old-style default selection? ##
170
171 The `enable-old` mode of operation is required because the old way for
172 `completing-read` to indicate that the user simply pressed RET and
173 selected the default option was to return an empty string. When this
174 old-style mode is used, `completing-read` doesn't even know what the
175 default is *supposed* to be -- the calling code handles all of that.
176 But in ido, simply pressing RET will return the first item of the
177 list, not an empty string. The way to enter an empty string in ido is
178 C-j. The `enable-old` mode enables ido completion, but swaps the
179 meaning of C-j and RET if you haven't entered any text or cycled the
180 options yet (once you do either of those, C-j and RET regain their
181 standard meanings). This allows you to select the default by pressing
182 RET as soon as the completion prompt appears, as intended (C-j would
183 select the first item).
184
185 Unfortunately, there is no way for ido-ubiquitous to detect when a
186 command is using this old-style default selection, so instead it uses
187 a built-in set of overrides telling it about commands that are known
188 to use old-style defaults. If you discover a command where pressing
189 RET or C-j at an empty prompt is not doing what you expect it to,
190 there's a good chance that you need to add an `enable-old` override
191 for that command to `ido-ubiquitous-command-overrides`. Luckily, since
192 this is an obsolete usage pattern, it is unlikely that any Elisp
193 functions written since 1990 or so will need to be added to this list.
194 Hopefully all uses of old-style completion will eventually be
195 eliminated, and with them, the need for this feature of
196 ido-ubiquitous.
197
198 ## How can I troubleshoot when ido-ubiquitous isn't doing what I want? ##
199
200 First, invoke the `ido-ubiquitous-debug-mode` and `ido-cr+-debug-mode`
201 commands. Then, with these two modes active, run the command(s) that
202 you are having trouble with, and when the completion prompt appears,
203 make a selection to complete the process. Then, examine the Messages
204 buffer, where ido-ubiquitous will explain which mode of operation it
205 selected and why. Based on this, you can add an override to
206 `ido-ubiquitous-command-overrides`. If you are not familiar with the
207 structure of this variable, I recommend using `M-x customize-variable`
208 to edit it, which will help you get it right. If ido completion was
209 skipped ido completion because the collection was too large, try
210 giving `ico-cr+-max-items` a larger value, or set it to nil if your
211 computer is fast enough to handle any size of collection.
212
213 Updates to ido-ubiquitous often include new overrides, but Emacs will
214 not edit your override variables if you have already customized them.
215 So, if you have recently upgraded ido-ubiquitous, remember to invoke
216 `ido-ubiquitous-restore-default-overrides` to add in any new
217 overrides. (In the future, this process may become automatic:
218 https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/90)
219
220 ## Where can I report bugs or suggest new overrides? ##
221
222 If you end up adding any overrides, please also report them at
124 ## How does ido-ubiquitous-mode decide when to replace `completing-read`? <br/> Why don't some commands use ido completion? ##
125
126 Emacs' `completing-read` is a complex function with many complex
127 features. Not all of these features are supported by ido, so it is
128 impossible to always replace `completing-read` with ido completion.
129 Trying to use ido when these features are requested can cause
130 confusing and unexpected behavior or even completely break the
131 completion system. So, ido-completing-read+ tries to get out of the
132 way whenever it detects that these features might be used by a given
133 call to `completing-read`. Furthermore, it's not always possible to
134 detect based on the arguments to `completing-read` whether such
135 ido-incompatible features are being used or not, so
136 ido-completing-read+ also comes with a blacklist of functions that are
137 known not to work with ido. You can inspect this blacklist using
138
139 `M-x describe-variable ido-cr+-function-blacklist`
140
141 If you want to know why a certain command isn't getting ido
142 completion, you can enable `ido-cr+-debug-mode` and then run the
143 command. There should then be a line in the `*Messages*` buffer that
144 explains the reason for disabling ido completion.
145
146 ## Why does RET sometimes not select the first completion on the list? <br/> Why is there an empty entry at the beginning of the completion list? <br/> What happened to old-style default selection? ##
147
148 The simplest way to think about this is that if the command that
149 called `completing-read` didn't specify a default, then the default is
150 the empty string. In other words, `""` is the default default.
151
152 Previous versions of ido-ubiquitous-mode gave special consideration to
153 cases where a default value was not provided to `completing-read` and
154 the user pressed RET without entering any text. The expected behavior
155 is that `completing-read` should return the empty string in this case,
156 which indicates to the calling function that the user did not select
157 any completion. This conflicts with the standard ido behavior of
158 selecting the first available completion when pressing RET, and this
159 conflict was previously resolved by having two different modes that
160 differed in their handling of RET on an empty input. Now there is only
161 one mode, and the no-default case is handled by acting as if the empty
162 string was specified as the default, which more closely matches the
163 behavior of standard emacs completion. Since you, the user, have no
164 way of knowing how `completing-read' was called, you can tell when
165 this is occurring by watching for the appearance of an empty
166 completion at the front of the list. Compare:
167
168 If the command specifies apple as the default when calling
169 `completing-read`, the prompt will look like this, and pressing RET
170 will select "apple":
171
172 Pick a fruit: {apple | banana | cherry | date}
173
174 However, if the command does not specify any default, an extra empty
175 option is displayed before the first option, and pressing RET will
176 select this empty option and return "":
177
178 Pick a fruit: { | apple | banana | cherry | date}
179
180 To select "apple" instead, you must first press the right arrow key
181 once, or type an "a", before pressing RET.
182
183 However, some commands don't take this quirk of `completing-read` into
184 account and don't expect it to ever return an empty string when
185 `require-match` is non-nil. You can accommodate these functions by
186 adding them to `ido-cr+-nil-def-alternate-behavior-list`.
187
188 ## How can I troubleshoot when ido-completing-read+ isn't doing what I want? ##
189
190 First, invoke the `ido-cr+-debug-mode` command. Then, run the command
191 or code that you are having trouble with, and when the completion
192 prompt appears, make a selection to complete the process. Then,
193 examine the Messages buffer, where ido-completing-read+ will explain
194 which mode of operation it selected and why. Based on this, you can
195 add an entry to `ido-cr+-function-blacklist`, or take some other
196 appropriate action.
197
198 Updates to ido-completing-read+ may include new blacklist entries, but
199 Emacs will not edit your override variables if you have already
200 customized them. So, if you have recently upgraded
201 ido-completing-read+, remember to invoke `ido-cr+-update-blacklist` to
202 add in any new overrides. By default, ido-completing-read+ will remind
203 you to do this whenever a new version adds to the blacklist. For more
204 information, see:
205
206 M-x describe-variable ido-cr+-auto-update-blacklist
207
208 ## Where can I report bugs? ##
209
210 If you end up adding any blacklist entries, please report them at
223211 https://github.com/DarwinAwardWinner/ido-ubiquitous/issues so I can
224212 incorporate them into the defaults for future versions. You can also
225 report any bugs you find in ido-ubiquitous.
226
227 ## I'm getting some weird warnings from ido-ubiquitous when Emacs starts. ##
213 report any bugs you find in ido-completing-read+.
214
215 ## I'm getting some weird warnings from ido-completing-read+ when Emacs starts. ##
228216
229217 I've gotten numerous reports about nonsensical warnings produced by
230 ido-ubiquitous, such as "free variable" warnings about variables that
218 this package, such as "free variable" warnings about variables that
231219 are most definitely properly declared, or warnings that only appear
232 when ido-ubiquitous is loaded after another unrelated package. For
233 many of these warnings, I've never been able to discover the cause or
234 reproduce the warnings myself, and I've given up trying to figure it
235 out. Please don't report any new bugs about variable warnings *unless*
236 you can tell me how to consistently reproduce them starting from
237 `emacs -Q`. If you are an Emacs expert who knows how to fix these
238 warnings, please let me know.
220 when ido-completing-read+ is loaded after another unrelated package.
221 For many of these warnings, I've never been able to discover the cause
222 or consistently reproduce the warnings myself, and I've given up
223 trying to figure it out. Please don't report any new bugs about
224 variable warnings *unless* you can tell me how to consistently
225 reproduce them starting from `emacs -Q`. If you are an Emacs expert
226 who knows how to fix these warnings, please let me know.
239227
240228 You can see the bug reports about weird warnings
241229 [here](https://github.com/DarwinAwardWinner/ido-ubiquitous/issues?utf8=%E2%9C%93&q=label%3Abizarre-unexplainable-scoping-issues+).
244232
245233 All users should just use the master branch, or better yet, install
246234 from MELPA. The bleeding-edge branch is where I test experimental and
247 unfinished features. Because ido-ubiquitous hooks deeply into the
248 bowels of Emacs, a bug in ido-ubiquitous could easily freeze or crash
249 Emacs entirely. Additionally, some bug only show up when
250 ido-ubiquitous is installed and compiled as a package. So I test every
251 new feature myself for some time on this branch before pushing to the
252 master branch. If you report a bug, I might develop a fix for it on
253 the bleeding edge branch and ask then you to try this branch.
235 unfinished features. Because ido-completing-read+ hooks deeply into
236 the bowels of Emacs, a bug in ido-completing-read+ could easily freeze
237 or crash Emacs entirely. Additionally, some bug only show up when
238 ido-completing-read+ is installed and compiled as a package. So I test
239 every new feature myself for some time on this branch before pushing
240 to the master branch. If you report a bug, I might develop a fix for
241 it on the bleeding edge branch and ask then you to try this branch.
254242 Otherwise, normal users don't need to think about this branch.
255243
256 # ido-completing-read+ #
257
258 As of version 3.0, most of the core functionality of ido-ubiquitous
259 has been spun off into a separate library called ido-completing-read+,
260 or "ido-cr+" for short. ido-cr+ incorporates all the features of
261 ido-ubiquitous that are actually just generic improvements to ido that
262 should probably always be enabled. It implements these fixes in a
263 single function `ido-completing-read+`, which should be suitable as a
264 drop-in replacement for either `ido-completing-read` or
265 `completing-read`. Notably, unlike the original `ido-completing-read`,
266 `ido-completing-read+` should always do something useful, by falling
267 back to normal completion when ido completion won't work.
268 Additionally, it allows you to manually fall back using C-f and C-b,
269 in the same way you can use those keys to switch between file and
270 buffer completion in ido. As a user, you don't really need to know
271 anything about ido-cr+. However, if you are writing an Emacs package
272 and would like to incorporate ido completion, you may wish to use
273 ido-cr+ to get more robust completion with fewer weird edge cases.
244 ## Running the tests
245
246 This package comes with a test suite. If you want to run it yourself,
247 first install the [cask](http://cask.readthedocs.io/en/latest/)
248 dependency manager. Then, from the package directory, run `cask
249 install` to install all the development dependencies, in
250 particular
251 [buttercup](https://github.com/jorgenschaefer/emacs-buttercup).
252 Finally, to run the tests, execute `cask exec buttercup -L .`. Please
253 run this test suite before submitting any pull requests, and note in
254 the pull request whether any of the tests fail.
00 ;;; ido-completing-read+.el --- A completing-read-function using ido -*- lexical-binding: t -*-
11
2 ;; Copyright (C) 2015 Ryan C. Thompson
2 ;; Copyright (C) 2011-2017 Ryan C. Thompson
33
44 ;; Filename: ido-completing-read+.el
55 ;; Author: Ryan Thompson
66 ;; Created: Sat Apr 4 13:41:20 2015 (-0700)
7 ;; Version: 3.16
8 ;; Package-Requires: ((emacs "24.1") (cl-lib "0.5"))
9 ;; URL: https://github.com/DarwinAwardWinner/ido-ubiquitous
7 ;; Version: 4.5
8 ;; Package-Requires: ((emacs "24.4") (cl-lib "0.5") (s "0.1") (memoize "1.1"))
9 ;; URL: https://github.com/DarwinAwardWinner/ido-completing-read-plus
1010 ;; Keywords: ido, completion, convenience
1111
1212 ;; This file is NOT part of GNU Emacs.
1414 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1515 ;;
1616 ;;; Commentary:
17
18 ;; If you use the excellent `ido-mode' for efficient completion of
19 ;; file names and buffers, you might wonder if you can get ido-style
20 ;; completion everywhere else too. Well, that's what this package
21 ;; does! ido-ubiquitous is here to enable ido-style completion for
22 ;; (almost) every function that uses the standard completion function
23 ;; `completing-read'.
1724
1825 ;; This package implements the `ido-completing-read+' function, which
1926 ;; is a wrapper for `ido-completing-read'. Importantly, it detects
2027 ;; edge cases that ordinary ido cannot handle and either adjusts them
2128 ;; so ido *can* handle them, or else simply falls back to Emacs'
22 ;; standard completion instead.
29 ;; standard completion instead. Hence, you can safely set
30 ;; `completing-read-function' to `ido-completing-read+' without
31 ;; worrying about breaking completion features that are incompatible
32 ;; with ido.
33
34 ;; To use this package, call `ido-ubiquitous-mode' to enable the mode,
35 ;; or use `M-x customize-variable ido-ubiquitous-mode' it to enable it
36 ;; permanently. Once the mode is enabled, most functions that use
37 ;; `completing-read' will now have ido completion. If you decide in
38 ;; the middle of a command that you would rather not use ido, just use
39 ;; C-f or C-b at the end/beginning of the input to fall back to
40 ;; non-ido completion (this is the same shortcut as when using ido for
41 ;; buffers or files).
42
43 ;; Note that `completing-read-default' is a very general function with
44 ;; many complex behaviors that ido cannot emulate. This package
45 ;; attempts to detect some of these cases and avoid using ido when it
46 ;; sees them. So some functions will not have ido completion even when
47 ;; this mode is enabled. Some other functions have ido disabled in
48 ;; them because their packages already provide support for ido via
49 ;; other means (for example, magit). See `M-x describe-variable
50 ;; ido-cr+-function-blacklist' for more information.
51
52 ;; ido-completing-read+ version 4.0 is a major update. The formerly
53 ;; separate package ido-ubiquitous has been subsumed into
54 ;; ido-completing-read+, so ido-ubiquitous 4.0 is just a wrapper that
55 ;; loads ido-completing-read+ and displays a warning about being
56 ;; obsolete. If you have previously customized ido-ubiquitous, be sure
57 ;; to check out `M-x customize-group ido-completing-read-plus' after
58 ;; updating to 4.0 and make sure the new settings are to your liking.
2359
2460 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2561 ;;
4076 ;;
4177 ;;; Code:
4278
43 (defconst ido-completing-read+-version "3.16"
44 "Currently running version of ido-ubiquitous.
79 (defconst ido-completing-read+-version "4.5"
80 "Currently running version of ido-completing-read+.
4581
4682 Note that when you update ido-completing-read+, this variable may
4783 not be updated until you restart Emacs.")
4884
4985 (require 'ido)
5086 (require 'cl-lib)
87 (require 'cus-edit)
88 (require 's)
89 (require 'memoize)
5190
5291 ;;; Debug messages
5392
5998 :global t
6099 :group 'ido-completing-read-plus)
61100
62 (defun ido-cr+--debug-message (format-string &rest args)
101 (defsubst ido-cr+--debug-message (format-string &rest args)
63102 (when ido-cr+-debug-mode
64103 (apply #'message (concat "ido-completing-read+: " format-string) args)))
65104
66 ;;; Core code
105 ;;; Ido variables
106
107 ;; For unknown reasons, these variables need to be re-declared here to
108 ;; silence byte-compiler warnings, despite already being declared in
109 ;; ido.el.
110
111 (defmacro define-ido-internal-var (symbol &optional initvalue docstring)
112 "Declare and initialize an ido internal variable.
113
114 This is used to suppress byte-compilation warnings about
115 reference to free variables when ido-cr+ attempts to access
116 internal ido variables with no initial value set. Such variables
117 are originally declared like `(defvar VARNAME)'.
118
119 This is a wrapper for `defvar' that supplies a default for the
120 INITVALUE and DOCSTRING arguments."
121 `(defvar ,symbol ,initvalue
122 ,(or docstring
123 "Internal ido variable.
124
125 This variable was originally declared in `ido.el' without an
126 initial value or docstring. The documentation you're reading
127 comes from re-declaring it in `ido-completing-read+.el' in order
128 to suppress some byte-compilation warnings. Setting another
129 package's variable is not safe in general, but in this case it
130 should be, because ido always let-binds this variable before
131 using it, so the initial value shouldn't matter.")))
132
133 (define-ido-internal-var ido-context-switch-command)
134 (define-ido-internal-var ido-cur-list)
135 (define-ido-internal-var ido-cur-item)
136 (define-ido-internal-var ido-require-match)
137 (define-ido-internal-var ido-process-ignore-lists)
67138
68139 ;;;###autoload
69 (defvar ido-cr+-enable-next-call nil
70 "If non-nil, then the next call to `ido-completing-read' is by `ido-completing-read+'.")
71 ;;;###autoload
72 (defvar ido-cr+-enable-this-call nil
73 "If non-nil, then the current call to `ido-completing-read' is by `ido-completing-read+'")
140 (defvar ido-cr+-minibuffer-depth -1
141 "Minibuffer depth of the most recent ido-cr+ activation.
142
143 If this equals the current minibuffer depth, then the minibuffer
144 is currently being used by ido-cr+, and ido-cr+ feature will be
145 active. Otherwise, something else is using the minibuffer and
146 ido-cr+ features will be deactivated to avoid interfering with
147 the other command.
148
149 This is set to -1 by default, since `(minibuffer-depth)' should
150 never return this value.")
151
152 (defvar ido-cr+-assume-static-collection nil
153 "If non-nil, ido-cr+ will assume that the collection is static.
154
155 This is used to avoid unnecessary work in the case where the
156 collection is a function, since a function collection could
157 potentially change the set of completion candidates
158 dynamically.")
159
160 (defvar ido-cr+-current-command nil
161 "Command most recently invoked by `call-interactively'.
162
163 This is necessary because `command-execute' and
164 `call-interactively' do not set `this-command'. Instead, the C
165 code that calls `command-execute' sets it beforehand, so using
166 either of those functions directly won't set `this-command'.")
167
168 (defvar ido-cr+-dynamic-collection nil
169 "Stores the collection argument if it is a function.
170
171 This allows ido-cr+ to update the set of completion candidates
172 dynamically.")
173
174 (defvar ido-cr+-previous-dynamic-update-texts nil
175 "Values of `ido-text' for the last few dynamic collection updates.
176
177 This is used in `ido-cr+-update-dynamic-collection' as an LRU
178 cache of recent values of `ido-text' in order to skip re-checking
179 prefixes of these strings.")
180
181 (defvar ido-cr+-dynamic-update-idle-time 0.25
182 "Time to wait before updating dynamic completion list.")
183
184 (defvar ido-cr+-dynamic-update-timer nil
185 "Idle timer for updating dynamic completion list.")
186
187 (defvar ido-cr+-exhibit-pending nil
188 "This is non-nil after calling `ido-tidy' until the next call to `ido-exhibit'.
189
190 Typically this is non-nil while any command is running and nil at all
191 other times, since those two functions are in `pre-command-hook'
192 and `post-command-hook' respectively. In particular, this will
193 generally be nil while running an idle timer.")
194
195 (make-obsolete-variable
196 'ido-cr+-no-default-action
197 " This variable no longer has any effect. Customize `ido-cr+-nil-def-alternate-behavior-list' instead."
198 "4.2")
199
200 (defvar ido-cr+-orig-completing-read-args nil
201 "Original arguments passed to `ido-completing-read+'.
202
203 These are used for falling back to `completing-read-default'.")
204
205 (defvar ido-cr+-all-completions-memoized nil
206 "Memoized version of `all-completions'.
207
208 During completion with dynamic collection, this variable is set
209 to a memoized copy of `all-completions'.")
210
211 (defvar ido-cr+-all-prefix-completions-memoized nil
212 "Memoized version of `ido-cr+-all-prefix-completions'.
213
214 During completion with dynamic collection, this variable is set
215 to a memoized copy of `ido-cr+-all-prefix-completions'.")
216
217 (defvar ido-cr+-active-restrictions nil
218 "List of restrictions in place from `ido-restrict-to-matches'.
219
220 Each element is a cons cell of (REMOVEP . TEXT), where REMOVEP is
221 the prefix argument to `ido-restrict-to-matches' and TEXT is the
222 pattern used to restrict.")
74223
75224 (defgroup ido-completing-read-plus nil
76225 "Extra features and compatibility for `ido-completing-read'."
120269 widget)))))
121270 :group 'ido-completing-read-plus)
122271
272 (defcustom ido-cr+-function-blacklist
273 '(read-file-name-internal
274 read-buffer
275 ;; https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues/60
276 todo-add-category
277 ;; Gnus already supports ido on its own
278 gnus-emacs-completing-read
279 gnus-iswitchb-completing-read
280 grep-read-files
281 ;; Magit already supports ido on its own
282 magit-builtin-completing-read
283 ;; ESS already supports ido on its own
284 ess-completing-read
285 ;; https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues/39
286 Info-read-node-name
287 ;; https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues/44
288 tmm-prompt)
289 "Functions & commands for which ido-cr+ should be disabled.
290
291 Each entry can be either a symbol or a string. A symbol means to
292 fall back specifically for the named function. A regular
293 expression means to fall back for any function whose name matches
294 that regular expression. When ido-cr+ is called through
295 `completing-read', if any function in the call stack of the
296 current command matches any of the blacklist entries, ido-cr+
297 will be disabled for that command. Additionally, if the
298 collection in the call to `completing-read' matches any of the
299 blacklist entries, ido-cr+ will be disabled.
300
301 Note that using specific function names is generally preferable
302 to regular expressions, because the associated function
303 definitions will be compared directly, so if the same function is
304 called by another name, it should still trigger the fallback. For
305 regular expressions, only name-based matching is possible."
306 :group 'ido-completing-read-plus
307 :type '(repeat (choice (symbol :tag "Function or command name")
308 (string :tag "Regexp"))))
309
310 (defcustom ido-cr+-function-whitelist
311 nil
312 "Functions & commands for which ido-cr+ should be enabled.
313
314 If this variable is nil, the whitelist will not be used, and
315 ido-cr+ will be allowed in all functions/commands not listed in
316 `ido-cr+-function-backlist'.
317
318 If this variable is non-nil, ido-cr+'s whitelisting mode will be
319 enabled, and ido-cr+ will be disabled for *all* functions unless
320 they match one of the entries. Matching is done in the same
321 manner as `ido-cr+-function-blacklist', and blacklisting takes
322 precedence over whitelisting."
323 :group 'ido-completing-read-plus
324 :type '(repeat (choice (symbol :tag "Function or command name")
325 (string :tag "Regexp"))))
326
327 (defcustom ido-cr+-nil-def-alternate-behavior-list
328 '("\\`describe-\\(function\\|variable\\)\\'"
329 "\\`wl-"
330 ;; https://github.com/mrkkrp/ebal/issues/12
331 "\\`ebal-"
332 ;; https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues/4
333 webjump
334 ;; https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues/83
335 where-is
336 ;; https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues/51
337 find-tag
338 ;; https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues/89
339 "\\`etags-select-"
340 ;; https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues/58
341 imenu--completion-buffer
342 ;; https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues/116
343 project--completing-read-strict
344 ;; https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues/127#issuecomment-319463217
345 bookmark-completing-read
346 )
347 "Functions & commands with alternate behavior when DEF is nil.
348
349 This variable has the same format as
350 `ido-cr+-function-blacklist'. When `ido-completing-read+` is
351 called through `completing-read' by/with any command, function,
352 or collection matched by entries in this list, it will behave
353 differently when DEF is nil. Instead of using the empty string as
354 the default value, it will use the first element of COLLECTION.
355
356 This is needed for optimal compatibility with commands written
357 under the assumption that REQUIRE-MATCH means that a match is
358 required."
359 :group 'ido-completing-read-plus
360 :type '(repeat (choice (symbol :tag "Function or command name")
361 (string :tag "Regexp"))))
362
363 (defvaralias 'ido-cr+-nil-def-wall-of-shame 'ido-cr+-nil-def-alternate-behavior-list
364 "Functions and commands whose authors need to read the docstring for `completing-read'.
365
366 Many functions that call `completing-read' are written with the
367 assumption that the setting the REQUIRE-MATCH argument of
368 `completing-read' to t means it is required to return a match.
369 While that would make logical sense, it's wrong. the docstring
370 for `completing-read' describes the correct behavior.
371
372 > If the input is null, ‘completing-read’ returns DEF, or the
373 > first element of the list of default values, or an empty string
374 > if DEF is nil, regardless of the value of REQUIRE-MATCH.
375
376 This can be avoided by passing an element of COLLECTION as DEF
377 instead of leaving it as nil.")
378
123379 ;;;###autoload
124380 (defcustom ido-cr+-replace-completely nil
125381 "If non-nil, replace `ido-completeing-read' completely with ido-cr+.
127383 Enabling this may interfere with or cause errors in other
128384 packages that use `ido-completing-read'. If you discover any such
129385 incompatibilities, please file a bug report at
130 https://github.com/DarwinAwardWinner/ido-ubiquitous/issues"
386 https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues"
131387 :type 'boolean)
132388
133389 ;; Signal used to trigger fallback
134 (put 'ido-cr+-fallback 'error-conditions '(ido-cr+-fallback error))
135 (put 'ido-cr+-fallback 'error-message "ido-cr+-fallback")
136
137 (defun ido-cr+--explain-fallback (arg)
390 (define-error 'ido-cr+-fallback "ido-cr+-fallback")
391
392 (defsubst ido-cr+--explain-fallback (arg)
138393 ;; This function accepts a string, or an ido-cr+-fallback
139394 ;; signal.
140395 (when ido-cr+-debug-mode
145400 ido-cr+-fallback-function arg)))
146401
147402 ;;;###autoload
403 (defsubst ido-cr+-active ()
404 "Returns non-nil if ido-cr+ is currently using the minibuffer."
405 (>= ido-cr+-minibuffer-depth (minibuffer-depth)))
406
407 (defsubst ido-cr+-default-was-provided ()
408 "Returns non-nil if ido-cr+ was passed a non-nil default argument."
409 (and (nth 6 ido-cr+-orig-completing-read-args)))
410
411 (defun ido-cr+--called-from-completing-read ()
412 "Returns non-nil if the most recent call to ido-cr+ was from `completing-read'."
413 (equal (cadr (backtrace-frame 1 'ido-completing-read+))
414 'completing-read))
415
416 (defmacro ido-cr+-function-is-in-list (fun fun-list &optional list-name)
417 "Return non-nil if FUN matches an entry in FUN-LIST.
418
419 This is used to check for matches to `ido-cr+-function-blacklist'
420 and `ido-cr+-function-whitelist'. Read those docstrings to see
421 how the matching is done.
422
423 This is declared as macro only in order to extract the variable
424 name used for the second argument so it can be used in a debug
425 message. It should be called as if it were a normal function."
426 (when (null list-name)
427 (if (symbolp fun-list)
428 (setq list-name (symbol-name fun-list))
429 (setq list-name "list")))
430 `(cl-loop
431 for entry in ,fun-list
432 if (cond
433 ;; Nil: Never matches anything
434 ((null entry)
435 nil)
436 ;; Symbol: Compare names and function definitions
437 ((symbolp entry)
438 (or (eq entry ,fun)
439 (let ((entry-def (ignore-errors (indirect-function entry)))
440 (fun-def (ignore-errors (indirect-function ,fun))))
441 (and
442 fun-def entry-def
443 (eq
444 (indirect-function entry-def)
445 (indirect-function fun-def))))))
446 ;; String: Do regexp matching against function name if it is a
447 ;; symbol
448 ((stringp entry)
449 (and (symbolp ,fun)
450 (string-match-p entry (symbol-name ,fun))))
451 ;; Anything else: invalid blacklist entry
452 (t
453 (ido-cr+--debug-message "Ignoring invalid entry in %s: `%S'" ,list-name entry)
454 nil))
455 return entry
456 ;; If no blacklist entry matches, return nil
457 finally return nil))
458
459 (defun ido-cr+-function-is-blacklisted (fun)
460 "Return non-nil if FUN is blacklisted.
461
462 See `ido-cr+-function-blacklist'."
463 (ido-cr+-function-is-in-list fun ido-cr+-function-blacklist))
464
465 (defun ido-cr+-function-is-whitelisted (fun)
466 "Return non-nil if FUN is whitelisted.
467
468 See `ido-cr+-function-whitelist'."
469 (or (null ido-cr+-function-whitelist)
470 (ido-cr+-function-is-in-list fun ido-cr+-function-whitelist)))
471
472 ;;;###autoload
148473 (defun ido-completing-read+ (prompt collection &optional predicate
149474 require-match initial-input
150475 hist def inherit-input-method)
156481 be used as the value of `completing-read-function'. Importantly,
157482 it detects edge cases that ido cannot handle and uses normal
158483 completion for them."
159 (let (;; Save the original arguments in case we need to do the
160 ;; fallback
161 (orig-args
162 (list prompt collection predicate require-match
163 initial-input hist def inherit-input-method)))
484 (let* (;; Save the original arguments in case we need to do the
485 ;; fallback
486 (ido-cr+-orig-completing-read-args
487 (list prompt collection predicate require-match
488 initial-input hist def inherit-input-method))
489 ;; Need to save this since activating the minibuffer once will
490 ;; clear out any temporary minibuffer hooks, which need to get
491 ;; restored before falling back.
492 (orig-minibuffer-setup-hook minibuffer-setup-hook)
493 ;; Need just the string part of INITIAL-INPUT
494 (initial-input-string
495 (cond
496 ((consp initial-input)
497 (car initial-input))
498 ((stringp initial-input)
499 initial-input)
500 ((null initial-input)
501 "")
502 (t
503 (signal 'wrong-type-argument (list 'stringp initial-input)))))
504 (ido-cr+-active-restrictions nil)
505 ;; If collection is a function, save it for later, unless
506 ;; instructed not to
507 (ido-cr+-dynamic-collection
508 (when (and (not ido-cr+-assume-static-collection)
509 (functionp collection))
510 collection))
511 ;; Only memoize if the collection is dynamic.
512 (ido-cr+-all-prefix-completions-memoized
513 (if ido-cr+-dynamic-collection
514 (memoize (indirect-function 'ido-cr+-all-prefix-completions))
515 'ido-cr+-all-prefix-completions))
516 (ido-cr+-all-completions-memoized
517 (if ido-cr+-dynamic-collection
518 (memoize (indirect-function 'all-completions))
519 'all-completions))
520 ;; If the whitelist is empty, everything is whitelisted
521 (whitelisted (not ido-cr+-function-whitelist))
522 ;; If non-nil, we need alternate nil DEF handling
523 (alt-nil-def nil))
164524 (condition-case sig
165525 (progn
166 (cond
167 (inherit-input-method
526 ;; Check a bunch of fallback conditions
527 (when inherit-input-method
168528 (signal 'ido-cr+-fallback
169529 '("ido cannot handle non-nil INHERIT-INPUT-METHOD")))
170 ((bound-and-true-p completion-extra-properties)
530 (when (bound-and-true-p completion-extra-properties)
171531 (signal 'ido-cr+-fallback
172532 '("ido cannot handle non-nil `completion-extra-properties'")))
173 ((functionp collection)
174 (signal 'ido-cr+-fallback
175 '("ido cannot handle COLLECTION being a function"))))
176 ;; Expand all possible completions
177 (setq collection (all-completions "" collection predicate))
533
534 ;; Check for black/white-listed collection function
535 (when (functionp collection)
536 ;; Blacklist
537 (when (ido-cr+-function-is-blacklisted collection)
538 (if (symbolp collection)
539 (signal 'ido-cr+-fallback
540 (list (format "collection function `%S' is blacklisted" collection)))
541 (signal 'ido-cr+-fallback
542 (list "collection function is blacklisted"))))
543 ;; Whitelist
544 (when (and (not whitelisted)
545 (ido-cr+-function-is-whitelisted collection))
546 (ido-cr+--debug-message
547 (if (symbolp collection)
548 (format "Collection function `%S' is whitelisted" collection)
549 "Collection function is whitelisted"))
550 (setq whitelisted t))
551 ;; nil DEF list
552 (when (and
553 require-match (null def)
554 (ido-cr+-function-is-in-list
555 collection
556 ido-cr+-nil-def-alternate-behavior-list))
557 (ido-cr+--debug-message
558 (if (symbolp collection)
559 (format "Using alternate nil DEF handling for collection function `%S'" collection)
560 "Using alternate nil DEF handling for collection function"))
561 (setq alt-nil-def t)))
562
563 ;; Expand all currently-known completions.
564 (setq collection
565 (if ido-cr+-dynamic-collection
566 (funcall ido-cr+-all-prefix-completions-memoized
567 initial-input-string collection predicate)
568 (all-completions "" collection predicate)))
569 ;; No point in using ido unless there's a collection
570 (when (and (= (length collection) 0)
571 (not ido-cr+-dynamic-collection))
572 (signal 'ido-cr+-fallback '("ido is not needed for an empty collection")))
178573 ;; Check for excessively large collection
179574 (when (and ido-cr+-max-items
180575 (> (length collection) ido-cr+-max-items))
183578 (format
184579 "there are more than %i items in COLLECTION (see `ido-cr+-max-items')"
185580 ido-cr+-max-items))))
186 ;; ido doesn't natively handle DEF being a list. If DEF is a
187 ;; list, prepend it to COLLECTION and set DEF to just the
188 ;; car of the default list.
189 (when (and def (listp def))
190 (setq collection
191 (append def
192 (nreverse (cl-set-difference collection def)))
193 def (car def)))
194 ;; Work around a bug in ido when both INITIAL-INPUT and
195 ;; DEF are provided.
196 (let ((initial
197 (or (if (consp initial-input)
198 (car initial-input)
199 initial-input)
200 "")))
201 (when (and def initial
202 (stringp initial)
203 (not (string= initial "")))
204 ;; Both default and initial input were provided. So keep
205 ;; the initial input and preprocess the collection list
206 ;; to put the default at the head, then proceed with
207 ;; default = nil.
208 (setq collection (cons def (remove def collection))
209 def nil)))
210 ;; Ready to do actual ido completion
581
582 ;; If called from `completing-read', check for
583 ;; black/white-listed commands/callers
584 (when (ido-cr+--called-from-completing-read)
585 ;; Check calling command and `ido-cr+-current-command'
586 (cl-loop
587 for cmd in (list this-command ido-cr+-current-command)
588
589 if (ido-cr+-function-is-blacklisted cmd)
590 do (signal 'ido-cr+-fallback
591 (list "calling command `%S' is blacklisted" cmd))
592
593 if (and (not whitelisted)
594 (ido-cr+-function-is-whitelisted cmd))
595 do (progn
596 (ido-cr+--debug-message "Command `%S' is whitelisted" cmd)
597 (setq whitelisted t))
598
599 if (and
600 require-match (null def) (not alt-nil-def)
601 (ido-cr+-function-is-in-list
602 cmd ido-cr+-nil-def-alternate-behavior-list))
603 do (progn
604 (ido-cr+--debug-message
605 "Using alternate nil DEF handling for command `%S'" cmd)
606 (setq alt-nil-def t)))
607
608 ;; Check every function in the call stack starting after
609 ;; `completing-read' until to the first
610 ;; `funcall-interactively' (for a call from the function
611 ;; body) or `call-interactively' (for a call from the
612 ;; interactive form, in which the function hasn't actually
613 ;; been called yet, so `funcall-interactively' won't be on
614 ;; the stack.)
615 (cl-loop for i upfrom 1
616 for caller = (cadr (backtrace-frame i 'completing-read))
617 while caller
618 while (not (memq (indirect-function caller)
619 '(internal--funcall-interactively
620 (indirect-function 'call-interactively))))
621
622 if (ido-cr+-function-is-blacklisted caller)
623 do (signal 'ido-cr+-fallback
624 (list (if (symbolp caller)
625 (format "calling function `%S' is blacklisted" caller)
626 "a calling function is blacklisted")))
627
628 if (and (not whitelisted)
629 (ido-cr+-function-is-whitelisted caller))
630 do (progn
631 (ido-cr+--debug-message
632 (if (symbolp caller)
633 (format "Calling function `%S' is whitelisted" caller)
634 "A calling function is whitelisted"))
635 (setq whitelisted t))
636
637 if (and require-match (null def) (not alt-nil-def)
638 (ido-cr+-function-is-in-list
639 caller ido-cr+-nil-def-alternate-behavior-list))
640 do (progn
641 (ido-cr+--debug-message
642 (if (symbolp caller)
643 (format "Using alternate nil DEF handling for calling function `%S'" caller)
644 "Using alternate nil DEF handling for a calling function"))
645 (setq alt-nil-def t))))
646
647 (unless whitelisted
648 (signal 'ido-cr+-fallback
649 (list "no functions or commands matched the whitelist for this call")))
650
651 (when (and require-match (null def))
652 ;; Replace nil with "" for DEF if match is required, unless
653 ;; alternate nil DEF handling is enabled
654 (if alt-nil-def
655 (ido-cr+--debug-message
656 "Leaving the default at nil because alternate nil DEF handling is enabled.")
657 (ido-cr+--debug-message
658 "Adding \"\" as the default completion since no default was provided.")
659 (setq def (list ""))))
660
661 ;; In ido, the semantics of "default" are simply "put it at
662 ;; the front of the list". Furthermore, ido can't handle a
663 ;; list of defaults, nor can it handle both DEF and
664 ;; INITIAL-INPUT being non-nil. So, just pre-process the
665 ;; collection to put the default(s) at the front and then
666 ;; set DEF to nil in the call to ido to avoid these issues.
667 (unless (listp def)
668 ;; Ensure DEF is a list
669 (setq def (list def)))
670 (when def
671 ;; Ensure DEF are strings
672 (setq def (mapcar (apply-partially #'format "%s") def))
673 ;; Prepend DEF to COLLECTION and remove duplicates
674 (setq collection (delete-dups (append def collection))
675 def nil))
676
677 ;; Check for a specific bug
678 (when (and ido-enable-dot-prefix
679 (version< emacs-version "26.1")
680 (member "" collection))
681 (signal 'ido-cr+-fallback
682 '("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")))
683
684 ;; Fix ido handling of cons-style INITIAL-INPUT. TODO add a
685 ;; version check after this bug is fixed:
686 ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27807
687 (when (consp initial-input)
688 ;; `completing-read' uses 0-based index while
689 ;; `read-from-minibuffer' uses 1-based index.
690 (cl-incf (cdr initial-input)))
691
692 ;; Finally ready to do actual ido completion
211693 (prog1
212 (let ((ido-cr+-enable-next-call t))
213 (ido-completing-read
214 prompt collection
215 predicate require-match initial-input hist def
216 inherit-input-method))
694 (let ((ido-cr+-minibuffer-depth (1+ (minibuffer-depth)))
695 ;; Initialize dynamic update vars
696 (ido-cr+-previous-dynamic-update-texts
697 (list initial-input-string))
698 (ido-cr+-dynamic-update-timer nil)
699 (ido-cr+-exhibit-pending t)
700 ;; Reset these for the next call to ido-cr+
701 (ido-cr+-no-default-action 'prepend-empty-string)
702 (ido-cr+-assume-static-collection nil))
703 (unwind-protect
704 (ido-completing-read
705 prompt collection
706 predicate require-match initial-input hist def
707 inherit-input-method)
708 (when ido-cr+-dynamic-update-timer
709 (cancel-timer ido-cr+-dynamic-update-timer)
710 (setq ido-cr+-dynamic-update-timer nil))))
217711 ;; This detects when the user triggered fallback mode
218712 ;; manually.
219713 (when (eq ido-exit 'fallback)
220714 (signal 'ido-cr+-fallback '("user manually triggered fallback")))))
715
221716 ;; Handler for ido-cr+-fallback signal
222717 (ido-cr+-fallback
223 (ido-cr+--explain-fallback sig)
224 (apply ido-cr+-fallback-function orig-args)))))
718 (let (;; Reset `minibuffer-setup-hook' to original value
719 (minibuffer-setup-hook orig-minibuffer-setup-hook)
720 ;; Reset these for the next call to ido-cr+
721 (ido-cr+-no-default-action 'prepend-empty-string)
722 (ido-cr+-assume-static-collection nil))
723 (ido-cr+--explain-fallback sig)
724 (apply ido-cr+-fallback-function ido-cr+-orig-completing-read-args))))))
225725
226726 ;;;###autoload
227 (defadvice ido-completing-read (around ido-cr+ activate)
228 "This advice handles application of ido-completing-read+ features.
229
230 First, it ensures that `ido-cr+-enable-this-call' is set
231 properly. This variable should be non-nil during execution of
232 `ido-completing-read' if it was called from
233 `ido-completing-read+'.
234
235 Second, if `ido-cr+-replace-completely' is non-nil, then this
236 advice completely replaces `ido-completing-read' with
237 `ido-completing-read+'."
727 (defun ido-completing-read@ido-cr+-replace (orig-fun &rest args)
728 "This advice allows ido-cr+ to completely replace `ido-completing-read'.
729
730 See the varaible `ido-cr+-replace-completely' for more information."
238731 ;; If this advice is autoloaded, then we need to force loading of
239732 ;; the rest of the file so all the variables will be defined.
240733 (when (not (featurep 'ido-completing-read+))
241734 (require 'ido-completing-read+))
242 (let ((ido-cr+-enable-this-call ido-cr+-enable-next-call)
243 (ido-cr+-enable-next-call nil))
244 (if (or
245 ido-cr+-enable-this-call ; Avoid recursion
246 (not ido-cr+-replace-completely))
247 ad-do-it
248 (message "Replacing ido-completing-read")
249 (setq ad-return-value (apply #'ido-completing-read+ (ad-get-args 0))))))
735 (if (or (ido-cr+-active)
736 (not ido-cr+-replace-completely))
737 ;; ido-cr+ has either already activated or isn't going to
738 ;; activate, so just run the function as normal
739 (apply orig-fun args)
740 ;; Otherwise, we need to activate ido-cr+.
741 (apply #'ido-completing-read+ args)))
742 ;;;###autoload
743 (advice-add 'ido-completing-read :around
744 #'ido-completing-read@ido-cr+-replace)
745
746 ;;;###autoload
747 (defun call-interactively@ido-cr+-record-current-command
748 (orig-fun command &rest args)
749 "Let-bind the command being interactively called.
750
751 See `ido-cr+-current-command' for more information."
752 (let ((ido-cr+-current-command command))
753 (apply orig-fun command args)))
754 ;;;###autoload
755 (advice-add 'call-interactively :around
756 #'call-interactively@ido-cr+-record-current-command)
250757
251758 ;; Fallback on magic C-f and C-b
252 ;;;###autoload
253 (defvar ido-context-switch-command nil
254 "Variable holding the command used for switching to another completion mode.
255
256 This variable is originally declared in `ido.el', but it is not
257 given a value (or a docstring). This documentation comes from a
258 re-declaration in `ido-completing-read+.el' that initializes it
259 to nil, which should suppress some byte-compilation warnings in
260 Emacs 25. Setting another package's variable is not safe in
261 general, but in this case it should be, because ido always
262 let-binds this variable before using it, so the initial value
263 shouldn't matter.")
264
265 (defadvice ido-magic-forward-char (before ido-cr+-fallback activate)
759 (defun ido-magic-forward-char@ido-cr+-fallback (&rest args)
266760 "Allow falling back in ido-completing-read+."
267 (when ido-cr+-enable-this-call
761 (when (ido-cr+-active)
268762 ;; `ido-context-switch-command' is already let-bound at this
269763 ;; point.
270764 (setq ido-context-switch-command #'ido-fallback-command)))
271
272 (defadvice ido-magic-backward-char (before ido-cr+-fallback activate)
765 (advice-add 'ido-magic-forward-char :before
766 #'ido-magic-forward-char@ido-cr+-fallback)
767
768 (defun ido-magic-backward-char@ido-cr+-fallback (&rest args)
273769 "Allow falling back in ido-completing-read+."
274 (when ido-cr+-enable-this-call
770 (when (ido-cr+-active)
275771 ;; `ido-context-switch-command' is already let-bound at this
276772 ;; point.
277773 (setq ido-context-switch-command #'ido-fallback-command)))
278
279 ;;; Workaround for https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/93
280
281 (defadvice ido-select-text (around fix-require-match-behavior activate)
774 (advice-add 'ido-magic-backward-char :before
775 #'ido-magic-backward-char@ido-cr+-fallback)
776
777 (defun ido-select-text@ido-cr+-fix-require-match (orig-fun &rest args)
282778 "Fix ido behavior when `require-match' is non-nil.
283779
284780 Standard ido will allow C-j to exit with an incomplete completion
286782 not allow this. In ordinary completion, RET on an incomplete
287783 match is equivalent to TAB, and C-j selects the first match.
288784 Since RET in ido already selects the first match, this advice
289 sets up C-j to be equivalent to TAB in the same situation."
785 sets up C-j to be equivalent to TAB in the same situation.
786
787 This advice only activates if the current ido completion was
788 called through ido-cr+."
290789 (if (and
291790 ;; Only override C-j behavior if...
292 ;; We're using ico-cr+
293 ido-cr+-enable-this-call
294 ;; Require-match is non-nil
295 (with-no-warnings ido-require-match)
296 ;; A default was provided, or ido-text is non-empty
297 (or (with-no-warnings ido-default-item)
298 (not (string= ido-text "")))
299 ;; Only if current text is not a complete choice
300 (not (member ido-text (with-no-warnings ido-cur-list))))
791 ;; We're using ico-cr+, and...
792 (ido-cr+-active)
793 ;; Require-match is non-nil, and...
794 ido-require-match
795 ;; The current input doesn't exactly match a known option, and...
796 (not (member ido-text ido-cur-list))
797 ;; The current input doesn't exactly match an option according
798 ;; to `try-completion' (or the collection is not dynamic).
799 (or (not ido-cr+-dynamic-collection)
800 (eq t (try-completion ido-text ido-cr+-dynamic-collection
801 (nth 2 ido-cr+-orig-completing-read-args)))))
301802 (progn
302803 (ido-cr+--debug-message
303804 "Overriding C-j behavior for require-match: performing completion instead of exiting with current text. (This might still exit with a match if `ido-confirm-unique-completion' is nil)")
304805 (ido-complete))
305 ad-do-it))
806 (apply orig-fun args)))
807 (advice-add 'ido-select-text :around
808 #'ido-select-text@ido-cr+-fix-require-match)
809
810 (defun ido-tidy@ido-cr+-set-exhibit-pending (&rest args)
811 (setq ido-cr+-exhibit-pending t))
812 (advice-add 'ido-tidy :after 'ido-tidy@ido-cr+-set-exhibit-pending)
813
814 (defun ido-exhibit@ido-cr+-clear-exhibit-pending (&rest args)
815 (setq ido-cr+-exhibit-pending nil))
816 (advice-add 'ido-exhibit :before 'ido-exhibit@ido-cr+-clear-exhibit-pending)
817
818 (defun ido-cr+-all-prefix-completions
819 (string collection &optional predicate)
820 "Run `all-completions' on every prefix of STRING.
821
822 Arguments COLLECTION and PREDICATE are as in `all-completions'.
823 Note that \"all prefixes\" includes both STRING itself and the
824 empty string. The return value is the union of all the returned
825 lists, with elements ordered by their first occurrence.
826
827 This function is only useful if COLLECTION is a function that
828 might return additional completions for certain non-empty strings
829 that it wouldn't return for the empty string. If COLLECTION is
830 not a function, this is equivalent to
831 `(all-completions \"\" COLELCTION PREDICATE)'."
832 (cond
833 ;; Dynamic collection.
834 ((functionp collection)
835 ;; Collect completions for all prefixes of STRING starting from
836 ;; "".
837 (cl-loop
838 for i from 0 upto (length string)
839 append (funcall
840 (or ido-cr+-all-completions-memoized
841 'all-completions)
842 (s-left i string)
843 collection
844 predicate)
845 into completion-list
846 finally return (delete-dups completion-list)))
847 ;; Otherwise, just call `all-completions' on the empty string to
848 ;; get every possible completions for a static COLLECTION.
849 (t
850 (all-completions "" collection predicate))))
851
852 (defun ido-cr+-apply-restrictions (collection restrictions)
853 "Filter COLLECTION through RESTRICTIONS in sequence.
854
855 COLLECTION is a list of strings. RESTRICTIONS is a list of cons
856 cells, with the cdr being the restriction text and the car being
857 nil to include matches for that text and t to exclude matches for
858 that text. The return value is a list of strings that satisfy all
859 the restrictions, in the same order as they appeared in
860 COLLECTION.
861
862 RESTRICTIONS are applied one by one in order, which is important
863 because in theory the order can make a difference to the final
864 result."
865 (cl-loop
866 with filtered-collection = collection
867 with need-reverse = nil
868 for (removep . text) in restrictions
869 for restriction-matches =
870 (let ((ido-text text)
871 (ido-cur-item (or ido-cur-item 'list)))
872 (ido-set-matches-1 filtered-collection t))
873 do (setq filtered-collection
874 (if removep
875 (seq-difference filtered-collection restriction-matches)
876 (setq need-reverse (not need-reverse))
877 restriction-matches))
878 ;; Each run of `ido-set-matches-1' reverses the order, so reverse
879 ;; it one more time if it had an odd number of reverses
880 finally return
881 (if need-reverse
882 (nreverse filtered-collection)
883 filtered-collection)))
884
885 (defun ido-cr+-update-dynamic-collection ()
886 "Update the set of completions for a dynamic collection.
887
888 This has no effect unless `ido-cr+-dynamic-collection' is non-nil."
889 (when (and (ido-cr+-active)
890 ido-cr+-dynamic-collection)
891 (let* ((ido-text
892 (buffer-substring-no-properties (minibuffer-prompt-end)
893 ido-eoinput))
894 (predicate (nth 2 ido-cr+-orig-completing-read-args))
895 (first-match (car ido-matches))
896 (strings-to-check
897 (cond
898 ;; If no match, then we only check `ido-text'
899 ((null first-match)
900 (list ido-text))
901 ;; If `ido-text' is a prefix of `first-match', then we
902 ;; only need to check `first-match'
903 ((and first-match
904 (s-prefix? ido-text first-match))
905 (list first-match))
906 ;; Otherwise we need to check both
907 (t
908 (list ido-text first-match))))
909 (new-completions
910 (cl-loop
911 for string in strings-to-check
912 nconc
913 (funcall
914 (or ido-cr+-all-prefix-completions-memoized
915 'ido-cr+-all-prefix-completions)
916 string ido-cr+-dynamic-collection predicate)
917 into result
918 finally return result)))
919 (when new-completions
920 (setq ido-cur-list (delete-dups new-completions))
921 (when ido-cr+-active-restrictions
922 (setq ido-cur-list (ido-cr+-apply-restrictions
923 ido-cur-list
924 ido-cr+-active-restrictions)))
925 (when (and first-match (member first-match ido-cur-list))
926 (setq ido-cur-list (ido-chop ido-cur-list first-match)))
927 (ido-cr+--debug-message
928 "Updated completion candidates for dynamic collection because `ido-text' changed to %S. `ido-cur-list' now has %s elements"
929 ido-text (length ido-cur-list))
930 ;; Recompute matches with new completions
931 (setq ido-rescan t)
932 (ido-set-matches)
933 ;; Rebuild the completion display unless ido is already planning
934 ;; to do it anyway
935 (unless ido-cr+-exhibit-pending
936 (ido-tidy)
937 (ido-exhibit)))))
938 ;; Always cancel an active timer when this function is called.
939 (when ido-cr+-dynamic-update-timer
940 (cancel-timer ido-cr+-dynamic-update-timer)
941 (setq ido-cr+-dynamic-update-timer nil)))
942
943 (defun ido-cr+-schedule-dynamic-collection-update ()
944 "Schedule a dynamic collection update for now or in the future."
945 (when (and (ido-cr+-active)
946 ido-cr+-dynamic-collection)
947 ;; Cancel the previous timer
948 (when ido-cr+-dynamic-update-timer
949 (cancel-timer ido-cr+-dynamic-update-timer)
950 (setq ido-cr+-dynamic-update-timer nil))
951 (if (<= (length ido-matches) 1)
952 ;; If we've narrowed it down to zero or one matches, update
953 ;; immediately.
954 (ido-cr+-update-dynamic-collection)
955 ;; If there are still several choices, defer update until idle
956 (setq ido-cr+-dynamic-update-timer
957 (run-with-idle-timer (max 0.01 ido-cr+-dynamic-update-idle-time) nil
958 #'ido-cr+-update-dynamic-collection)))))
959
960 (defun ido-cr+-minibuffer-setup ()
961 "set up minibuffer `post-command-hook' for ido-cr+ "
962 (when (ido-cr+-active)
963 (add-hook 'post-command-hook
964 'ido-cr+-schedule-dynamic-collection-update)))
965 (add-hook 'ido-minibuffer-setup-hook
966 'ido-cr+-minibuffer-setup)
967
968 ;; Also need to update dynamic collections on TAB, and do so *before*
969 ;; deciding to exit based on `ido-confirm-unique-completion'
970 (defun ido-complete@ido-cr+-update-dynamic-collection (oldfun &rest args)
971 "Maybe update the set of completions when pressing TAB."
972 (when ido-cr+-dynamic-collection
973 ;; First run with `ido-confirm-unique-completion' non-nil so it
974 ;; can't exit
975 (let ((ido-confirm-unique-completion t))
976 (apply oldfun args))
977 ;; Update `ido-eoinput'
978 (setq ido-eoinput (point-max))
979 ;; Now do update
980 (ido-cr+-update-dynamic-collection))
981 ;; After maybe updating the dynamic collection, if there's still
982 ;; only one completion, now it's allowed to exit
983 (apply oldfun args))
984 (advice-add 'ido-complete :around 'ido-complete@ido-cr+-update-dynamic-collection)
985
986 ;; When using `ido-restrict-to-matches', we also need to add an
987 ;; equivalent predicate to the dynamic collection so that
988 ;; dynamically-added completions are also properly restricted.
989 (defun ido-restrict-to-matches@ido-cr+-record-restriction
990 (&optional removep)
991 "Record the restriction criterion for ido-cr+"
992 (ido-cr+--debug-message "Appending restriction %S to `ido-cr+-active-restrictions'"
993 (cons removep ido-text))
994 (add-to-list 'ido-cr+-active-restrictions (cons removep ido-text) t))
995 (advice-add 'ido-restrict-to-matches :before
996 'ido-restrict-to-matches@ido-cr+-record-restriction)
997
998 ;; Interoperation with minibuffer-electric-default-mode: only show the
999 ;; default when the input is empty and the empty string is the
1000 ;; selected choice
1001 (defun minibuf-eldef-update-minibuffer@ido-cr+-compat (orig-fun &rest args)
1002 "This advice allows minibuffer-electric-default-mode to work with ido-cr+."
1003 (if (ido-cr+-active)
1004 (unless (eq minibuf-eldef-showing-default-in-prompt
1005 (and (string= (car ido-cur-list) "")
1006 (string= ido-text "")))
1007 ;; Swap state.
1008 (setq minibuf-eldef-showing-default-in-prompt
1009 (not minibuf-eldef-showing-default-in-prompt))
1010 (overlay-put minibuf-eldef-overlay 'invisible
1011 (not minibuf-eldef-showing-default-in-prompt)))
1012 (apply orig-fun args)))
1013 (advice-add 'minibuf-eldef-update-minibuffer :around
1014 #'minibuf-eldef-update-minibuffer@ido-cr+-compat)
1015
1016 ;;;###autoload
1017 (define-minor-mode ido-ubiquitous-mode
1018 "Use ido completion instead of standard completion almost everywhere.
1019
1020 If this mode causes problems for a function, you can customize
1021 when ido completion is or is not used by customizing
1022 `ido-cr+-function-blacklist'."
1023 nil
1024 :global t
1025 :group 'ido-completing-read-plus
1026 ;; Actually enable/disable the mode by setting
1027 ;; `completing-read-function'.
1028 (setq completing-read-function
1029 (if ido-ubiquitous-mode
1030 #'ido-completing-read+
1031 ido-cr+-fallback-function)))
1032
1033 (defcustom ido-cr+-auto-update-blacklist 'notify
1034 "Whether to add new overrides when updating ido-cr+.
1035
1036 This variable has 3 possible values, with the following meanings:
1037
1038 `t': Auto-update the blacklist
1039 `notify': Notify you about updates but do not apply them
1040 `nil': Ignore all blacklist updates
1041
1042 Ido-cr+ comes with a default blacklist for commands that are
1043 known to be incompatible with ido completion. New versions of
1044 ido-cr+ may come with updates to this blacklist as more
1045 incompatible commands are discovered. However, customizing your
1046 own overrides would normally prevent you from receiving these
1047 updates, since Emacs will not overwrite your customizations.
1048
1049 To resolve this problem, you can set this variable to `t', and
1050 then ido-cr+ can automatically add any new built-in overrides
1051 whenever it is updated. (Actually, the update will happen the
1052 next time Emacs is restarted after the update.) This allows you
1053 to add your own overrides but still receive updates to the
1054 default set.
1055
1056 If you want ido-cr+ to just notify you about new default
1057 overrides instead of adding them itself, set this variable to
1058 `notify'. If you don't want this auto-update behavior at all, set
1059 it to `nil'.
1060
1061 (Note that having this option enabled effectively prevents you
1062 from removing any of the built-in default blacklist entries,
1063 since they will simply be re-added the next time Emacs starts.)"
1064 :type '(choice :tag "When new overrides are available:"
1065 (const :menu-tag "Auto-add"
1066 :tag "Add them automatically"
1067 t)
1068 (const :menu-tag "Notify"
1069 :tag "Notify me about them"
1070 notify)
1071 (const :menu-tag "Ignore"
1072 :tag "Ignore them"
1073 nil))
1074 :group 'ido-completing-read-plus)
1075
1076 (defun ido-cr+-update-blacklist (&optional save quiet)
1077 "Re-add any missing default blacklist entries.
1078
1079 This is useful after an update of ido-ubiquitous that adds new
1080 default overrides. See `ido-cr+-auto-update-blacklist' for more
1081 information.
1082
1083 If SAVE is non-nil, also save the new blacklist to the user's
1084 Custom file (but only if it was already customized beforehand).
1085 When called interactively, a prefix argument triggers a save.
1086
1087 When called from Lisp code, this function returns non-nil if the
1088 blacklist was modified."
1089 (interactive "P")
1090 (let* ((var-state (custom-variable-state 'ido-cr+-function-blacklist
1091 ido-cr+-function-blacklist))
1092 (curval ido-cr+-function-blacklist)
1093 (defval (eval (car (get 'ido-cr+-function-blacklist 'standard-value))))
1094 (newval (delete-dups (append defval curval)))
1095 (new-entries (cl-set-difference defval curval :test #'equal))
1096 (modified nil)
1097 (saved nil)
1098 (message-lines ()))
1099 (cl-case var-state
1100 (standard
1101 ;; Var is not customized, just set the new default
1102 (ido-cr+--debug-message "Blacklist was not customized, so it has been updated to the new default value.")
1103 (setq ido-cr+-function-blacklist defval
1104 modified new-entries))
1105 ((saved set changed)
1106 ;; Var has been customized and saved by the user, so set the
1107 ;; new value and maybe save it
1108 (ido-cr+--debug-message "Updating user-customized blacklist with new default entries.")
1109 (setq ido-cr+-function-blacklist newval
1110 modified t)
1111 (when (and save (eq var-state 'saved))
1112 (ido-cr+--debug-message "Saving new blacklist value to Custom file.")
1113 (customize-save-variable 'ido-cr+-function-blacklist ido-cr+-function-blacklist)
1114 (setq saved t)))
1115 (otherwise
1116 (ido-cr+--debug-message "Customization status of blacklist is unknown. Not modifying it.")))
1117 (if (and modified (not quiet))
1118 (progn
1119 (push (format "Added the following entries to `ido-cr+-function-blacklist': %S" new-entries)
1120 message-lines)
1121 (if saved
1122 (push "Saved the new value of `ido-cr+-function-blacklist' to your Custom file."
1123 message-lines)
1124 (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'."
1125 message-lines)))
1126 (push "No updates were required to `ido-cr+-function-blacklist'." message-lines))
1127 (unless quiet
1128 (message (mapconcat #'identity (nreverse message-lines) "\n")))
1129 modified))
1130
1131 (defun ido-cr+-maybe-update-blacklist ()
1132 "Maybe call `ico-cr+-update-blacklist.
1133
1134 See `ido-cr+-auto-update-blacklist' for more information."
1135 (if ido-cr+-auto-update-blacklist
1136 (let* ((curval ido-cr+-function-blacklist)
1137 (defval (eval (car (get 'ido-cr+-function-blacklist 'standard-value))))
1138 (new-entries (cl-set-difference curval defval :test #'equal)))
1139 (if new-entries
1140 (if (eq ido-cr+-auto-update-blacklist 'notify)
1141 (display-warning 'ido-completing-read+ "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.)")
1142 (ido-cr+--debug-message "Initiating blacklist update.")
1143 (ido-cr+-update-blacklist t))
1144 (ido-cr+--debug-message "No blacklist updates available.")))
1145 (ido-cr+--debug-message "Skipping blacklist update by user request.")))
1146
1147 (ido-cr+-maybe-update-blacklist)
3061148
3071149 (provide 'ido-completing-read+)
3081150
00 ;;; ido-ubiquitous.el --- Use ido (nearly) everywhere. -*- lexical-binding: t -*-
11
2 ;; Copyright (C) 2011-2015 Ryan C. Thompson
2 ;; Copyright (C) 2011-2017 Ryan C. Thompson
33
44 ;; Author: Ryan C. Thompson
55 ;; URL: https://github.com/DarwinAwardWinner/ido-ubiquitous
6 ;; Version: 3.16
6 ;; Version: 4.5
77 ;; Created: 2011-09-01
88 ;; Keywords: convenience, completion, ido
99 ;; EmacsWiki: InteractivelyDoThings
10 ;; Package-Requires: ((emacs "24.1") (ido-completing-read+ "3.16") (cl-lib "0.5"))
10 ;; Package-Requires: ((emacs "24.1") (ido-completing-read+ "4.5") (cl-lib "0.5"))
1111 ;; Filename: ido-ubiquitous.el
1212
1313 ;; This file is NOT part of GNU Emacs.
1616 ;;
1717 ;;; Commentary:
1818
19 ;; If you use the excellent `ido-mode' for efficient completion of
20 ;; file names and buffers, you might wonder if you can get ido-style
21 ;; completion everywhere else too. Well, that's what this package
22 ;; does! ido-ubiquitous is here to enable ido-style completion for
23 ;; (almost) every function that uses the standard completion function
24 ;; `completing-read'.
25
26 ;; To use this package, call `ido-ubiquitous-mode' to enable the mode,
27 ;; or use `M-x customize-variable ido-ubiquitous-mode' it to enable it
28 ;; permanently. Once the mode is enabled, most functions that use
29 ;; `completing-read' will now have ido completion. If you decide in
30 ;; the middle of a command that you would rather not use ido, just C-f
31 ;; or C-b at the end/beginning of the input to fall back to non-ido
32 ;; completion (this is the same shortcut as when using ido for buffers
33 ;; or files).
34
35 ;; Note that `completing-read' has some quirks and complex behavior
36 ;; that ido cannot emulate. Ido-ubiquitous attempts to detect some of
37 ;; these quirks and avoid using ido when it sees them. So some
38 ;; functions will not have ido completion even when this mode is
39 ;; enabled. Some other functions have ido disabled in them because
40 ;; their packages already provide support for ido via other means (for
41 ;; example, magit). See `M-x customize-group ido-ubiquitous' and read
42 ;; about the override variables for more information.
43
44 ;; ido-ubiquitous version 3.0 is a major update, including a split
45 ;; into two packages, and some of the configuration options have
46 ;; changed in non-backwards-compatible ways. If you have customized
47 ;; ido-ubiquitous, be sure to check out `M-x customize-group
48 ;; ido-ubiquitous' and `M-x customize-group ido-completing-read+'
49 ;; after updating to 3.0 and make sure the new settings are to your
50 ;; liking.
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.
5121
5222 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5323 ;;
6838 ;;
6939 ;;; Code:
7040
71 (defconst ido-ubiquitous-version "3.16"
41 (defconst ido-ubiquitous-version "4.5"
7242 "Currently running version of ido-ubiquitous.
7343
7444 Note that when you update ido-ubiquitous, this variable may not
7545 be updated until you restart Emacs.")
7646
77 (eval-when-compile
78 (when (or (not (boundp 'completing-read-function))
79 (< emacs-major-version 24))
80 (error "Could not find required variable `completing-read-function'. Are you using Emacs version 24 or higher? If you have Emacs 23 or lower, please downgrade to ido-ubiquitous version 1.7 (or upgrade Emacs).")))
81
82 (require 'ido)
83 (require 'advice)
84 (require 'cl-lib)
85 (require 'cus-edit)
8647 (require 'ido-completing-read+)
8748
88 ;; Only exists in emacs 24.4 and up; we don't use this library
89 ;; directly, but we load it here so we can test if it's available,
90 ;; because if it isn't we need enable a workaround.
91 (require 'nadvice nil 'noerror)
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")
9251
93 ;;; Debug messages
94
95 ;;;###autoload
96 (define-minor-mode ido-ubiquitous-debug-mode
97 "If non-nil, ido-ubiquitous will print debug info.
98
99 Debug info is printed to the *Messages* buffer."
100 nil
101 :global t
102 :group 'ido-ubiquitous)
103
104 (defun ido-ubiquitous--debug-message (format-string &rest args)
105 (when ido-ubiquitous-debug-mode
106 (apply #'message (concat "ido-ubiquitous: " format-string) args)))
107
108 (defun ido-ubiquitous--explain-fallback (arg)
109 ;; This function accepts a string, or an ido-ubiquitous-fallback
110 ;; signal.
111 (when ido-ubiquitous-debug-mode
112 (when (and (listp arg)
113 (eq (car arg) 'ido-ubiquitous-fallback))
114 (setq arg (cadr arg)))
115 (ido-ubiquitous--debug-message "Falling back to `%s' because %s."
116 ido-cr+-fallback-function arg)))
117
118 ;;; Internal utility functions
119
120 (defun ido-ubiquitous--as-string (sym-or-str)
121 "Return name of symbol, return string as is."
122 (if (symbolp sym-or-str)
123 (symbol-name sym-or-str)
124 sym-or-str))
125
126 (defun ido-ubiquitous--as-symbol (sym-or-str)
127 "Return string as symbol, return symbol as is."
128 (if (symbolp sym-or-str)
129 sym-or-str
130 (intern sym-or-str)))
131
132 ;;; Custom widget definitions
133
134 ;; We need to define some custom widget types for use in the override
135 ;; variables.
136
137 (define-widget 'lazy-notag 'lazy
138 "Like lazy widget, but does not display its tag, only its value."
139 :format "%v")
140
141 ;; Define matcher functions and widgets for match specifications
142 (defvar ido-ubiquitous-match-spec-widget-types nil
143 "List of widget names for match specs.")
144 (defvar ido-ubiquitous-spec-matchers nil
145 "Alist of functions for matching function specs against function names.")
146 (cl-loop for (widget-name widget-tag key field-type matcher) in
147 '((exact-match "Exact match" exact string string=)
148 (prefix-match "Prefix match" prefix string string-prefix-p)
149 (regexp-match "Regexp match" regexp regexp string-match-p))
150 do (define-widget (ido-ubiquitous--as-symbol widget-name) 'lazy-notag widget-tag
151 :menu-tag widget-tag
152 :type `(list :tag ,widget-tag :format "%v"
153 (const :format ""
154 :tag ,widget-tag
155 ,key)
156 (,field-type :tag ,widget-tag)))
157 do (add-to-list 'ido-ubiquitous-match-spec-widget-types
158 widget-name 'append)
159 do (add-to-list 'ido-ubiquitous-spec-matchers
160 (cons key matcher) 'append))
161
162 (define-widget 'ido-ubiquitous-match-spec 'lazy-notag
163 "Choice of exact, prefix, or regexp match."
164 :type `(choice :tag "Match type"
165 ,@ido-ubiquitous-match-spec-widget-types))
166
167 (define-widget 'ido-ubiquitous-command-override-spec 'lazy-notag
168 "Choice of override action plus match specification."
169 :type '(cons :tag "Override rule"
170 (choice :tag "For matching commands"
171 (const :menu-tag "Disable"
172 :tag "Disable ido-ubiquitous"
173 disable)
174 (const :menu-tag "Enable"
175 :tag "Enable ido-ubiquitous in normal default mode"
176 enable)
177 (const :menu-tag "Enable old-style default"
178 :tag "Enable ido-ubiquitous in old-style default mode"
179 enable-old))
180 ido-ubiquitous-match-spec))
181
182 (define-widget 'ido-ubiquitous-function-override-spec 'lazy-notag
183 "Choice of override action and function name. (Exact match only.)"
184 :type '(list :tag "Override rule"
185 (choice :tag "Do the following"
186 (const :menu-tag "Disable"
187 :tag "Disable ido-ubiquitous"
188 disable)
189 (const :menu-tag "Enable"
190 :tag "Enable ido-ubiquitous in normal default mode"
191 enable)
192 (const :menu-tag "Enable old-style default"
193 :tag "Enable ido-ubiquitous in old-style default mode"
194 enable-old))
195 (const :format "" exact)
196 (string :tag "For function")))
197
198 ;;; Custom Declarations
199
200 (defgroup ido-ubiquitous nil
201 "Use ido for (almost) all completion."
202 :group 'ido
203 :group 'ido-completing-read-plus)
204
205 ;;;###autoload
206 (define-obsolete-variable-alias 'ido-ubiquitous
207 'ido-ubiquitous-mode "ido-ubiquitous 0.8")
208 ;;;###autoload
209 (define-obsolete-function-alias 'ido-ubiquitous
210 'ido-ubiquitous-mode "ido-ubiquitous 0.8")
211
212 ;;;###autoload
213 (define-minor-mode ido-ubiquitous-mode
214 "Use `ido-completing-read' instead of `completing-read' almost everywhere.
215
216 If this mode causes problems for a function, you can customize
217 when ido completion is or is not used by customizing
218 `ido-ubiquitous-command-overrides' or
219 `ido-ubiquitous-function-overrides'."
220 nil
221 :global t
222 :group 'ido-ubiquitous
223 ;; Actually enable/disable the mode by setting
224 ;; `completing-read-function'.
225 (setq completing-read-function
226 (if ido-ubiquitous-mode
227 #'completing-read-ido-ubiquitous
228 ido-cr+-fallback-function)))
229
230 ;; Variables for functionality that has moved to ido-completing-read+
231 (define-obsolete-variable-alias
232 'ido-ubiquitous-max-items
233 'ido-cr+-max-items
234 "ido-ubiquitous 3.0")
235 (define-obsolete-variable-alias
236 'ido-ubiquitous-fallback-completing-read-function
237 'ido-cr+-fallback-function
238 "ido-ubiquitous 3.0")
239
240 (define-obsolete-variable-alias
241 'ido-ubiquitous-enable-compatibility-globally
242 'ido-ubiquitous-enable-old-style-default
243 "ido-ubiquitous 2.0")
244
245 (defcustom ido-ubiquitous-default-state 'enable
246 "Default ido-ubiquitous mode of operation for commands with no override.
247
248 This can be set to one of three options:
249
250 * `enable': use normal ido completion;
251 * `enable-old': use ido completion, but with emulation of the
252 old-style default selection of `completing-read';
253 * `disable': use non-ido completion.
254
255 Command-specific and function-specific overrides are available to
256 override this default for specific commands/functions. See
257 `ido-ubiquitous-command-overrides' and
258 `ido-ubiquitous-function-overrides'.
259
260 The `enable-old' option swaps the behavior of RET and C-j but
261 only for the first keypress after beginning completion.
262 Specifically, on the first keypress, RET will return an empty
263 string and C-j will return the first item on the list. The
264 purpose of this is to emulate a legacy compatibility quirk of
265 `completing-read'. From the `completing-read' docstring:
266
267 > If the input is null, `completing-read' returns DEF, or the
268 > first element of the list of default values, or an empty string
269 > if DEF is nil, regardless of the value of REQUIRE-MATCH.
270
271 This odd behavior is required for compatibility with an old-style
272 usage pattern whereby the default was requested by returning an
273 empty string. In this mode, the caller receives the empty string
274 and handles the default case manually, while `completing-read'
275 never has any knowledge of the default. This is a problem for
276 ido, which normally returns the first element in the list, not an
277 empty string, when the input is empty and you press RET. Without
278 knowledge of the default, it cannot ensure that the default is
279 first on the list, so returning the first item is not the correct
280 behavior. Instead, it must return an empty string like
281 `completing-read'.
282
283 The `disable' mode is available as a default, which seems
284 counterintuitive. But this allows you, if you so desire, to
285 enable ido-ubiquitous selectively for only a few specific commands
286 using overrides and disable it for everything else."
287 :type '(choice :tag "Default mode"
288 (const :menu-tag "Disable"
289 :tag "Disable ido-ubiquitous"
290 disable)
291 (const :menu-tag "Enable"
292 :tag "Enable ido-ubiquitous in normal default mode"
293 enable)
294 (const :menu-tag "Enable old-style default"
295 :tag "Enable ido-ubiquitous in old-style default mode"
296 enable-old))
297 :group 'ido-ubiquitous)
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")
29860
29961 (make-obsolete-variable
300 'ido-ubiquitous-enable-old-style-default
301 "This variable no longer has any effect. Set
302 `ido-ubiquitous-default-state' to `enable-old' instead."
303 "ido-ubiquitous 3.0")
304
305 (defconst ido-ubiquitous-default-command-overrides
306 '(;; If you want ido for M-x, install smex
307 (disable exact "execute-extended-command")
308 ;; Wanderlust uses new-style default
309 (enable prefix "wl-")
310 ;; Info functions use old-style default selection
311 (enable-old prefix "Info-")
312 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/4
313 (enable exact "webjump")
314 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/28
315 (enable regexp "\\`\\(find\\|load\\|locate\\)-library\\'")
316 ;; https://github.com/bbatsov/prelude/issues/488
317 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/44
318 ;; tmm implements its own non-standard completion mechanics
319 (disable prefix "tmm-")
320 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/47
321 ;; theme functions don't need old-style compatibility
322 (enable regexp "\\`\\(load\\|enable\\|disable\\|describe\\|custom-theme-visit\\)-theme\\'")
323 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/79
324 (enable-old prefix "bbdb-")
325 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/83
326 (enable-old exact "where-is")
327 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/60
328 (disable exact "todo-add-category")
329 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/51
330 (enable exact "find-tag")
331 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/89
332 (enable prefix "etags-select-")
333 ) ; Close paren on separate line for better VC diffs
334 "Default value of `ido-ubiquitous-command-overrides'.
335
336 You can restore these using the command `ido-ubiquitous-restore-default-overrides'.")
337
338 (defconst ido-ubiquitous-default-function-overrides
339 '((disable exact "read-file-name")
340 (disable exact "read-file-name-internal")
341 (disable exact "read-buffer")
342 (disable exact "gnus-emacs-completing-read")
343 (disable exact "gnus-iswitchb-completing-read")
344 (disable exact "grep-read-files")
345 (disable exact "magit-builtin-completing-read")
346 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/36
347 (enable exact "bookmark-completing-read")
348 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/4
349 (enable-old exact "webjump-read-choice")
350 (enable-old exact "webjump-read-url-choice")
351 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/9
352 (disable exact "isearchp-read-unicode-char")
353 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/38
354 (enable exact "read-char-by-name")
355 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/39
356 (disable exact "Info-read-node-name")
357 ;; https://github.com/purcell/emacs.d/issues/182#issuecomment-44212927
358 (disable exact "tmm-menubar")
359 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/58
360 ;; https://github.com/mooz/js2-mode/issues/181
361 (enable exact "imenu--completion-buffer")
362 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/74
363 (enable-old exact "auto-insert")
364 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/116
365 (enable exact "project--completing-read-strict")
366 ) ; Close paren on separate line for better VC diffs
367 "Default value of `ido-ubiquitous-function-overrides'.
368
369 You can restore these using the command `ido-ubiquitous-restore-default-overrides'.")
370
371 (defcustom ido-ubiquitous-command-overrides ido-ubiquitous-default-command-overrides
372 "List of command override specifications for ido-ubiquitous
373
374 Each override specification describes how ido-ubiquitous should
375 behave one or many commands. A specification has the
376 form `(BEHAVIOR MATCH-TYPE MATCH-TEXT)'. BEHAVIOR is one of the
377 following:
378
379 * `disable': ido-ubiquitous should not be used at all for the
380 specified commands;
381 * `enable': ido-ubiquitous may be used with the specified
382 commands, without emulating the old-style default selection
383 of `completing-read';
384 * `enable-old': ido-ubiquitous may be used with the specified
385 commands, and should emulate the old-style default selection
386 of `completing-read'.
387
388 MATCH-TYPE affects how MATCH-TEXT is interpreted, as follows:
389
390 * `exact': the specification only affects the one command
391 whose name is MATCH-TEXT;
392 * `prefix': the specification affects any command whose name
393 starts with MATCH-TEXT (This is useful for specifying a
394 certain behavior for an entire package);
395 * `regexp': the specification affects any command whose name
396 matches MATCH-TEXT (with MATCH-TEXT being interpreted as a
397 regular expression)
398
399 MATCH-TEXT should be a string.
400
401 Since this variable's has a somewhat complex structure, it is
402 recommended that you set this variable through Customize.
403
404 Note that this variable only affects *commands*, which are
405 functions marked as interactive. See
406 `ido-ubiquitous-function-overrides' for how to modify the
407 behavior of ido-ubiquitous for arbitrary functions.
408
409 Note: If multiple overrides match the same commmand, the first
410 one in the list will take precedence.
411
412 If you need to add a new specification to this list, please also
413 file a bug report at https://github.com/DarwinAwardWinner/ido-ubiquitous/issues"
414 :type '(repeat ido-ubiquitous-command-override-spec)
415 :group 'ido-ubiquitous)
416
417 (defmacro ido-ubiquitous-with-override (override &rest body)
418 "Eval BODY with specified OVERRIDE in place.
419
420 The OVERRIDE argument is evaluated normally, so if it is a
421 literal symbol, it must be quoted.
422
423 See `ido-ubiquitous-command-overrides' for valid override types."
424 (declare (indent 1))
425 ;; Eval override
426 `(let ((ido-ubiquitous-next-override ,override))
427 ,@body))
428
429 (defun ido-ubiquitous-apply-function-override (func override)
430 "Set the override property on FUNC to OVERRIDE and set up advice to apply the override."
431 (setq func (ido-ubiquitous--as-symbol func)
432 override (ido-ubiquitous--as-symbol override))
433 (if (memq override '(disable enable enable-old nil))
434 (progn
435 (put func 'ido-ubiquitous-override override)
436 (when override
437 (let ((docstring
438 (format "Override ido-ubiquitous behavior in %s if its `ido-ubiquitous-override' property is non-nil." func)))
439 (eval
440 `(defadvice ,func (around ido-ubiquitous-override activate)
441 ,docstring
442 (let* ((func ',func)
443 (override (get func 'ido-ubiquitous-override)))
444 (when override
445 (ido-ubiquitous--debug-message
446 "Using override `%s' for function `%s'"
447 override func))
448 (ido-ubiquitous-with-override override
449 ad-do-it)))))))
450 (display-warning
451 'ido-ubiquitous
452 (format "Ignoring invalid override action `%s' for function `%s' found in `ido-ubiquitous-function-overrides'."
453 override func)
454 :warning)))
455
456 (defun ido-ubiquitous-set-function-overrides (sym newval)
457 "Custom setter function for `ido-ubiquitous-function-overrides'.
458
459 In addition to setting the variable, this also sets up advice on
460 each function to apply the appropriate override."
461 ;; Unset all previous overrides
462 (when (boundp sym)
463 (let ((oldval (eval sym)))
464 (cl-loop for (_action _match-type func) in oldval
465 do (ido-ubiquitous-apply-function-override func nil))))
466 ;; Ensure that function names are strings, not symbols
467 (setq newval
468 (cl-loop for (action match-type func) in newval
469 collect (list action match-type
470 (ido-ubiquitous--as-string func))))
471 ;; set new overrides
472 (cl-loop for override in newval
473 for (action match-type func) = override
474
475 ;; Remove duplicate overrides
476 if (member func overridden-functions)
477 do (display-warning
478 'ido-ubiquitous
479 (format
480 "Removing duplicate override for function `%s'" func))
481
482 ;; Apply valid overrides
483 else if (eq match-type 'exact)
484 do (ido-ubiquitous-apply-function-override func action)
485 and collect func into overridden-functions
486 and collect override into final-value
487
488 ;; Remove invalid overrides
489 else
490 do (display-warning
491 'ido-ubiquitous
492 (format
493 "Removing invalid function override match-type `%s' for function `%s'; only match-type `exact' is supported in `ido-ubiquitous-function-overrides'."
494 match-type func))
495
496 ;; Set the value to only the overrides that were actually
497 ;; applied.
498 finally return
499 (set-default sym final-value)))
500
501 (defcustom ido-ubiquitous-auto-update-overrides 'notify
502 "Whether to add new overrides when updating ido-ubiquitous.
503
504 Ido-ubiquitous comes with a default set of overrides for commands
505 that are known to require them. New versions of ido-ubiquitous
506 may come with updates to the default overrides as more commands
507 are discovered to require them. However, customizing your own
508 overrides would normally prevent you from receiving these
509 updates, since Emacs will not overwrite your customizations.
510
511 To resolve this problem, you can set this variable to `t', and
512 then ido-ubiquitous can automatically add any new built-in
513 overrides whenever it is updated. (Actually, the update will
514 happen the next time Emacs is restarted after the update.) This
515 allows you to add your own overrides but still receive updates to
516 the default set. The default overrides will always be added with
517 lower precedence than user-added ones.
518
519 If you want ido-ubiquitous to just notify you about new default
520 overrides instead of adding them itself, set this variable to
521 `notify'. If you don't want this auto-update behavior at all, set
522 it to `nil'.
523
524 (Note that having this option enabled effectively prevents you
525 from removing any of the built-in default overrides, since they
526 will simply be re-added the next time Emacs starts. However, your
527 custom overrides will still take precedence, so this shouldn't be
528 a problem.)"
529 :type '(choice :tag "When new overrides are available:"
530 (const :menu-tag "Auto-add"
531 :tag "Add them automatically"
532 t)
533 (const :menu-tag "Notify"
534 :tag "Notify the user about them"
535 notify)
536 (const :menu-tag "Ignore"
537 :tag "Ignore them"
538 nil))
539 :group 'ido-ubiquitous)
540
541 (defcustom ido-ubiquitous-function-overrides ido-ubiquitous-default-function-overrides
542 "List of function override specifications for ido-ubiquitous
543
544 Function override specifications have a similar structure to
545 command override specifications (see
546 `ido-ubiquitous-command-overrides'). A function override
547 specification has the form `(BEHAVIOR MATCH-TYPE MATCH-TEXT)'.
548 However, `MATCH-TYPE' may ONLY be `exact'; No other match type is
549 supported.
550
551 Note: If multiple overrides are set for the same function, the
552 first one in the list will take precedence, and the rest will be
553 ignored and deleted from the override list, with a warning.
554 Invalid override specifications will also be deleted with a
555 warning.
556
557 If you need to add a new specification to this list, please also file a
558 bug report at https://github.com/DarwinAwardWinner/ido-ubiquitous/issues
559
560 Setting this variable directly has no effect. You must set it
561 through Customize."
562 :type '(repeat ido-ubiquitous-function-override-spec)
563 :set 'ido-ubiquitous-set-function-overrides
564 :group 'ido-ubiquitous)
565
566 (defcustom ido-ubiquitous-allow-on-functional-collection nil
567 "Allow ido completion when COLLECTION is a function.
568
569 The `completing-read' function allows its COLLECTION argument to
570 be a function instead of a list of choices. Some such functions
571 simply return a list of completions and are suitable for use with
572 ido, but others implement more complex behavior and will result
573 in incorrect behavior if used with ido. Since there is no way to
574 tell the difference, this preference defaults to nil, which means
575 that ido-ubiquitous will not work when COLLECTION is a function
576 unless there is a specific override in effect. To disable this
577 safeguard and GUARANTEE ERRORS on some functions, you may set
578 this to non-nil, but this is not recommended."
579 :type 'boolean
580 :group 'ido-ubiquitous)
581
582 ;;; ido-ubiquitous core
583
584 ;; These variable are used to make ido-ubiquitous work properly in the
585 ;; case that `completing-read' is called recursively (which is
586 ;; possible when `enable-recursive-minibuffers' is non-nil.)
587 (defvar ido-ubiquitous-enable-next-call nil
588 "If non-nil, then the next call to `ido-completing-read' is by ido-ubiquitous.")
589 (defvar ido-ubiquitous-enable-this-call nil
590 "If non-nil, then the current call to `ido-completing-read' is by ido-ubiquitous.")
591 (defvar ido-ubiquitous-next-override nil
592 "This holds the override to be applied on the next call to `completing-read'.
593
594 It's value can be nil or one of the symbols `disable', `enable', or
595 `enable-old'.
596
597 You should not modify this variable directly. Instead use the
598 macro `ido-ubiquitous-with-override'.")
599 (defvar ido-ubiquitous-active-override nil
600 "This holds the override being applied to the current call to `completing-read'.
601
602 It's value can be nil or one of the symbols `disable', `enable', or
603 `enable-old'.
604
605 You should not modify this variable directly. Instead use the
606 macro `ido-ubiquitous-with-override'.")
607 (defvar ido-ubiquitous-active-state nil
608 "This holds the ido-ubiquitous mode of operation for the current call to `completing-read'.
609
610 It's value can be nil or one of the symbols `disable', `enable', or
611 `enable-old'.
612
613 You should not modify this variable directly.")
614
615 (defadvice ido-completing-read (around ido-ubiquitous activate)
616 "Enable ido-ubiquitous features if this call was done through ido-ubiquitous.
617
618 This advice ensures that `ido-ubiquitous-enable-this-call' is set
619 properly while `ido-completing-read' is executing. This variable
620 is used to determine whether to enable certain behaviors only for
621 ido-ubiquitous, not for ordinary ido completion."
622 ;; Set "this" and clear "next" so it doesn't apply to nested calls.
623 (let* ((ido-ubiquitous-enable-this-call ido-ubiquitous-enable-next-call)
624 (ido-ubiquitous-enable-next-call nil)
625 (ido-ubiquitous-initial-item nil))
626 ad-do-it))
627
628 ;; Signal used to trigger fallback (don't use `define-error' because
629 ;; it's only supported in 24.4 and up)
630 (put 'ido-ubiquitous-fallback 'error-conditions '(ido-ubiquitous-fallback error))
631 (put 'ido-ubiquitous-fallback 'error-message "ido-ubiquitous-fallback")
632
633 (defun completing-read-ido-ubiquitous
634 (prompt collection &optional predicate
635 require-match initial-input
636 hist def inherit-input-method)
637 "ido-based method for reading from the minibuffer with completion.
638
639 See `completing-read' for the meaning of the arguments.
640
641 This function is a wrapper for `ido-completing-read' designed to
642 be used as the value of `completing-read-function'. Importantly,
643 it detects edge cases that ido cannot handle and uses normal
644 completion for them."
645 (let (;; Save the original arguments in case we need to do the
646 ;; fallback
647 (orig-args
648 (list prompt collection predicate require-match
649 initial-input hist def inherit-input-method)))
650 ;; Outer `condition-case' is the fallback handler
651 (condition-case sig
652 ;; Inner `condition-case' converts any unexpected errors into
653 ;; fallback signals.
654 (condition-case err
655 (let* (;; Set the active override and clear the "next" one so it
656 ;; doesn't apply to nested calls.
657 (ido-ubiquitous-active-override ido-ubiquitous-next-override)
658 (ido-ubiquitous-next-override nil)
659 ;; Apply the active override, if any
660 (ido-ubiquitous-active-state
661 (or ido-ubiquitous-active-override
662 ido-ubiquitous-default-state
663 'enable)))
664 ;; If ido-ubiquitous is disabled this time, fall back
665 (when (eq ido-ubiquitous-active-state 'disable)
666 (signal 'ido-ubiquitous-fallback
667 '("`ido-ubiquitous-active-state' is `disable'")))
668 ;; Handle a collection that is a function: either expand
669 ;; completion list now or fall back
670 (when (functionp collection)
671 (if (or ido-ubiquitous-allow-on-functional-collection
672 (memq ido-ubiquitous-active-override
673 '(enable enable-old)))
674 (setq collection (all-completions "" collection predicate)
675 ;; `all-completions' will apply the predicate,
676 ;; so it now becomes redundant.
677 predicate nil)
678 (signal 'ido-ubiquitous-fallback
679 '("COLLECTION is a function and there is no override"))))
680 (let ((ido-ubiquitous-enable-next-call t))
681 (ido-completing-read+
682 prompt collection predicate require-match
683 initial-input hist def inherit-input-method)))
684 ;; Pass through any known fallback signals to the outer
685 ;; `condition-case'
686 (ido-ubiquitous-fallback
687 (signal (car err) (cdr err)))
688 ;; Convert any other error into a fallback signal.
689 (error
690 (signal 'ido-ubiquitous-fallback
691 (list (format "ido-ubiquitous encountered an unexpected error: %S"
692 err)))))
693 ;; Handler for ido-ubiquitous-fallback signal
694 (ido-ubiquitous-fallback
695 (ido-ubiquitous--explain-fallback sig)
696 (apply ido-cr+-fallback-function orig-args)))))
697 (define-obsolete-function-alias 'completing-read-ido 'completing-read-ido-ubiquitous
698 "ido-ubiquitous 3.0")
699
700 ;;; Old-style default support
701
702 (defvar ido-ubiquitous-initial-item nil
703 "The first item selected when ido starts.
704
705 This is initialized to the first item in the list of completions
706 when ido starts, and is cleared when any character is entered
707 into the prompt or the list is cycled. If it is non-nil and still
708 equal to the first item in the completion list when ido exits,
709 then if `ido-ubiquitous-active-state' is `enable-old', ido
710 returns an empty string instead of the first item on the list.")
711
712 (defmacro ido-ubiquitous-set-initial-item (item)
713 "Wrapper for `(setq ido-ubiquitous-initial-item ITEM)'.
714
715 This wrapper differs from simply doing `(setq
716 ido-ubiquitous-initial-item ITEM)' in several ways. First, it has
717 no effect (and does not evaluate ITEM) unless
718 `ido-ubiquitous-active-state' is `enable-old'. Second, it emits
719 appropriate debug messages."
720 `(when (eq ido-ubiquitous-active-state 'enable-old)
721 (let ((item ,item))
722 (cond
723 (item
724 (ido-ubiquitous--debug-message
725 "Setting `ido-ubiquitous-initial-item' to `%S'."
726 item))
727 (ido-ubiquitous-initial-item
728 (ido-ubiquitous--debug-message "Clearing `ido-ubiquitous-initial-item'.")))
729 (setq ido-ubiquitous-initial-item item))))
730
731 (defadvice ido-read-internal (before ido-ubiquitous-clear-initial-item activate)
732 (ido-ubiquitous-set-initial-item nil))
733
734 (defadvice ido-make-choice-list (after ido-ubiquitous-set-initial-item activate)
735 (ido-ubiquitous-set-initial-item
736 (when (and ad-return-value (listp ad-return-value))
737 (car ad-return-value))))
738
739 (defadvice ido-next-match (after ido-ubiquitous-clear-initial-item activate)
740 (ido-ubiquitous-set-initial-item nil))
741
742 (defadvice ido-prev-match (after ido-ubiquitous-clear-initial-item activate)
743 (ido-ubiquitous-set-initial-item nil))
744
745 ;; Clear initial item after `self-insert-command'
746 (defun ido-ubiquitous-post-insert-hook ()
747 (eval '(ido-ubiquitous-set-initial-item nil)))
748
749 (defun ido-ubiquitous-ido-minibuffer-setup-hook ()
750 (add-hook
751 'post-self-insert-hook
752 #'ido-ubiquitous-post-insert-hook
753 nil
754 'local))
755
756 (add-hook 'ido-minibuffer-setup-hook
757 #'ido-ubiquitous-ido-minibuffer-setup-hook)
758
759 (defun ido-ubiquitous-should-use-old-style-default ()
760 "Returns non nil if ido-ubiquitous should emulate old-style default.
761
762 This function simply encapsulates all the checks that need to be
763 done in order to decide whether to swap RET and C-j. See
764 `ido-ubiquitous-default-state' for more information."
765 ;; These checks outside the loop don't produce debug messages
766 (and
767 ;; Only if old-style default enabled
768 (eq ido-ubiquitous-active-state 'enable-old)
769 ;; This loop is just an implementation of `and' that reports which
770 ;; arg was nil for debugging purposes.
771 (cl-loop
772 for test in
773 '((bound-and-true-p ido-cur-item)
774 ;; Only if completing a list, not a buffer or file
775 (eq ido-cur-item 'list)
776 ;; Only if this call was done through ido-ubiquitous
777 ido-ubiquitous-enable-this-call
778 ;; Only if default is nil
779 (null ido-default-item)
780 ;; Only if input is empty
781 (string= ido-text "")
782 ;; Only if `ido-ubiquitous-initial-item' hasn't been cleared
783 ido-ubiquitous-initial-item
784 ;; Only if initial item hasn't changed
785 (string= (car ido-cur-list)
786 ido-ubiquitous-initial-item))
787 for test-result = (eval test)
788 if (not test-result)
789 do (ido-ubiquitous--debug-message
790 "Not enabling old-style default selection because `%S' is nil"
791 test)
792 and return nil
793 finally do (ido-ubiquitous--debug-message
794 "Enabling old-style default selection")
795 finally return t)))
796
797 (defadvice ido-exit-minibuffer (around ido-ubiquitous-old-style-default-compat activate)
798 "Emulate a quirk of `completing-read'.
799
800 > If the input is null, `completing-read' returns DEF, or the
801 > first element of the list of default values, or an empty string
802 > if DEF is nil, regardless of the value of REQUIRE-MATCH.
803
804 See `ido-ubiquitous-default-state', which controls whether this
805 advice has any effect."
806 (condition-case nil
807 (if (ido-ubiquitous-should-use-old-style-default)
808 (let ((ido-ubiquitous-active-state 'enable))
809 (ido-select-text))
810 ad-do-it)
811 (error
812 (display-warning 'ido-ubiquitous "Advice on `ido-exit-minibuffer' failed." :warning)
813 ad-do-it))
814 (ido-ubiquitous-set-initial-item nil))
815
816 (defadvice ido-select-text (around ido-ubiquitous-old-style-default-compat activate)
817 "Emulate a quirk of `completing-read'.
818
819 > If the input is null, `completing-read' returns DEF, or the
820 > first element of the list of default values, or an empty string
821 > if DEF is nil, regardless of the value of REQUIRE-MATCH.
822
823 See `ido-ubiquitous-default-state', which controls whether this
824 advice has any effect."
825 (condition-case nil
826 (if (ido-ubiquitous-should-use-old-style-default)
827 (let ((ido-ubiquitous-active-state 'enable))
828 (ido-exit-minibuffer))
829 ad-do-it)
830 (error
831 (display-warning 'ido-ubiquitous "Advice on `ido-select-text' failed." :warning)
832 ad-do-it))
833 (ido-ubiquitous-set-initial-item nil))
834
835 ;;; Overrides
836
837 (defun ido-ubiquitous--overrides-have-same-target-p (o1 o2)
838 (cl-destructuring-bind (oride1 type1 text1) o1
839 (cl-destructuring-bind(oride2 type2 text2) o2
840 ;; Avoid warnings about unused vars
841 oride1 oride2
842 (and (string= text1 text2)
843 (eq type1 type2)))))
844
845 (defun ido-ubiquitous--combine-override-lists (olist1 olist2)
846 "Append OLIST2 to OLIST1, but remove redundant elements.
847
848 Redundancy is determined using
849 `ido-ubiquitous--overrides-have-same-target-p'."
850 (let ((olist2
851 (cl-remove-if
852 (lambda (o2) (cl-member
853 o2 olist1
854 :test #'ido-ubiquitous--overrides-have-same-target-p))
855 olist2)))
856 (append olist1 olist2)))
857
858 (defun ido-ubiquitous-update-overrides (&optional save quiet)
859 "Re-add the default overrides without erasing custom overrides.
860
861 This is useful after an update of ido-ubiquitous that adds new
862 default overrides. See `ido-ubiquitous-auto-update-overrides' for
863 more information.
864
865 If SAVE is non-nil, also save the overrides to the user's custom
866 file (but only if they were already customized). When called
867 interactively, a prefix argument triggers a save.
868
869 When called from Lisp code, this function returns the list of
870 variables whose values were modified. In particular, it returns
871 non-nil if any variables were modified, and nil if no modifications
872 were made."
873 (interactive "P")
874 (let ((unmodified-vars nil)
875 (updated-vars nil)
876 (final-message-lines nil)
877 (final-message-is-warning nil))
878 (cl-loop
879 for (var def) in
880 '((ido-ubiquitous-command-overrides
881 ido-ubiquitous-default-command-overrides)
882 (ido-ubiquitous-function-overrides
883 ido-ubiquitous-default-function-overrides))
884 do (let* ((var-state (custom-variable-state var (eval var)))
885 (curval (eval var))
886 (defval (eval def))
887 (newval (ido-ubiquitous--combine-override-lists
888 curval defval)))
889 (cond
890 ;; Nothing to add to var, do nothing
891 ((and (equal curval newval)
892 (eq var-state 'saved))
893 (ido-ubiquitous--debug-message
894 "No need to modify value of option `%s'"
895 var)
896 (push var unmodified-vars))
897 ;; Var is not customized, just set the new default
898 ((eq var-state 'standard)
899 (ido-ubiquitous--debug-message
900 "Setting uncustomized option `%s' to its default value"
901 var)
902 (push var unmodified-vars)
903 (set var defval))
904 ;; Var is saved to custom.el, set and save new value (if
905 ;; SAVE is t)
906 ((and save
907 (eq var-state 'saved))
908 (ido-ubiquitous--debug-message
909 "Updating option `%s' with new overrides and saving it."
910 var)
911 (push var updated-vars)
912 (customize-save-variable var newval))
913 ;; Var is modified but not saved (or SAVE is nil), update it
914 ;; but don't save it
915 (t
916 (ido-ubiquitous--debug-message
917 "Updating option `%s' with new overrides but not saving it for future sessions."
918 var)
919 (push var updated-vars)
920 (customize-set-variable var newval)))))
921 (unless quiet
922 ;; Now compose a single message that summarizes what was done
923 (if (null updated-vars)
924 (push "No updates to ido-ubiquitous override variables were needed."
925 final-message-lines)
926 (push
927 (format "Updated the following ido-ubiquitous override variables: %S"
928 (sort updated-vars #'string<))
929 final-message-lines)
930 (if save
931 (push
932 "All updated variables were successfully saved."
933 final-message-lines)
934 (push
935 "However, they have not been saved for future sessions. To save them, re-run this command with a prefix argument: `C-u M-x ido-ubiquitous-update-overrides'; or else manually inspect and save their values using `M-x customize-group ido-ubiquitous'."
936 final-message-lines)
937 (setq final-message-is-warning t)))
938 (if final-message-is-warning
939 (display-warning 'ido-ubiquitous
940 (mapconcat 'identity (nreverse final-message-lines) "\n"))
941 (message (mapconcat 'identity (nreverse final-message-lines) "\n"))))
942 updated-vars))
943
944 (defun ido-ubiquitous--find-override-updates (current-value available-updates)
945 (cl-set-difference (ido-ubiquitous--combine-override-lists
946 current-value available-updates)
947 current-value))
948
949 (defun ido-ubiquitous--maybe-update-overrides ()
950 "Maybe call `ido-ubiquitous-update-overrides.
951
952 See `ido-ubiquitous-auto-update-overrides."
953 (if ido-ubiquitous-auto-update-overrides
954 (let* ((command-override-updates
955 (ido-ubiquitous--find-override-updates
956 ido-ubiquitous-command-overrides
957 ido-ubiquitous-default-command-overrides))
958 (function-override-updates
959 (ido-ubiquitous--find-override-updates
960 ido-ubiquitous-function-overrides
961 ido-ubiquitous-default-function-overrides))
962 (update-count
963 (+ (length command-override-updates)
964 (length function-override-updates))))
965 (if (> update-count 0)
966 (if (eq ido-ubiquitous-auto-update-overrides 'notify)
967 (display-warning
968 'ido-ubiquitous
969 (format "There are %s new overrides available. Use `M-x ido-ubiquitous-update-overrides' to enable them. (See `ido-ubiquitous-auto-update-overrides' for more information.)"
970 update-count))
971 (ido-ubiquitous--debug-message "Applying override updates.")
972 (ido-ubiquitous-update-overrides t))
973 (ido-ubiquitous--debug-message "No override updates availble.")))
974 (ido-ubiquitous--debug-message "Skipping override updates by user preference.")))
975
976 (define-obsolete-function-alias
977 'ido-ubiquitous-restore-default-overrides
978 'ido-ubiquitous-update-overrides
979 "ido-ubiquitous 3.9")
980
981 (defun ido-ubiquitous-spec-match (spec symbol)
982 "Returns t if SPEC matches SYMBOL (which should be a function name).
983
984 See `ido-ubiquitous-command-overrides'. If the match spec is
985 invalid or any other error occurs, the error is demoted to a
986 warning and the function returns nil."
987 (condition-case err
988 (when (and symbol (symbolp symbol))
989 (cl-destructuring-bind (type text) spec
990 (let ((matcher (cdr (assoc type ido-ubiquitous-spec-matchers)))
991 (text (ido-ubiquitous--as-string text))
992 (symname (ido-ubiquitous--as-string symbol)))
993 (if matcher
994 (funcall matcher text symname)
995 ;; If the matcher is invalid, issue a warning and return
996 ;; nil.
997 (error "Unknown match spec type \"%s\". See `ido-ubiquitous-spec-matchers' for valid types." type)
998 nil))))
999 (error
1000 (display-warning 'ido-ubiquitous "Error during ido-ubiquitous spec matching: %S" err)
1001 nil)))
1002
1003 (defun ido-ubiquitous-get-command-override (cmd)
1004 "Return the override associated with the command CMD.
1005
1006 If there is no override set for CMD in
1007 `ido-ubiquitous-command-overrides', return nil."
1008 (when (and cmd (symbolp cmd))
1009 (cl-loop for override in ido-ubiquitous-command-overrides
1010 for (action . spec) = override
1011 for valid-action = (and (memq action '(disable enable enable-old nil))
1012 (assoc (car spec) ido-ubiquitous-spec-matchers))
1013 unless valid-action
1014 do (progn
1015 (display-warning
1016 'ido-ubiquitous
1017 (format "Removing invalid override `%S' from `ido-ubiquitous-command-overrides'"
1018 (cons action spec))
1019 :warning)
1020 (setq ido-ubiquitous-command-overrides
1021 (remove override ido-ubiquitous-command-overrides)))
1022 when (and valid-action (ido-ubiquitous-spec-match spec cmd))
1023 return action
1024
1025 finally return nil)))
1026
1027 ;;; Workaround for https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/24
1028
1029 ;; When `call-interactively' is advised, `called-interactively-p'
1030 ;; always returns nil. So we redefine it (and `interactive-p') to test
1031 ;; the correct condition.
1032
1033 (defsubst ido-ubiquitous--looks-like-advised-orig (func)
1034 "Returns t if FUNC is a symbol starting with \"ad-Orig-\".
1035
1036 Such symbols are used to store the original definitions of
1037 functions that have been advised by `defadvice' or similar."
1038 (and (symbolp func)
1039 (string-prefix-p "ad-Orig-" (symbol-name func))))
1040
1041 (defsubst ido-ubiquitous--looks-like-call-interactively (func)
1042 "Returns t if FUNC looks like the function `call-interactively'.
1043
1044 FUNC \"looks like\" `call-interactively' if it is the literal
1045 symbol `call-interactively', or the value of `(symbol-function
1046 'call-interactively)', or a symbol whose `symbol-function' is the
1047 same as that of `call-interactively'.
1048
1049 This function is used to determine whether a given function was
1050 \"called by\" `call-interactively' and therefore was called
1051 interactively."
1052 (when func
1053 (eq (symbol-function 'call-interactively)
1054 (if (symbolp func)
1055 (symbol-function func)
1056 func))))
1057
1058 (defun ido-ubiquitous--backtrace-from (fun)
1059 "Return all backtrace frames, starting with the one for FUN.
1060
1061 FUN may be a list of functions, in which case the first one found
1062 on the stack will be used."
1063 (let ((stack
1064 (cl-loop for i upfrom 0
1065 for frame = (backtrace-frame i)
1066 while frame
1067 collect frame))
1068 (funcs (if (functionp fun)
1069 (list fun)
1070 fun)))
1071 (while (and stack
1072 (not (memq (cl-cadar stack) funcs)))
1073 (setq stack (cdr stack)))
1074 stack))
1075
1076 (defun ido-ubiquitous--clean-advice-from-backtrace (stack)
1077 "Takes a stack trace and cleans all evidence of advice.
1078
1079 Specifically, for each call to a function starting with
1080 \"ad-Orig-\", that call and all prior calls up to but not
1081 including the advised function's original name are deleted from
1082 the stack."
1083 (let ((skipping-until nil))
1084 (cl-loop for frame in stack
1085 for func = (cadr frame)
1086 ;; Check if we found the frame we we're skipping to
1087 if (and skipping-until
1088 (eq func skipping-until))
1089 do (setq skipping-until nil)
1090 ;; If we're looking at an the original form of an advised
1091 ;; function, skip until the real name of that function.
1092 if (and (not skipping-until)
1093 (ido-ubiquitous--looks-like-advised-orig func))
1094 do (setq skipping-until
1095 (intern
1096 (substring (symbol-name func)
1097 (eval-when-compile (length "ad-Orig-")))))
1098 unless skipping-until collect frame)))
1099
1100 (defsubst ido-ubiquitous--interactive-internal ()
1101 "Equivalent of the INTERACTIVE macro in the Emacs C source.
1102
1103 This is an internal function that should never be called
1104 directly.
1105
1106 See the C source for the logic behind this function."
1107 (and (not executing-kbd-macro)
1108 (not noninteractive)))
1109
1110 (defun ido-ubiquitous--interactive-p-internal ()
1111 "Equivalent of C function \"interactive_p\".
1112
1113 This is an internal function that should never be called
1114 directly.
1115
1116 See the C source for the logic behind this function."
1117 (let ((stack
1118 ;; We clean advice from the backtrace. This ensures that we
1119 ;; get the right answer even if `call-interactively' has been
1120 ;; advised.
1121 (ido-ubiquitous--clean-advice-from-backtrace
1122 (cdr
1123 (ido-ubiquitous--backtrace-from
1124 '(called-interactively-p interactive-p))))))
1125 ;; See comments in the C function for the logic here.
1126 (while (and stack
1127 (or (eq (cl-cadar stack) 'bytecode)
1128 (null (caar stack))))
1129 (setq stack (cdr stack)))
1130 ;; Top of stack is now the function that we want to know
1131 ;; about. Pop it, then check if the next function is
1132 ;; `call-interactively', using a more permissive test than the default.
1133 (ido-ubiquitous--looks-like-call-interactively (cl-cadadr stack))))
1134
1135 (defadvice call-interactively (around ido-ubiquitous activate)
1136 "Implements the behavior specified in `ido-ubiquitous-command-overrides'."
1137 (let* ((cmd (ad-get-arg 0))
1138 (override (ido-ubiquitous-get-command-override cmd)))
1139 (when override
1140 (ido-ubiquitous--debug-message "Using override `%s' for command `%s'"
1141 override cmd))
1142 (ido-ubiquitous-with-override override
1143 ad-do-it)))
1144
1145 ;; Work around `called-interactively-p' in Emacs 24.3 and earlier,
1146 ;; which always returns nil when `call-interactively' is advised.
1147 (when (not (and (featurep 'nadvice)
1148 (boundp 'called-interactively-p-functions)))
1149
1150 (defadvice interactive-p (around ido-ubiquitous activate)
1151 "Return the correct result when `call-interactively' is advised.
1152
1153 This advice completely overrides the original definition."
1154 (condition-case nil
1155 (setq ad-return-value
1156 (and (ido-ubiquitous--interactive-internal)
1157 (ido-ubiquitous--interactive-p-internal)))
1158 ;; In case of error in the advice, fall back to the default
1159 ;; implementation
1160 (error ad-do-it)))
1161
1162 (defadvice called-interactively-p (around ido-ubiquitous activate)
1163 "Return the correct result when `call-interactively' is advised.
1164
1165 This advice completely overrides the original definition."
1166 (condition-case nil
1167 (setq ad-return-value
1168 (and (or (ido-ubiquitous--interactive-internal)
1169 (not (eq kind 'interactive)))
1170 (ido-ubiquitous--interactive-p-internal)))
1171 ;; In case of error in the advice, fall back to the default
1172 ;; implementation
1173 (error ad-do-it))))
1174
1175 ;;; Other
1176
1177 (defsubst ido-ubiquitous--fixup-old-advice ()
1178 ;; Clean up old versions of ido-ubiquitous advice if they exist
1179 (ignore-errors (ad-remove-advice 'completing-read 'around 'ido-ubiquitous))
1180 (ignore-errors (ad-remove-advice 'ido-completing-read 'around 'detect-replacing-cr))
1181 (ignore-errors (ad-remove-advice 'ido-magic-forward-char 'before 'ido-ubiquitous-fallback))
1182 (ignore-errors (ad-remove-advice 'ido-magic-backward-char 'before 'ido-ubiquitous-fallback))
1183 (ignore-errors (ad-remove-advice 'ido-exit-minibuffer 'around 'compatibility))
1184 (ad-activate-all))
1185
1186 (defsubst ido-ubiquitous--fixup-old-magit-overrides ()
1187 (let ((old-override '(disable prefix "magit-"))
1188 (new-override '(disable exact "magit-builtin-completing-read")))
1189 (when (member old-override
1190 ido-ubiquitous-command-overrides)
1191 (customize-set-variable
1192 'ido-ubiquitous-command-overrides
1193 (remove old-override ido-ubiquitous-command-overrides))
1194 (unless (member new-override ido-ubiquitous-function-overrides)
1195 (customize-set-variable 'ido-ubiquitous-function-overrides
1196 (append ido-ubiquitous-function-overrides
1197 (list new-override))))
1198 (display-warning
1199 'ido-ubiquitous
1200 "Fixing obsolete magit overrides.
1201
1202 Magit has changed recently such that the old override that
1203 ido-ubiquitous defined for it now causes problems. This old
1204 override has been automatically removed and the new one added.
1205 Please use `M-x customize-group ido-ubiquitous' and review the
1206 override variables and save them to your customization file."
1207 :warning))))
1208
1209 (defun ido-ubiquitous-initialize ()
1210 "Do initial setup for ido-ubiquitous.
1211
1212 This only needs to be called once when the file is first loaded.
1213 It cleans up any traces of old versions of ido-ubiquitous and
1214 then sets up the mode."
1215 (ido-ubiquitous--fixup-old-advice)
1216 (ido-ubiquitous--fixup-old-magit-overrides)
1217 (ido-ubiquitous--maybe-update-overrides)
1218 ;; Make sure the mode is turned on/off as specified by the value of
1219 ;; the mode variable
1220 (ido-ubiquitous-mode (if ido-ubiquitous-mode 1 0)))
1221 (ido-ubiquitous-initialize)
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")
122277
122378 (provide 'ido-ubiquitous)
79
122480 ;; Local Variables:
122581 ;; indent-tabs-mode: nil
122682 ;; End:
55 perl -i'orig_*' -lape "s/Version: [0-9.]+/Version: $TARGET_VERSION/g;" \
66 -e "s/((?:defconst|defvar|setq).*-version\s+)\"[0-9.]+\"/\${1}\"$TARGET_VERSION\"/g;" \
77 -e "s/(Package-Requires.*\(ido-completing-read\+\s+)\"[0-9.]+\"\)/\${1}\"${TARGET_VERSION}\")/g;" \
8 *.el
8 -e "s/\(package \"ido-ubiquitous\" \"[0-9.]+\"/(package \"ido-ubiquitous\" \"${TARGET_VERSION}\"/g" \
9 *.el Cask
910 else
1011 echo "Usage: $0 VERSION_NUMBER"
1112 fi
+0
-567
test/ido-ubiquitous-test.el less more
0 ;;; ido-ubiquitous-test.el --- -*- lexical-binding: t -*-
1
2 ;; Copyright (C) 2015 Ryan C. Thompson
3
4 ;; Filename: ido-ubiquitous-test.el
5 ;; Author: Ryan C. Thompson
6 ;; Created: Tue Oct 6 20:52:45 2015 (-0700)
7
8 ;; This file is NOT part of GNU Emacs.
9
10 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11 ;;
12 ;; This program is free software: you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation, either version 3 of the License, or (at
15 ;; your option) any later version.
16 ;;
17 ;; This program is distributed in the hope that it will be useful, but
18 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 ;; General Public License for more details.
21 ;;
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
24 ;;
25 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26 ;;
27 ;;; Code:
28
29 (require 'ido-completing-read+)
30 (require 'ido-ubiquitous)
31 (require 'ert)
32 (require 'cl-lib)
33
34 ;; This is a series of macros to facilitate the testing of completion
35 ;; non-interactively by simulating input.
36
37 (defmacro keyboard-quit-to-error (&rest body)
38 "Evaluate BODY but signal an error on `keyboard-quit'."
39 `(condition-case nil
40 (progn ,@body)
41 (quit
42 (error "Caught `keyboard-quit'"))))
43
44 (defmacro with-simulated-input (keys &rest body)
45 "Eval body with KEYS as simulated input.
46
47 This macro is intended for testing normally interactive functions
48 by simulating input. If BODY tries to read more input events than
49 KEYS provides, `keyboard-quit' is invoked (by means of appending
50 multple C-g keys to KEYS). This is to ensure that BODY will never
51 block waiting for input, since this macro is intended for
52 noninteractive use. As such, BODY should not invoke
53 `keyboard-quit' under normal operation, and KEYS should not
54 include C-g, or this macro will interpret it as reading past the
55 end of input."
56 ;; It would be better to detect end-of-input by overriding
57 ;; `read-event' to throw an error, since theoretically C-g could be
58 ;; rebound to something other than `keyboard-quit'. But apparently
59 ;; some functions read input directly in C code, and redefining
60 ;; `read-event' has no effect on those. So the suboptimal solution
61 ;; is to rely on C-g.
62 (declare (indent 1))
63 `(let* ((key-sequence (listify-key-sequence (kbd ,keys)))
64 (C-g-key-sequence
65 (listify-key-sequence
66 ;; We *really* want to trigger `keyboard-quit' if we reach
67 ;; the end of the input.
68 (kbd "C-g C-g C-g C-g C-g C-g C-g")))
69 (unread-command-events
70 (append key-sequence C-g-key-sequence)))
71 (when (member (car C-g-key-sequence) key-sequence)
72 (error "KEYS must not include C-g"))
73 (condition-case nil
74 (progn ,@body)
75 (quit
76 (error "Reached end of simulated input while evaluating body")))))
77
78 (defmacro with-mode (mode arg &rest body)
79 "Eval (MODE ARG), then body, then restore previous status of MODE.
80
81 This will only work on modes that respect the normal conventions
82 for activation and deactivation."
83 (declare (indent 2))
84 `(let* ((orig-status ,mode)
85 (restore-arg (if orig-status 1 0)))
86 (unwind-protect
87 (progn
88 (,mode ,arg)
89 ,@body)
90 (message "Restoring mode %s to %s" ',mode restore-arg)
91 (,mode restore-arg))))
92
93 (defmacro with-ido-ubiquitous-standard-env (&rest body)
94 "Execute BODY with standard ido-ubiquitous settings.\n\nAll ido-ubiquitous and ido-cr+ options will be let-bound to their\ndefault values, and `ido-ubiquitous-mode' will be enabled."
95 (declare (indent 0))
96 (let*
97 ((ido-ubiquitous-options
98 '(ido-ubiquitous-allow-on-functional-collection
99 ido-ubiquitous-command-overrides
100 ido-ubiquitous-debug-mode
101 ido-ubiquitous-default-state
102 ido-ubiquitous-function-overrides
103 ido-cr+-fallback-function
104 ido-cr+-max-items
105 ido-cr+-replace-completely
106 ido-confirm-unique-completion))
107 (idu-bindings
108 (cl-loop for var in ido-ubiquitous-options collect
109 (list var
110 (list 'quote
111 (eval (car (get var 'standard-value))))))))
112 `(with-mode ido-ubiquitous-mode 1
113 (let ,idu-bindings ,@body))))
114
115 (defmacro collection-as-function (collection)
116 "Return a function equivalent to COLLECTION.
117
118 The returned function will work equivalently to COLLECTION when
119 passed to `all-completions' and `try-completion'."
120 `(completion-table-dynamic (lambda (string) (all-completions string ,collection))))
121
122 (cl-defmacro should-with-tag (form &key tag)
123 "Equivalent to `(should FORM)' but with a TAG on the output.
124
125 This is useful if the same `should' form will be called multiple
126 times in different contexts. Each test can pass a different tag
127 so it's clear in the ERT output which context is causing the
128 failure.
129
130 Note that although this is a macro, the TAG argument is evaluated normally."
131 `(let ((tagvalue ,tag))
132 (condition-case err
133 (should ,form)
134 (ert-test-failed
135 (message "Error symbol: %S" (car err))
136 (message "Error data: %S" (cdr err))
137 (when tagvalue
138 (setf (cadr err) (append (cadr err) (list :tag tagvalue))))
139 (message "New error data: %S" (cdr err))
140 (signal (car err) (cdr err))))))
141
142 (defun plist-delete (plist property)
143 "Delete PROPERTY from PLIST.
144 This is in contrast to merely setting it to 0."
145 (let (p)
146 (while plist
147 (if (not (eq property (car plist)))
148 (setq p (plist-put p (car plist) (nth 1 plist))))
149 (setq plist (cddr plist)))
150 p))
151
152 (cl-defmacro should-error-with-tag (form &rest other-keys &key tag &allow-other-keys)
153 "Equivalent to `(should FORM)' but with a TAG on the output.
154 See `should-with-tag'.
155
156 Note that although this is a macro, the TAG argument is evaluated normally."
157 (setq other-keys (plist-delete other-keys :tag))
158 `(let ((tagvalue ,tag))
159 (condition-case err
160 (should-error ,form ,@other-keys)
161 (ert-test-failed
162 (message "Error symbol: %S" (car err))
163 (message "Error data: %S" (cdr err))
164 (when tagvalue
165 (setf (cadr err) (append (cadr err) (list :tag tagvalue))))
166 (message "New error data: %S" (cdr err))
167 (signal (car err) (cdr err))))))
168
169 (defun test-ido-ubiquitous-expected-mode (override &optional tag)
170 "Test whether observed ido-ubiquitous behavior matches OVERRIDE."
171 (declare (indent 1))
172 (if (eq override 'disable)
173 (progn
174 (should-with-tag
175 ;; Verify that we get standard completion
176 (string=
177 "g"
178 (with-simulated-input "g RET"
179 (completing-read "Prompt: " '("blue" "yellow" "green"))))
180 :tag tag)
181 (should-with-tag
182 (string=
183 "green"
184 (with-simulated-input "g RET"
185 (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
186 :tag tag)
187 ;; Standard completion should refuse to finish with incomplete
188 ;; input if match is required
189 (should-error-with-tag
190 (with-simulated-input "b RET"
191 (completing-read "Prompt: " '("brown" "blue" "yellow" "green") nil t))
192 :type 'error
193 :tag tag))
194 ;; Common tests whenever ido-ubiquitous is enabled in any way
195 (should-with-tag
196 ;; Verify that ido completion is active
197 (string=
198 "green"
199 (with-simulated-input "g RET"
200 (completing-read "Prompt: " '("blue" "yellow" "green"))))
201 :tag tag)
202 ;; Verify that C-j is working correctly
203 (should-with-tag
204 (string=
205 "g"
206 (with-simulated-input "g C-j"
207 (completing-read "Prompt: " '("blue" "yellow" "green"))))
208 :tag tag)
209 (let ((collection '("brown" "blue" "yellow" "green")))
210 (should-with-tag
211 (member
212 (with-simulated-input "b RET"
213 (completing-read "Prompt: " collection))
214 (all-completions "b" collection))
215 :tag tag))
216 (cl-case override
217 (enable
218 ;; Test for new style
219 (should-with-tag
220 (string=
221 "blue"
222 (with-simulated-input "RET"
223 (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
224 :tag tag)
225 (should-with-tag
226 (string=
227 ""
228 (with-simulated-input "C-j"
229 (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
230 :tag tag))
231 (enable-old
232 (should-with-tag
233 (string=
234 ""
235 (with-simulated-input "RET"
236 (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
237 :tag tag)
238 (should-with-tag
239 (string=
240 "blue"
241 (with-simulated-input "C-j"
242 (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
243 :tag tag)
244 ;; Verify that doing other stuff reverts RET and C-j to standard
245 ;; meanings
246 (should-with-tag
247 (string=
248 "blue"
249 (with-simulated-input "g DEL RET"
250 (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
251 :tag tag)
252 (should-with-tag
253 (string=
254 "blue"
255 (with-simulated-input "<right> <left> RET"
256 (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
257 :tag tag)
258 (should-with-tag
259 (string=
260 ""
261 (with-simulated-input "g DEL C-j"
262 (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
263 :tag tag)
264 (should-with-tag
265 (string=
266 ""
267 (with-simulated-input "<right> <left> C-j"
268 (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
269 :tag tag))
270 (otherwise (error "Unknown override %S" override)))))
271
272 (defvar original-completing-read (symbol-function #'completing-read))
273
274 (defun test-ido-ubiquitous-expected-mode-on-functional-collection (override &optional tag)
275 "Test whether observed ido-ubiquitous behavior on functional collection matches OVERRIDE."
276 (declare (indent 1))
277 ;; This just temporarily replaces `completing-read' with a wrapper
278 ;; that always converts the collection argument to an equivalent
279 ;; function. That way, any use of `completing-read' will always see
280 ;; a functional collection.
281 (cl-letf (((symbol-function 'completing-read)
282 (lambda (prompt collection &rest args)
283 (apply original-completing-read prompt
284 (collection-as-function collection)
285 args))))
286 (test-ido-ubiquitous-expected-mode override tag)))
287
288 (ert-deftest ido-ubiquitous-test-simple ()
289 :tags '(ido ido-ubiquitous)
290 "Test that basic ido-ubiquitous functionality is working."
291 (with-ido-ubiquitous-standard-env
292 (ido-ubiquitous-mode 1)
293 (test-ido-ubiquitous-expected-mode 'enable
294 :simple-enable)
295 (ido-ubiquitous-mode 0)
296 (test-ido-ubiquitous-expected-mode 'disable
297 :simple-disable)))
298
299 (ert-deftest ido-ubiquitous-test-oldstyle ()
300 :tags '(ido ido-ubiquitous)
301 "Test whether old-style completion works as expected."
302 (with-ido-ubiquitous-standard-env
303 (let ((ido-ubiquitous-default-state 'enable-old))
304 (test-ido-ubiquitous-expected-mode 'enable-old
305 :simple-oldstyle))))
306
307 (ert-deftest ido-ubiquitous-test-maxitems ()
308 :tags '(ido ido-ubiquitous)
309 "Test whether the large-collection fallback works."
310 (with-ido-ubiquitous-standard-env
311 (let ((ido-cr+-max-items -1))
312 (test-ido-ubiquitous-expected-mode 'disable
313 :maxitems))))
314
315 (ert-deftest ido-ubiquitous-test-override ()
316 :tags '(ido ido-ubiquitous)
317 "Test whether ido-ubiquitous overrides work."
318 (with-ido-ubiquitous-standard-env
319 (ido-ubiquitous-with-override 'enable
320 (test-ido-ubiquitous-expected-mode 'enable
321 :override-enable))
322 (ido-ubiquitous-with-override 'enable-old
323 (test-ido-ubiquitous-expected-mode 'enable-old
324 :override-enable-old))
325 (ido-ubiquitous-with-override 'disable
326 (test-ido-ubiquitous-expected-mode 'disable
327 :override-disable))))
328
329 (ert-deftest ido-ubiquitous-test-functional-collection ()
330 :tags '(ido ido-ubiquitous)
331 "Test whether ido-ubiquitous overrides work when collection is a function."
332 (with-ido-ubiquitous-standard-env
333 (test-ido-ubiquitous-expected-mode-on-functional-collection 'disable
334 :collfunc)
335 (ido-ubiquitous-with-override 'enable
336 (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable
337 :override-enable-collfunc))
338 (ido-ubiquitous-with-override 'enable-old
339 (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable-old
340 :override-enable-old-collfunc))))
341
342 (ert-deftest ido-cr+-require-match ()
343 :tags '(ido ido-cr+)
344 "Test whether require-match works."
345 (with-ido-ubiquitous-standard-env
346 ;; "C-j" should be allowed to return an empty string even if
347 ;; require-match is non-nil, as long as default is nil
348 (should
349 (string=
350 ""
351 (with-simulated-input "C-j"
352 (ido-completing-read+
353 "Prompt: "
354 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t))))
355 ;; "C-j" should NOT be allowed to return an empty string if
356 ;; require-match and default are both non-nil.
357 (should-error
358 (with-simulated-input "C-j"
359 (ido-completing-read+
360 "Prompt: "
361 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t nil nil "yellow")))
362 ;; Multiple presses of C-j won't just select the first match
363 (should-error
364 (with-simulated-input "b C-j C-j C-j"
365 (ido-completing-read+
366 "Prompt: "
367 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t)))
368 ;; First press of C-j should complete unique common prefix after the
369 ;; first b, but then get stuck on the choice for the second b.
370 (should-error
371 (with-simulated-input "b C-j b C-j C-j"
372 (ido-completing-read+
373 "Prompt: "
374 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t)))
375 ;; This should complete to "blueberry" via 2 rounds of unique common
376 ;; prefix completion, and then return on the 3rd "C-j"
377 (should
378 (string=
379 "blueberry"
380 (with-simulated-input "b C-j b C-j e C-j C-j"
381 (ido-completing-read+
382 "Prompt: "
383 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t))))
384 ;; The "C-j" should complete to "bluegrass" and return, because
385 ;; `ido-confirm-unique-completion is nil.
386 (should
387 (string=
388 "bluegrass"
389 (with-simulated-input "b l u e g C-j"
390 (ido-completing-read+
391 "Prompt: "
392 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t))))
393 (let ((ido-confirm-unique-completion t))
394 ;; Now the first "C-j" should complete to "bluegrass" but should
395 ;; not return.
396 (should-error
397 (with-simulated-input "b l u e g C-j"
398 (ido-completing-read+
399 "Prompt: "
400 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t)))
401 ;; The first "C-j" should complete to "bluegrass", and the second
402 ;; should return.
403 (should
404 (string=
405 "bluegrass"
406 (with-simulated-input "b l u e g C-j C-j"
407 (ido-completing-read+
408 "Prompt: "
409 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t)))))
410 ;; Finally, a few tests for the expected wrong behavior without
411 ;; ido-cr+. If ido.el ever fixes this bug, it will cause this test
412 ;; to fail as a signal that the workaround can be phased out.
413 (should
414 (string=
415 ""
416 (with-simulated-input "C-j"
417 (ido-completing-read
418 "Prompt: "
419 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t))))
420 (should
421 (string=
422 "b"
423 (with-simulated-input "b C-j"
424 (ido-completing-read
425 "Prompt: "
426 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t))))))
427
428 ;; Functions to define overrides on for testing
429 (defun idu-no-override-testfunc ()
430 (test-ido-ubiquitous-expected-mode 'enable
431 :func-override-none)
432 (test-ido-ubiquitous-expected-mode-on-functional-collection 'disable
433 :func-override-none-collfunc))
434 (defun idu-enabled-testfunc (&rest args)
435 (test-ido-ubiquitous-expected-mode 'enable
436 :func-override-enable)
437 (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable
438 :func-override-enable-collfunc))
439 (defun idu-disabled-testfunc (&rest args)
440 (test-ido-ubiquitous-expected-mode 'disable
441 :func-override-disable)
442 (test-ido-ubiquitous-expected-mode-on-functional-collection 'disable
443 :func-override-disable-collfunc))
444 (defun idu-enabled-oldstyle-testfunc (&rest args)
445 (test-ido-ubiquitous-expected-mode 'enable-old
446 :func-override-enable-old)
447 (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable-old
448 :func-override-enable-old-collfunc))
449
450 ;; commands to define overrides on for testing
451 (defun idu-no-override-testcmd (&rest args)
452 (interactive
453 (list
454 (test-ido-ubiquitous-expected-mode 'enable
455 :cmd-override-none)
456 (test-ido-ubiquitous-expected-mode-on-functional-collection 'disable
457 :cmd-override-none-collfunc)))
458 (test-ido-ubiquitous-expected-mode 'enable
459 :cmd-override-none)
460 (test-ido-ubiquitous-expected-mode-on-functional-collection 'disable
461 :cmd-override-non-collfunc))
462 (defun idu-enabled-testcmd (&rest args)
463 (interactive
464 (list
465 (test-ido-ubiquitous-expected-mode 'enable
466 :cmd-override-enable)
467 (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable
468 :cmd-override-enable-collfunc)))
469 (test-ido-ubiquitous-expected-mode 'enable
470 :cmd-override-enable)
471 (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable
472 :cmd-override-enable-collfunc))
473 (defun idu-disabled-testcmd (&rest args)
474 (interactive
475 (list
476 (test-ido-ubiquitous-expected-mode 'disable
477 :cmd-override-disable)
478 (test-ido-ubiquitous-expected-mode-on-functional-collection 'disable
479 :cmd-override-disable-collfunc)))
480 (test-ido-ubiquitous-expected-mode 'disable
481 :cmd-override-disable)
482 (test-ido-ubiquitous-expected-mode-on-functional-collection 'disable
483 :cmd-override-disable-collfunc))
484 (defun idu-enabled-oldstyle-testcmd (&rest args)
485 (interactive
486 (list
487 (test-ido-ubiquitous-expected-mode 'enable-old
488 :cmd-override-enable-old)
489 (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable-old
490 :cmd-override-enable-old-collfunc)))
491 (test-ido-ubiquitous-expected-mode 'enable-old
492 :cmd-override-enable-old)
493 (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable-old
494 :cmd-override-enable-old-collfunc))
495
496 (ert-deftest ido-ubiquitous-test-command-and-function-overrides ()
497 :tags '(ido ido-ubiquitous)
498 "Test whether command- and function-specific overrides work."
499 (let ((orig-func-overrides ido-ubiquitous-function-overrides)
500 (orig-cmd-overrides ido-ubiquitous-command-overrides))
501 (unwind-protect
502 (with-ido-ubiquitous-standard-env
503 (customize-set-variable
504 'ido-ubiquitous-function-overrides
505 (append ido-ubiquitous-function-overrides
506 '((enable exact "idu-enabled-testfunc")
507 (disable exact "idu-disabled-testfunc")
508 (enable-old exact "idu-enabled-oldstyle-testfunc"))))
509 (cl-loop for func in
510 '(idu-no-override-testfunc
511 idu-enabled-testfunc
512 idu-disabled-testfunc
513 idu-enabled-oldstyle-testfunc)
514 do (funcall func))
515 (customize-set-variable
516 'ido-ubiquitous-command-overrides
517 (append ido-ubiquitous-command-overrides
518 '((enable exact "idu-enabled-testcmd")
519 (disable exact "idu-disabled-testcmd")
520 (enable-old exact "idu-enabled-oldstyle-testcmd"))))
521 (cl-loop for cmd in
522 '(idu-no-override-testcmd
523 idu-enabled-testcmd
524 idu-disabled-testcmd
525 idu-enabled-oldstyle-testcmd)
526 do (call-interactively cmd)))
527 (customize-set-variable 'ido-ubiquitous-function-overrides orig-func-overrides)
528 (customize-set-variable 'ido-ubiquitous-command-overrides orig-cmd-overrides))))
529
530 (ert-deftest ido-ubiquitous-test-fallback ()
531 :tags '(ido ido-ubiquitous)
532 "Test whether manually invoking fallback works."
533 (with-ido-ubiquitous-standard-env
534 (should
535 ;; C-b/f not at beginning/end of input should not fall back
536 (string=
537 "green"
538 (with-simulated-input "g C-b C-f RET"
539 (completing-read "Prompt: " '("blue" "yellow" "green")))))
540 (should
541 ;; C-f at end of input should fall back
542 (string=
543 "g"
544 (with-simulated-input "g C-f RET"
545 (completing-read "Prompt: " '("blue" "yellow" "green")))))
546 (should
547 ;; Repeated C-b should not fall back
548 (string=
549 "green"
550 (with-simulated-input "g C-b C-b C-b C-b RET"
551 (completing-read "Prompt: " '("blue" "yellow" "green")))))
552 (should
553 ;; C-b at beginning of line should fall back (if previous action
554 ;; was not also C-b)
555 (string=
556 "g"
557 (with-simulated-input "g C-b x DEL C-b RET"
558 (completing-read "Prompt: " '("blue" "yellow" "green")))))))
559
560 (defun ido-ubiquitous-run-all-tests ()
561 (interactive)
562 (ert "^ido-\\(ubiquitous\\|cr\\+\\)-"))
563
564 (provide 'ido-ubiquitous-test)
565
566 ;;; ido-ubiquitous-test.el ends here
+0
-41
test/test-helper.el less more
0 ;;; test-helper.el --- -*- lexical-binding: t -*-
1
2 ;; Copyright (C) 2015 Ryan C. Thompson
3
4 ;; Filename: test-helper.el
5 ;; Author: Ryan C. Thompson
6 ;; Created: Sat Nov 21 15:27:00 2015 (-0800)
7
8 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9 ;;
10 ;; This program is free software: you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation, either version 3 of the License, or (at
13 ;; your option) any later version.
14 ;;
15 ;; This program is distributed in the hope that it will be useful, but
16 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 ;; General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
22 ;;
23 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
24 ;;
25 ;;; Code:
26
27 (require 'f)
28
29 (defvar test-path
30 (f-dirname (f-this-file)))
31
32 (defvar code-path
33 (f-parent test-path))
34
35 (add-to-list 'load-path code-path)
36
37 (require 'ido-completing-read+)
38 (require 'ido-ubiquitous)
39
40 ;;; test-helper.el ends here
0 ;;; -*- lexical-binding: t -*-
1
2 (require 'ido)
3 (require 'ido-completing-read+)
4 (require 'buttercup)
5 (require 'cl-lib)
6 (require 'with-simulated-input)
7
8 (defun collection-as-function (collection)
9 "Return a function equivalent to COLLECTION.
10
11 The returned function will work equivalently to COLLECTION when
12 passed to `all-completions' and `try-completion'."
13 (completion-table-dynamic (lambda (string) (all-completions string collection))))
14
15 (defun shadow-var (var &optional temp-value)
16 "Shadow the value of VAR.
17
18 This will push the current value of VAR to VAR's
19 `shadowed-values' property, and then set it to TEMP-VALUE. To
20 reverse this process, call `unshadow-var' on VAR. Vars can
21 be shadowed recursively, and must be unshadowed once for each
22 shadowing in order to restore the original value. You can think
23 of shadowing as dynamic binding with `let', but with manual
24 control over when bindings start and end.
25
26 If VAR is a Custom variable (see `custom-variable-p'), it will be
27 set using `customize-set-variable', and if TEMP-VALUE is nil it
28 will be replaces with VAR's standard value.
29
30 Other variables will be set with `set-default', and a TEMP-VALUE
31 of nil will not be treated specially.
32
33 `shadow-var' only works on variables declared as special (i.e.
34 using `defvar' or similar). It will not work on lexically bound
35 variables."
36 (unless (special-variable-p var)
37 (error "Cannot shadow lexical var `%s'" var))
38 (let* ((use-custom (custom-variable-p var))
39 (setter (if use-custom 'customize-set-variable 'set-default))
40 (temp-value (or temp-value
41 (and use-custom
42 (eval (car (get var 'standard-value)))))))
43 ;; Push the current value on the stack
44 (push (symbol-value var) (get var 'shadowed-values))
45 (funcall setter var temp-value)))
46
47 (defun var-shadowed-p (var)
48 "Return non-nil if VAR is shadowed by `shadow-var'."
49 ;; We don't actually want to return that list if it's non-nil.
50 (and (get var 'shadowed-values) t))
51
52 (defun unshadow-var (var)
53 "Reverse the last call to `shadow-var' on VAR."
54 (if (var-shadowed-p var)
55 (let* ((use-custom (custom-variable-p var))
56 (setter (if use-custom 'customize-set-variable 'set-default))
57 (value (pop (get var 'shadowed-values))))
58 (funcall setter var value))
59 (error "Var is not shadowed: %s" var)))
60
61 (defun fully-unshadow-var (var)
62 "Reverse *all* calls to `shadow-var' on VAR."
63 (when (var-shadowed-p var)
64 (let* ((use-custom (custom-variable-p var))
65 (setter (if use-custom 'customize-set-variable 'set-default))
66 (value (car (last (get var 'shadowed-values)))))
67 (put var 'shadowed-values nil)
68 (funcall setter var value))))
69
70 (defun fully-unshadow-all-vars (&optional vars)
71 "Reverse *all* calls to `shadow-var' on VARS.
72
73 If VARS is nil, unshadow *all* variables."
74 (if vars
75 (mapc #'fully-unshadow-var vars)
76 (mapatoms #'fully-unshadow-var))
77 nil)
78
79 (defmacro shadow-vars (varlist)
80 "Shadow a list of vars with new values.
81
82 VARLIST describes the variables to be shadowed with the same
83 syntax as `let'.
84
85 See `shadow-var'."
86 (declare (indent 0))
87 (cl-loop
88 with var = nil
89 with value = nil
90 for binding in varlist
91 if (symbolp binding)
92 do (setq var binding
93 value nil)
94 else
95 do (setq var (car binding)
96 value (cadr binding))
97 collect `(shadow-var ',var ,value) into exprs
98 finally return `(progn ,@exprs)))
99
100 (defmacro unshadow-vars (vars)
101 "Un-shadow a list of VARS.
102
103 This is a macro for consistency with `shadow-vars', but it will
104 also accept a quoted list for the sake of convenience."
105 (declare (indent 0))
106 (when (eq (car vars) 'quote)
107 (setq vars (eval vars)))
108 `(mapc #'unshadow-var ',vars))
109
110 (describe "Within the `ido-completing-read+' package"
111
112 ;; Reset all of these variables to their standard values before each
113 ;; test, saving the previous values for later restoration.
114 (before-each
115 (shadow-vars
116 ((ido-mode t)
117 (ido-ubiquitous-mode t)
118 ido-cr+-debug-mode
119 ido-cr+-auto-update-blacklist
120 ido-cr+-fallback-function
121 ido-cr+-max-items
122 ido-cr+-function-blacklist
123 ido-cr+-function-whitelist
124 ido-cr+-nil-def-alternate-behavior-list
125 ido-cr+-replace-completely
126 ido-confirm-unique-completion
127 ido-enable-flex-matching)))
128
129 ;; Restore the saved values after each test
130 (after-each
131 (fully-unshadow-all-vars))
132
133 (describe "the `ido-completing-read+' function"
134
135 (it "should complete with a matching item on RET"
136 (expect
137 (with-simulated-input "g RET"
138 (ido-completing-read+ "Prompt: " '("blue" "yellow" "green")))
139 :to-equal "green"))
140 (it "should complete with the first match when multiple matches are available"
141 (expect
142 (with-simulated-input "b RET"
143 (ido-completing-read+ "Prompt: " '("brown" "blue" "yellow" "green")))
144 :to-equal "brown"))
145 (it "should allow <left> and <right> to cycle completions, with wrap-around"
146 (expect
147 (with-simulated-input "b <right> <right> <right> <right> <left> RET"
148 (ido-completing-read+ "Prompt: " '("brown" "blue" "yellow" "green")))
149 :to-equal
150 "blue"))
151
152 (it "should return \"\" when RET or C-j is pressed on an empty input even when REQUIRE-MATCH is non-nil"
153 ;; No REQUIRE-MATCH
154 (expect
155 (with-simulated-input "RET"
156 (ido-completing-read+ "Prompt: " '("blue" "yellow" "green")))
157 :to-equal "blue")
158 (expect
159 (with-simulated-input "C-j"
160 (ido-completing-read+ "Prompt: " '("blue" "yellow" "green")))
161 :to-equal "")
162 ;; Again, with REQUIRE-MATCH
163 (expect
164 (with-simulated-input "RET"
165 (ido-completing-read+ "Prompt: " '("blue" "yellow" "green") nil t))
166 :to-equal "")
167 (expect
168 (with-simulated-input "C-j"
169 (ido-completing-read+ "Prompt: " '("blue" "yellow" "green") nil t))
170 :to-equal ""))
171
172 ;; Verify that DEF works, whether or not it is an element of
173 ;; COLLECTION
174 (it "should accept all the same forms of DEF as `completing-read-default'"
175 (expect
176 (with-simulated-input "RET"
177 (ido-completing-read+ "Prompt: " '("blue" "yellow" "green") nil nil nil nil "green"))
178 :to-equal "green")
179 (expect
180 (with-simulated-input "RET"
181 (ido-completing-read+ "Prompt: " '("blue" "yellow" "green") nil t nil nil "green"))
182 :to-equal "green")
183 (expect
184 (with-simulated-input "RET"
185 (ido-completing-read+ "Prompt: " '("blue" "yellow" "brown") nil nil nil nil "brown"))
186 :to-equal "brown")
187 (expect
188 (with-simulated-input "RET"
189 (ido-completing-read+ "Prompt: " '("blue" "yellow" "brown") nil t nil nil "brown"))
190 :to-equal "brown")
191 (expect
192 (with-simulated-input "RET"
193 (ido-completing-read+ "Prompt: " '("blue" "yellow" "brown") nil t nil nil '("brown" "green")))
194 :to-equal "brown"))
195
196 ;; Verify that INITIAL-INPUT works
197 (it "should work with INITIAL-INPUT"
198 (expect
199 (with-simulated-input "RET"
200 (ido-completing-read+ "Prompt: " '("blue" "yellow" "green") nil nil "gr"))
201 :to-equal "green"))
202
203 ;; Verify that INITIAL-INPUT and DEF don't interfere with each other
204 (it "should properly handle both INITIAL-INPUT and DEF at the same time"
205 (expect
206 (with-simulated-input "RET"
207 (ido-completing-read+ "Prompt: " '("blue" "yellow" "green") nil nil "gr" nil "blue"))
208 :to-equal "green")
209 (expect
210 (with-simulated-input "DEL DEL RET"
211 (ido-completing-read+ "Prompt: " '("blue" "yellow" "green") nil nil "gr" nil "blue"))
212 :to-equal "blue"))
213
214 ;; Verify that ido-cr+ works on function collections
215 (it "should work when COLLECTION is a function"
216 (expect
217 (with-simulated-input "g RET"
218 (ido-completing-read+ "Prompt: " (collection-as-function '("blue" "yellow" "green"))))
219 :to-equal "green"))
220
221 (describe "when `ido-cr+-max-items' is set"
222 (it "should not trigger a fallback for small collections"
223 (expect
224 (with-simulated-input "g RET"
225 (ido-completing-read+ "Prompt: " '("blue" "yellow" "green")))
226 :to-equal "green"))
227 (it "should trigger a fallback for large collections"
228 (expect
229 ;; With max-items negative, all collections are considered "too
230 ;; large"
231 (let ((ido-cr+-max-items -1))
232 (with-simulated-input "g RET"
233 (ido-completing-read+ "Prompt: " '("blue" "yellow" "green"))))
234 :to-equal "g")))
235
236 (describe "when REQUIRE-MATCH is non-nil"
237 (it "should still allow exiting with an empty string if DEF is nil"
238 (expect
239 (with-simulated-input "C-j"
240 (ido-completing-read+
241 "Prompt: "
242 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t))
243 :to-equal ""))
244 ;; "C-j" should NOT be allowed to return an empty string if
245 ;; require-match and default are both non-nil.
246 (it "should not alow exiting with an empty string if DEF is non-nil"
247 (expect
248 (with-simulated-input "C-j"
249 (ido-completing-read+
250 "Prompt: "
251 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t nil nil "yellow"))
252 :to-throw))
253 (it "shouldn't allow C-j to select an ambiguous match"
254 (expect
255 (with-simulated-input "b C-j C-j C-j"
256 (ido-completing-read+
257 "Prompt: "
258 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t))
259 :to-throw)
260 ;; First press of C-j should complete to "blue" after the
261 ;; first b, but then get stuck on the choice for the second b.
262 (expect
263 (with-simulated-input "b C-j b C-j C-j C-j"
264 (ido-completing-read+
265 "Prompt: "
266 '("bluebird" "blues" "bluegrass" "blueberry" "yellow" "green") nil t))
267 :to-throw))
268 (it "should allow exiting with an unambiguous match"
269 (expect
270 (with-simulated-input "b C-j b C-j e C-j C-j"
271 (ido-completing-read+
272 "Prompt: "
273 '("bluebird" "blues" "bluegrass" "blueberry" "yellow" "green") nil t))
274 :to-equal "blueberry")
275 ;; The "C-j" should complete to "bluegrass" and return, because
276 ;; `ido-confirm-unique-completion is nil.
277 (expect
278 (with-simulated-input "b l u e g C-j"
279 (ido-completing-read+
280 "Prompt: "
281 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t))
282 :to-equal "bluegrass"))
283 (it "should require an extra C-j to exit when `ido-confirm-unique-completion' is non-nil"
284 (setq ido-confirm-unique-completion t)
285 ;; Now the first "C-j" should complete to "bluegrass" but should
286 ;; not return.
287 (expect
288 (with-simulated-input "b l u e g C-j"
289 (ido-completing-read+
290 "Prompt: "
291 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t))
292 :to-throw)
293 ;; The first "C-j" should complete to "bluegrass", and the second
294 ;; should return.
295 (expect
296 (with-simulated-input "b l u e g C-j C-j"
297 (ido-completing-read+
298 "Prompt: "
299 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t))
300 :to-equal "bluegrass"))
301
302 ;; Finally, a test for the expected wrong behavior without
303 ;; ido-cr+. If ido.el ever fixes this bug, it will cause this test
304 ;; to fail as a signal that the workaround can be phased out.
305 (it "should return a non-match when ordinary `ido-completing-read' is used"
306 (expect
307 (with-simulated-input "b C-j"
308 (ido-completing-read
309 "Prompt: "
310 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t))
311 :to-equal "b")))
312
313 (describe "with manual fallback shortcuts"
314 (it "should not fall back when C-b or C-f is used in the middle of the input"
315 (expect
316 ;; C-b/f not at beginning/end of input should not fall back
317 (with-simulated-input "g C-b C-f RET"
318 (ido-completing-read+ "Prompt: " '("blue" "yellow" "green")))
319 :to-equal "green"))
320 (it "should fall back on C-f at end of input"
321 (expect
322 ;; C-f at end of input should fall back
323 (with-simulated-input "g C-f RET"
324 (ido-completing-read+ "Prompt: " '("blue" "yellow" "green")))
325 :to-equal "g"))
326 (it "should not fall back from repeated C-b that hits the start of input"
327 (expect
328 ;; Repeated C-b should not fall back
329 (with-simulated-input "g C-b C-b C-b C-b RET"
330 (ido-completing-read+ "Prompt: " '("blue" "yellow" "green")))
331 :to-equal "green"))
332 (it "should fall back on C-b at beginning of input (if previous action was not C-b)"
333 (expect
334 ;; C-b at beginning of line should fall back (if previous action
335 ;; was not also C-b)
336 (with-simulated-input "g C-b x DEL C-b RET"
337 (ido-completing-read+ "Prompt: " '("blue" "yellow" "green")))
338 :to-equal "g")))
339
340 (describe "with a workaround for an bug with non-nil `ido-enable-dot-prefix'"
341 ;; See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=26997
342 ;; for more information on this bug.
343 (before-each
344 (setq ido-enable-dot-prefix t))
345 (it "should not throw an error when \"\" is in the collection"
346 (expect
347 (with-simulated-input "RET"
348 (ido-completing-read+ "Pick: " '("" "aaa" "aab" "aac")))
349 :to-equal "")
350 (expect
351 (with-simulated-input "a a b RET"
352 (ido-completing-read+ "Pick: " '("" "aaa" "aab" "aac")))
353 :to-equal "aab")))
354
355 (describe "with dynamic collections"
356 (before-all
357 (setq my-dynamic-collection
358 (completion-table-dynamic
359 (lambda (text)
360 (cond
361 ;; Sub-completions for "hello"
362 ((s-prefix-p "hello" text)
363 '("hello" "hello-world" "hello-everyone" "hello-universe"))
364 ;; Sub-completions for "goodbye"
365 ((s-prefix-p "goodbye" text)
366 '("goodbye" "goodbye-world" "goodbye-everyone" "goodbye-universe"))
367 ;; General completions
368 (t
369 '("hello" "goodbye" "helicopter" "helium" "goodness" "goodwill")))))))
370 (after-all
371 (setq my-dynamic-collection nil))
372 (before-each
373 (setq ido-enable-flex-matching t
374 ido-confirm-unique-completion nil)
375 (spy-on 'ido-cr+-update-dynamic-collection
376 :and-call-through))
377
378 (it "should allow selection of dynamically-added completions"
379 (expect
380 (with-simulated-input "hello- RET"
381 (ido-completing-read+ "Say something: " my-dynamic-collection))
382 :to-equal "hello-world")
383 (expect 'ido-cr+-update-dynamic-collection
384 :to-have-been-called))
385
386 (it "should allow ido flex-matching of dynamically-added completions"
387 (expect
388 (with-simulated-input "hello-ld RET"
389 (ido-completing-read+ "Say something: " my-dynamic-collection))
390 :to-equal
391 "hello-world")
392 (expect 'ido-cr+-update-dynamic-collection
393 :to-have-been-called))
394 (it "should do a dynamic update when pressing TAB"
395 (expect
396 (with-simulated-input "h TAB -ld RET"
397 (ido-completing-read+ "Say something: " my-dynamic-collection))
398 :to-equal
399 "hello-world")
400 (expect 'ido-cr+-update-dynamic-collection
401 :to-have-been-called))
402 (it "should do a dynamic update when idle"
403 (expect
404 (with-simulated-input
405 '("h"
406 (wsi-simulate-idle-time (1+ ido-cr+-dynamic-update-idle-time))
407 "-ld RET")
408 (ido-completing-read+ "Say something: " my-dynamic-collection))
409 :to-equal
410 "hello-world")
411 (expect 'ido-cr+-update-dynamic-collection
412 :to-have-been-called))
413 (it "should do a dynamic update when there is only one match remaining"
414 (expect
415 (with-simulated-input "hell-ld RET"
416 (ido-completing-read+ "Say something: " my-dynamic-collection))
417 :to-equal
418 "hello-world")
419 (expect 'ido-cr+-update-dynamic-collection
420 :to-have-been-called))
421 (it "should not exit with a unique match if new matches are dynamically added"
422 (expect
423 (with-simulated-input '("hell TAB -ld RET")
424 (ido-completing-read+ "Say something: " my-dynamic-collection))
425 :to-equal
426 "hello-world")
427 (expect 'ido-cr+-update-dynamic-collection
428 :to-have-been-called))
429 (it "should exit with a match that is still unique after dynamic updating"
430 (expect
431 (with-simulated-input '("helic TAB")
432 (ido-completing-read+ "Say something: " my-dynamic-collection))
433 :to-equal
434 "helicopter")
435 (expect 'ido-cr+-update-dynamic-collection
436 :to-have-been-called))
437 (it "should respect `ido-restrict-to-matches' when doing dynamic updates"
438 (let ((collection
439 (list "aaa-ddd-ggg" "aaa-eee-ggg" "aaa-fff-ggg"
440 "bbb-ddd-ggg" "bbb-eee-ggg" "bbb-fff-ggg"
441 "ccc-ddd-ggg" "ccc-eee-ggg" "ccc-fff-ggg"
442 "aaa-ddd-hhh" "aaa-eee-hhh" "aaa-fff-hhh"
443 "bbb-ddd-hhh" "bbb-eee-hhh" "bbb-fff-hhh"
444 "ccc-ddd-hhh" "ccc-eee-hhh" "ccc-fff-hhh"
445 "aaa-ddd-iii" "aaa-eee-iii" "aaa-fff-iii"
446 "bbb-ddd-iii" "bbb-eee-iii" "bbb-fff-iii"
447 "ccc-ddd-iii" "ccc-eee-iii" "ccc-fff-iii")))
448 ;; Test the internal function
449 (expect
450 (ido-cr+-apply-restrictions
451 collection
452 (list (cons nil "bbb")
453 (cons nil "eee")))
454 :to-equal '("bbb-eee-ggg" "bbb-eee-hhh" "bbb-eee-iii"))
455
456 ;; First verify it without a dynamic collection
457 (expect
458 (with-simulated-input "eee C-SPC bbb C-SPC ggg RET"
459 (ido-completing-read+
460 "Pick: " collection nil t nil nil (car collection)))
461 :to-equal "bbb-eee-ggg")
462 ;; Now test the same with a dynamic collection
463 (expect
464 (with-simulated-input "eee C-SPC bbb C-SPC ggg RET"
465 (ido-completing-read+
466 "Pick: " (collection-as-function collection) nil t nil nil (car collection)))
467 :to-equal "bbb-eee-ggg"))))
468
469 (describe "with unusual inputs"
470 (it "should accept a COLLECTION of symbols"
471 (expect
472 (with-simulated-input "g RET"
473 (ido-completing-read+ "Prompt: " '(blue yellow green)))
474 :to-equal "green"))
475 (it "should accept a mix of strings and symbols in COLLECTION"
476 (expect
477 (with-simulated-input "g RET"
478 (ido-completing-read+ "Prompt: " '(blue "yellow" green)))
479 :to-equal "green"))
480 (it "should accept symbols in DEF"
481 (expect
482 (with-simulated-input "RET"
483 (ido-completing-read+ "Prompt: " '("blue" "yellow" "brown") nil t nil nil '(brown "green")))
484 :to-equal "brown"))
485 (it "should accept an alist COLLECTION"
486 (expect
487 (with-simulated-input "RET"
488 (ido-completing-read+
489 "Prompt: "
490 '(("blue" . blue-value)
491 ("yellow" . yellow-value)
492 (green . green-value))
493 nil nil nil nil "green"))
494 :to-equal "green"))
495 (it "should accept a hash table COLLECTION"
496 (expect
497 (with-simulated-input "RET"
498 (let ((collection (make-hash-table)))
499 (puthash "blue" 'blue-value collection)
500 (puthash "yellow" 'yellow-value collection)
501 (puthash 'green 'green-value collection)
502 (ido-completing-read+ "Prompt: " collection nil nil nil nil "green")))
503 :to-equal "green"))
504 (it "should accept an obarray COLLECTION"
505 (expect
506 (with-simulated-input "forward-char RET"
507 (ido-completing-read+ "Prompt: " obarray #'commandp
508 t nil nil "backward-char"))
509 :to-equal "forward-char"))))
510
511 (describe "ido-ubiquitous-mode"
512 ;; Set up a test command that calls `completing-read'
513 (before-all
514 (setf (symbol-function 'test-command)
515 (lambda ()
516 (interactive)
517 (completing-read "Prompt: " '("blue" "yellow" "green")))))
518 ;; Delete the test command
519 (after-all
520 (setf (symbol-function 'test-command) nil))
521
522 ;; Verify that the mode can be activated
523 (it "should enable itself properly"
524 (expect
525 (progn
526 (ido-ubiquitous-mode 1)
527 (with-simulated-input "g RET"
528 (command-execute 'test-command)))
529 :to-equal "green"))
530 (it "should disable itself properly"
531 (expect
532 (progn
533 (ido-ubiquitous-mode 0)
534 (with-simulated-input "g RET"
535 (command-execute 'test-command)))
536 :to-equal "g"))
537
538 (describe "with `ido-cr+-function-blacklist'"
539 (before-all
540 (setf (symbol-function 'blacklisted-command)
541 (lambda (arg)
542 (interactive (list (completing-read "Prompt: " '("blue" "yellow" "green"))))
543 arg)
544 (symbol-function 'blacklisted-function)
545 (lambda ()
546 (completing-read "Prompt: " '("blue" "yellow" "green")))
547 (symbol-function 'cmd-that-calls-blacklisted-function)
548 (lambda ()
549 (interactive)
550 (funcall 'blacklisted-function))
551 (symbol-function 'blacklisted-collection)
552 (collection-as-function '("blue" "yellow" "green"))))
553 (after-all
554 (setf (symbol-function 'blacklisted-command) nil
555 (symbol-function 'blacklisted-function) nil
556 (symbol-function 'cmd-that-calls-blacklisted-function) nil
557 (symbol-function 'blacklisted-collection) nil))
558 ;; First verify that they work normally before blacklisting them
559 (describe "when the blacklist is empty"
560 (it "should not affect a non-blacklisted command"
561 (expect
562 (with-simulated-input "g RET"
563 (call-interactively 'blacklisted-command))
564 :to-equal "green"))
565 (it "should not affect a non-blacklisted function"
566 (expect
567 (with-simulated-input "g RET"
568 (call-interactively 'cmd-that-calls-blacklisted-function))
569 :to-equal "green"))
570 (it "should not affect a non-blacklisted collection"
571 (expect
572 (with-simulated-input "g RET"
573 (ido-completing-read+ "Prompt: " 'blacklisted-collection))
574 :to-equal "green")))
575
576 (describe "when the specified functions are blacklisted"
577 (before-each
578 (setq ido-cr+-function-blacklist
579 (append '(blacklisted-command
580 blacklisted-function
581 blacklisted-collection)
582 ido-cr+-function-blacklist)))
583 (it "should prevent ido in a blacklisted command"
584 (expect
585 (with-simulated-input "g RET"
586 (call-interactively 'blacklisted-command))
587 :to-equal "g"))
588 (it "should prevent ido in a blacklisted function"
589 (expect
590 (with-simulated-input "g RET"
591 (call-interactively 'cmd-that-calls-blacklisted-function))
592 :to-equal "g"))
593 (it "should prevent ido with a blacklisted collection"
594 (expect
595 (with-simulated-input "g RET"
596 (ido-completing-read+ "Prompt: " 'blacklisted-collection))
597 :to-equal "g"))))
598
599 (describe "with `ido-cr+-function-whitelist'"
600 (before-all
601 (setf (symbol-function 'whitelisted-command)
602 (lambda (arg)
603 (interactive
604 (list
605 (completing-read "Prompt: " '("blue" "yellow" "green"))))
606 arg)
607 (symbol-function 'whitelisted-function)
608 (lambda ()
609 (completing-read "Prompt: " '("blue" "yellow" "green")))
610 (symbol-function 'cmd-that-calls-whitelisted-function)
611 (lambda ()
612 (interactive)
613 (funcall 'whitelisted-function))
614 (symbol-function 'whitelisted-collection)
615 (lambda (string pred action)
616 (complete-with-action action '("blue" "yellow" "green") string pred))))
617 (after-all
618 (setf (symbol-function 'whitelisted-command) nil
619 (symbol-function 'whitelisted-function) nil
620 (symbol-function 'cmd-that-calls-whitelisted-function) nil
621 (symbol-function 'whitelisted-collection) nil))
622 (describe "when the whitelist is inactive (i.e. everything is whitelisted)"
623 (before-each
624 (setq ido-cr+-function-whitelist nil))
625 (it "should enable ido in a command"
626 (expect
627 (with-simulated-input "g RET"
628 (call-interactively 'whitelisted-command))
629 :to-equal "green"))
630 (it "should enable ido in a function"
631 (expect
632 (with-simulated-input "g RET"
633 (call-interactively 'cmd-that-calls-whitelisted-function))
634 :to-equal "green"))
635 (it "should enable ido for a collection"
636 (expect
637 (with-simulated-input "g RET"
638 (ido-completing-read+ "Prompt: " 'whitelisted-collection))
639 :to-equal "green")))
640 (describe "when the specified functions are whitelisted"
641 (before-each
642 (setq ido-cr+-function-whitelist
643 (append '(whitelisted-command
644 whitelisted-function
645 whitelisted-collection)
646 ido-cr+-function-whitelist)))
647 (it "should enable ido in a whitelisted command"
648 (expect
649 (with-simulated-input "g RET"
650 (call-interactively 'whitelisted-command))
651 :to-equal "green"))
652 (it "should enable ido in a whitelisted function"
653 (expect
654 (with-simulated-input "g RET"
655 (call-interactively 'cmd-that-calls-whitelisted-function))
656 :to-equal "green"))
657 (it "should enable ido for a whitelisted collection"
658 (expect
659 (with-simulated-input "g RET"
660 (ido-completing-read+ "Prompt: " 'whitelisted-collection))
661 :to-equal "green")))
662 (describe "when the whitelist is active but empty (i.e. nothing whitelisted)"
663 (before-each
664 (setq ido-cr+-function-whitelist (list nil)))
665 (it "should prevent ido in a command"
666 (expect
667 (with-simulated-input "g RET"
668 (call-interactively 'whitelisted-command))
669 :to-equal "g"))
670 (it "should prevent ido in a function"
671 (expect
672 (with-simulated-input "g RET"
673 (call-interactively 'cmd-that-calls-whitelisted-function))
674 :to-equal "g"))
675 (it "should prevent ido for a collection"
676 (expect
677 (with-simulated-input "g RET"
678 (ido-completing-read+ "Prompt: " 'whitelisted-collection))
679 :to-equal "g"))))
680
681 (describe "with `ido-cr+-nil-def-alternate-behavior-list'"
682 (before-all
683 (setf (symbol-function 'def-nil-command)
684 (lambda (arg)
685 (interactive
686 (list
687 (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
688 arg)
689 (symbol-function 'def-nil-function)
690 (lambda ()
691 (completing-read "Prompt: " '("blue" "yellow" "green") nil t))
692 (symbol-function 'cmd-that-calls-def-nil-function)
693 (lambda ()
694 (interactive)
695 (funcall 'def-nil-function))
696 (symbol-function 'def-nil-collection)
697 (lambda (string pred action)
698 (complete-with-action action '("blue" "yellow" "green") string pred))))
699 (after-all
700 (setf (symbol-function 'def-nil-command) nil
701 (symbol-function 'def-nil-function) nil
702 (symbol-function 'cmd-that-calls-def-nil-function) nil
703 (symbol-function 'def-nil-collection) nil))
704
705 (describe "when the specified functions are not in the list"
706 (before-each
707 (setq ido-cr+-nil-def-alternate-behavior-list nil))
708
709 (it "should use empty string default in a command"
710 (expect
711 (with-simulated-input "RET"
712 (call-interactively 'def-nil-command))
713 :to-equal ""))
714 (it "should use empty string default in a function"
715 (expect
716 (with-simulated-input "RET"
717 (call-interactively 'cmd-that-calls-def-nil-function))
718 :to-equal ""))
719 (it "should use empty string default for a collection"
720 (expect
721 (with-simulated-input "RET"
722 (ido-completing-read+ "Prompt: " 'def-nil-collection nil t))
723 :to-equal "")))
724
725 (describe "when the specified functions are in the list"
726 (before-each
727 (setq ido-cr+-nil-def-alternate-behavior-list
728 (append '(def-nil-command
729 def-nil-function
730 def-nil-collection)
731 ido-cr+-nil-def-alternate-behavior-list)))
732 (it "should not use empty string default in a command"
733 (expect
734 (with-simulated-input "RET"
735 (call-interactively 'def-nil-command))
736 :to-equal "blue"))
737 (it "should not use empty string default in a function"
738 (expect
739 (with-simulated-input "RET"
740 (call-interactively 'cmd-that-calls-def-nil-function))
741 :to-equal "blue"))
742 (it "should not use empty string default for a collection"
743 (expect
744 (with-simulated-input "RET"
745 (ido-completing-read+ "Prompt: " 'def-nil-collection nil t))
746 :to-equal "blue"))))))
747
748 ;; (defun ido-cr+-run-all-tests ()
749 ;; (interactive)
750 ;; (ert "^ido-cr\\+-"))
751
752 ;;; test-ido-completing-read+.el ends here