Codebase list ido-ubiquitous / f69b846
New upstream version 3.14 Lev Lamberov 7 years ago
9 changed file(s) with 2655 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 /.cask
0 ;; -*- mode: emacs-lisp -*-
1
2 (source melpa)
3
4 (package "ido-ubiquitous" "3.8" "Use ido (nearly) everywhere.")
5
6 (development
7 (depends-on "f")
8 (depends-on "ert-runner"))
0 2016-06-18 Ryan C. Thompson <rct@thompsonclan.org>
1
2 * ido-ubiquitous.el (completing-read-ido-ubiquitous): Fix an edge
3 case where COLLECTION is a function and PREDICATE is non-nil. This
4 edge case caused errors in "describe-function" and
5 "describe-variable" in Emacs 25.1.
6 (completing-read-ido-ubiquitous): Make error handling more robust.
7 In addition to falling back to normal completion on a specific set
8 of expected errors, ido-ubiquitous now falls back on *any* error
9 encountered in the body of "completing-read-ido-ubiquitous".
10 (ido-ubiquitous-default-command-overrides): Add override for
11 "describe-function" and "describe-variable", which now require
12 them in Emacs 25.1.
13
14 2016-02-20 Ryan C. Thompson <rct@thompsonclan.org>
15
16 * ido-completing-read+.el (ido-select-text): Eliminate another
17 compiler warning
18
19 2016-02-17 Ryan C. Thompson <rct@thompsonclan.org>
20
21 * test/ido-ubiquitous-test.el: Significant refactoring of awkward
22 testing code. Tests should now be more robust.
23
24 * ido-completing-read+.el (ido-select-text): Fix an edge case in
25 ido-select-text: when require-match and default are both non-nil,
26 it should be impossible to return an empty string.
27 (ido-cr+-fallback-function): Don't allow ido-ubiquitous to be a
28 fallback for ido-cr+.
29
30 2016-01-29 Ryan C. Thompson <rct@thompsonclan.org>
31
32 * ido-ubiquitous.el (ido-ubiquitous--maybe-update-overrides):
33 Change default auto-update setting to notify. If the user has
34 customized overrides and new ones are added upstream, it will nag
35 them until they choose to explicitly enable or disable
36 auto-updating.
37
38 2016-01-16 Rasmus <rasmus@gmx.us>
39
40 * ido-ubiquitous.el (ido-ubiquitous-update-overrides): Remove
41 dependency on s.el.
42
43 2015-11-22 Ryan C. Thompson <rct@thompsonclan.org>
44
45 * ido-ubiquitous.el (ido-ubiquitous--maybe-update-overrides):
46 Allow ido-ubiquitous to automatically add new overrides.
47
48 2015-11-21 Ryan C. Thompson <rct@thompsonclan.org>
49
50 * ido-ubiquitous.el: Fix up dependency declarations and require
51 statements (including a pull request by Steve Purcell)
52
53 * ido-completing-read+.el (ido-select-text): Fix C-j behavior when
54 require-match is enabled
55
56 2015-10-04 Ryan C. Thompson <rct@thompsonclan.org>
57
58 * ido-ubiquitous.el: Add override for etags-select
59
60 2015-06-19 Ryan C. Thompson <rct@thompsonclan.org>
61
62 * ido-ubiquitous.el: Fix some byte-compile warnings in autoloads
63 by also autoloading the associated variable declarations
64
65 2015-06-18 Ryan C. Thompson <rct@thompsonclan.org>
66
67 * ido-ubiquitous.el: Ignore and warn about invalid overrides
68 instead of crashing
69
70 * ido-completing-read+.el: Fix some variable declaration warnings
71
72 * ido-ubiquitous.el (ido-ubiquitous-default-command-overrides):
73 Add override for "where-is" command
74
75 2015-05-28 Ryan C. Thompson <rct@thompsonclan.org>
76
77 * ido-ubiquitous.el (ido-ubiquitous-version): Fix a typo in the previous version
78
79 2015-04-23 Ryan C. Thompson <rct@thompsonclan.org>
80
81 * ido-completing-read+.el: Fix obsolete reference to "choices"
82 instead of "collection"
83
84 2015-04-08 Ryan C. Thompson <rct@thompsonclan.org>
85
86 * ido-ubiquitous.el: Major refactor. Split into two packages:
87 ido-completing-read+.el and ido-ubiquitous.el that depends on it.
88 Additionally, some of the customization variables for
89 ido-ubiquitous have been changed for increased flexibility in
90 configuration, and the internals have been rearchitected
91 significantly.
92
93 2015-01-25 Ryan C. Thompson <rct@thompsonclan.org>
94
95 * ido-ubiquitous: Fix indentation issues
96 (https://github.com/DarwinAwardWinner/ido-ubiquitous/pull/62)
97
98 2014-09-04 Ryan C. Thompson <rct@thompsonclan.org>
99
100 * ido-ubiquitous: Enable fallbacks to non-ido-completion using C-f
101 and C-b
102
103 2014-05-26 Ryan C. Thompson <rct@thompsonclan.org>
104
105 * ido-ubiquitous: Disable in tmm when called as a function as well
106 as a command
107
108 2014-03-27 Ryan C. Thompson <rct@thompsonclan.org>
109
110 * ido-ubiquitous: Add override for "*-theme" functions
111
112 2014-03-24 Ryan C. Thompson <rct@thompsonclan.org>
113
114 * ido-ubiquitous: Fix a bug related to
115 "ido-ubiquitous-allow-on-functional-collection"
116 (#46)
117
118 2014-02-25 Ryan C. Thompson <rct@thompsonclan.org>
119
120 * ido-ubiquitous: Disable in tmm-menubar
121
122 2013-11-19 Ryan C. Thompson <rct@thompsonclan.org>
123
124 * ido-ubiquitous: Add new custom variable
125 "ido-ubiquitous-allow-on-functional-collection"
126
127 2013-10-02 Ryan C. Thompson <rct@thompsonclan.org>
128
129 * ido-ubiquitous: Enable in "read-char-by-name"
130
131 2013-09-27 Ryan C. Thompson <rct@thompsonclan.org>
132
133 * ido-ubiquitous: Disable in org and magit since they already
134 support ido
135
136 2013-09-26 Ryan C. Thompson <rct@thompsonclan.org>
137
138 * ido-ubiquitous: Make ido-ubiquitous work with Emacs trunk
139 (pre-24.4)
140
141 * ido-ubiquitous: Fix a few minor and unlikely-to-ever-occur bugs
142
143 * ido-ubiquitous: Replace collection function whitelist with
144 overrides (overrides can now force ido completion when collection
145 is a function)
146
147 2013-09-23 Ryan C. Thompson <rct@thompsonclan.org>
148
149 * ido-ubiquitous: Implement collection function whitelist
150
151 * ido-ubiquitous: Implement collection size limit for ido
152 completion
153
154 2013-09-17 Ryan C. Thompson <rct@thompsonclan.org>
155
156 * ido-ubiquitous: Eliminate use of "macroexp--backtrace", which
157 doesn't exist in Emacs 24.2.
158
159 2013-09-11 Ryan C. Thompson <rct@thompsonclan.org>
160
161 * ido-ubiquitous: Fix handling of collection being a function
162 (issues #23 and #25).
163
164 2013-09-10 Ryan C. Thompson <rct@thompsonclan.org>
165
166 * ido-ubiquitous: Fix the issue where `called-interactively-p'
167 always returns false
168 https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/24
169
170 2013-09-05 Ryan C. Thompson <rct@thompsonclan.org>
171
172 * ido-ubiquitous: Ido-ubiquitous now works better with interactive
173 commands. Specifically, it now works when the completion happens
174 inside the "interactive" form of the command instead of the
175 function body.
176
177 * ido-ubiquitous: Functions and commands that need non-standard
178 behavior are now controlled through the variables
179 "ido-ubiquitous-command-overrides" and
180 "ido-ubiquitous-function-overrides".
181
182 * ido-ubiquitous: Major rewrite of a significant portions of
183 ido-ubiquitous.
184
185 2013-05-31 Ryan C. Thompson <rct@thompsonclan.org>
186
187 * ido-ubiquitous: Officially drop support for Emacs 23 and lower.
188 ido-ubiquitous now uses the `completing-read-function' variable
189 instead of advising `completing-read'.
190
191 * ido-ubiquitous: Make ido-ubiquitous work more reliably in
192 interactive commands.
193
194 * ido-ubiquitous: Avoid spurious warning when loaded before ido.
195
196 * ido-ubiquitous: Disable ido when completion-extra-properties is
197 non-nil
198
199 * ido-ubiquitous: The interface for setting old-style completion
200 compatibility has changed. If you have customized these settings,
201 you should review them after upgrading.
202
203 2012-09-07 Ryan C. Thompson <rct@thompsonclan.org>
204
205 * ido-ubiquitous: Restore compatibility with Emacs 23 and earlier
206
207 * ido-ubiquitous: Work around an ido bug where providing both an
208 initial input and a default would break things
209
210 * ido-ubiquitous: Most modifications to ido behavior are now
211 activated only when ido is acting as a completing-read
212 replacement, and not when it is used directly. This shoud prevent
213 ido-ubiquitous from interfering with normal usage of ido.
214
215 * ido-ubiquitous: Add Custom interface for compatibility
216 exceptions.
217
218 2012-09-03 Ryan C. Thompson <rct@thompsonclan.org>
219
220 * ido-ubiquitous: New implementation: Switch from defining advice
221 on "completing-read" to setting "completing-read-function"
0 # ido-ubiquitous #
1
2 [![MELPA Stable](https://stable.melpa.org/packages/ido-ubiquitous-badge.svg)](https://stable.melpa.org/#/ido-ubiquitous)
3 [![Join the chat at https://gitter.im/DarwinAwardWinner/ido-ubiquitous](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/DarwinAwardWinner/ido-ubiquitous?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4
5 Gimme some ido... everywhere! This package replaces stock emacs
6 completion with ido completion wherever it is possible to do so
7 without breaking things.
8
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.
20
21 # How to enable ido in as many places as possible #
22
23 If you are using this package, you probably want to enable ido
24 everywhere that it is possible to do so. Here are all the places to
25 enable ido that I'm aware of. (Note that most of these variables can
26 also be set via `M-x customize-variable` if you prefer that.)
27
28 ## Ido itself ##
29
30 First, enable `ido-mode` and `ido-everywhere`.
31
32 (ido-mode 1)
33 (ido-everywhere 1)
34
35 ## ido-ubiquitous (this package) ##
36
37 Install this package [from MELPA](http://melpa.org/#/ido-ubiquitous)
38 and then turn on `ido-ubiquitous-mode`:
39
40 (require 'ido-ubiquitous)
41 (ido-ubiquitous-mode 1)
42
43 ## Smex ##
44
45 Smex allows you to use ido for completion of commands in M-x, with
46 enhancements like putting your most-used commands at the front of the
47 list. First install the [smex](https://github.com/nonsequitur/smex)
48 package, then follow the directions to set up key-bindings for it.
49
50 ## ido-yes-or-no ##
51
52 If you want to use ido for yes-or-no questions, even though it's
53 massive overkill, install my [ido-yes-or-no package from MELPA](http://melpa.org/#/ido-yes-or-no), and then enable the mode:
54
55 (require 'ido-yes-or-no)
56 (ido-yes-or-no-mode 1)
57
58 ## ido for `describe-face` and certain other commands ##
59
60 Some commands, such as `describe-face`, use `completing-read-multiple`
61 instead of `completing-read`. You can get ido completion for these
62 commands with `crm-custom-mode`, which replaces
63 `completing-read-multiple` with repeated calls to `completing-read`,
64 which would then use ido thanks to ido-ubiquitous-mode. First, install
65 the [crm-custom](https://github.com/DarwinAwardWinner/crm-custom)
66 package [from MELPA](http://melpa.org/#/crm-custom), then enable the
67 mode:
68
69 (require 'crm-custom)
70 (crm-custom-mode 1)
71
72 Remember that when using this mode, completion for affected commands
73 will continue to read additional items until you use C-j to enter an
74 empty input, which terminates the completion. (Due to this quirk, I do
75 not find this mode to be very useful in conjunction with ido, but it
76 does work.)
77
78 ## Packages with built-in ido support ##
79
80 Lastly, some packages already provide their own interfaces to ido, so
81 ido-ubiquitous specifically avoids interfering with these. If you use
82 any of the following packages, you need to enable ido for each of them
83 separately.
84
85 * Magit: `(setq magit-completing-read-function 'magit-ido-completing-read)`
86 * Gnus: `(setq gnus-completing-read-function 'gnus-ido-completing-read)`
87
88 (You can also use `M-x customize-variable` to set all of these
89 options.)
90
91 # Frequently asked questions #
92
93 ## How does ido-ubiquitous decide when to replace `completing-read`? <br/> Why don't some commands use ido completion? ##
94
95 Emacs' `completing-read` is a complex function with many advanced
96 features and some quirks that are only maintained for backwards
97 compatibility. Not all of these features are supported by ido, so it
98 is impossible to always replace `completing-read` with ido completion.
99 Trying to use ido when these features are requested can completely
100 break the completion system. So, by default ido-ubiquitous tries to
101 get out of the way whenever it detects that these features might be
102 used by a given call to `completing-read`. Furthermore, it's not
103 always possible to detect based on the arguments to `completing-read`
104 whether such ido-incompatible features are being used or not.
105 ido-ubiquitous uses a series of heuristics to determine whether
106 unsupported features *might* be used, and also supports an override
107 feature to correct it when the heuristics get things wrong.
108
109 Each time a function invokes `completing-read`, ido-ubiquitous selects
110 one of 3 modes:
111
112 * `enable`: use ido completion;
113 * `enable-old`: use ido completion, but with a compatibility fix for
114 old-style default selection; and
115 * `disable`: no ido completion.
116
117 The following describes in detail how ido-ubiquitous selects the
118 appropriate mode, and what to do when you think it is making the wrong
119 choice.
120
121 ### Disabling ido completion when the collection is very large ###
122
123 Ido can get slow on very large collections, so by default
124 ido-ubiquitous disables itself for collections with more than 30,000
125 items in them. This rule takes precedence over anything else, even
126 overrides that explicitly enable ido completion for a command.
127
128 You can change the large collection threshold by customizing
129 `ido-cr+-max-items`.
130
131 ### Disabling ido completion when the collection is a function ###
132
133 One feature of `completing-read` is that the collection argument can
134 be a function. This function could simply return a list of all
135 possible completions, in which case it would be safe to use ido, or it
136 could implement a completely new completion system, in which case
137 using ido would interfere with this new completion system (for an
138 example of this, see the `tmm` command). But ido-ubiquitous cannot
139 tell by looking at the function which kind it is, so it errs on the
140 side of caution and disables itself whenever the collection is a
141 function, unless an override exists telling it that the command is
142 safe for ido completion. You can turn off this safeguard by
143 customizing `ido-ubiquitous-allow-on-functional-collection`. Be aware
144 that enabling this will likely break completion entirely in any
145 command that uses this feature to implement non-standard completion.
146
147 If you run across a command that unexpectedly uses normal Emacs
148 completion instead of ido completion, it's likely that either this or
149 the previous option is to blame.
150
151 ### Disabling or enabling ido completion by overrides ###
152
153 If ido-ubiquitous is not running for a command where is should be due
154 to the functional collection rule, you can add an override for that
155 command by using `M-x customize-variable
156 ido-ubiquitous-command-overrides`. Conversely, if ido completion
157 causes problems for a command, you can also use this to disable
158 ido-ubiquitous for that command.
159
160 ## What is old-style default selection? ##
161
162 The `enable-old` mode of operation is required because the old way for
163 `completing-read` to indicate that the user simply pressed RET and
164 selected the default option was to return an empty string. When this
165 old-style mode is used, `completing-read` doesn't even know what the
166 default is *supposed* to be -- the calling code handles all of that.
167 But in ido, simply pressing RET will return the first item of the
168 list, not an empty string. The way to enter an empty string in ido is
169 C-j. The `enable-old` mode enables ido completion, but swaps the
170 meaning of C-j and RET if you haven't entered any text or cycled the
171 options yet (once you do either of those, C-j and RET regain their
172 standard meanings). This allows you to select the default by pressing
173 RET as soon as the completion prompt appears, as intended (C-j would
174 select the first item).
175
176 Unfortunately, there is no way for ido-ubiquitous to detect when a
177 command is using this old-style default selection, so instead it uses
178 a built-in set of overrides telling it about commands that are known
179 to use old-style defaults. If you discover a command where pressing
180 RET or C-j at an empty prompt is not doing what you expect it to,
181 there's a good chance that you need to add an `enable-old` override
182 for that command to `ido-ubiquitous-command-overrides`. Luckily, since
183 this is an obsolete usage pattern, it is unlikely that any Elisp
184 functions written since 1990 or so will need to be added to this list.
185 Hopefully all uses of old-style completion will eventually be
186 eliminated, and with them, the need for this feature of
187 ido-ubiquitous.
188
189 ## How can I troubleshoot when ido-ubiquitous isn't doing what I want? ##
190
191 First, invoke the `ido-ubiquitous-debug-mode` and `ido-cr+-debug-mode`
192 commands. Then, with these two modes active, run the command(s) that
193 you are having trouble with, and when the completion prompt appears,
194 make a selection to complete the process. Then, examine the Messages
195 buffer, where ido-ubiquitous will explain which mode of operation it
196 selected and why. Based on this, you can add an override to
197 `ido-ubiquitous-command-overrides`. If you are not familiar with the
198 structure of this variable, I recommend using `M-x customize-variable`
199 to edit it, which will help you get it right. If ido completion was
200 skipped ido completion because the collection was too large, try
201 giving `ico-cr+-max-items` a larger value, or set it to nil if your
202 computer is fast enough to handle any size of collection.
203
204 Updates to ido-ubiquitous often include new overrides, but Emacs will
205 not edit your override variables if you have already customized them.
206 So, if you have recently upgraded ido-ubiquitous, remember to invoke
207 `ido-ubiquitous-restore-default-overrides` to add in any new
208 overrides. (In the future, this process may become automatic:
209 https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/90)
210
211 ## Where can I report bugs or suggest new overrides? ##
212
213 If you end up adding any overrides, please also report them at
214 https://github.com/DarwinAwardWinner/ido-ubiquitous/issues so I can
215 incorporate them into the defaults for future versions. You can also
216 report any bugs you find in ido-ubiquitous.
217
218 ## I'm getting some weird warnings from ido-ubiquitous when Emacs starts. ##
219
220 I've gotten numerous reports about nonsensical warnings produced by
221 ido-ubiquitous, such as "free variable" warnings about variables that
222 are most definitely properly declared, or warnings that only appear
223 when ido-ubiquitous is loaded after another unrelated package. For
224 many of these warnings, I've never been able to discover the cause or
225 reproduce the warnings myself, and I've given up trying to figure it
226 out. Please don't report any new bugs about variable warnings *unless*
227 you can tell me how to consistently reproduce them starting from
228 `emacs -Q`. If you are an Emacs expert who knows how to fix these
229 warnings, please let me know.
230
231 You can see the bug reports about weird warnings
232 [here](https://github.com/DarwinAwardWinner/ido-ubiquitous/issues?utf8=%E2%9C%93&q=label%3Abizarre-unexplainable-scoping-issues+).
233
234 ## What is the "bleeding-edge" branch? ##
235
236 All users should just use the master branch, or better yet, install
237 from MELPA. The bleeding-edge branch is where I test experimental and
238 unfinished features. Because ido-ubiquitous hooks deeply into the
239 bowels of Emacs, a bug in ido-ubiquitous could easily freeze or crash
240 Emacs entirely. Additionally, some bug only show up when
241 ido-ubiquitous is installed and compiled as a package. So I test every
242 new feature myself for some time on this branch before pushing to the
243 master branch. If you report a bug, I might develop a fix for it on
244 the bleeding edge branch and ask then you to try this branch.
245 Otherwise, normal users don't need to think about this branch.
246
247 # ido-completing-read+ #
248
249 As of version 3.0, most of the core functionality of ido-ubiquitous
250 has been spun off into a separate library called ido-completing-read+,
251 or "ido-cr+" for short. ido-cr+ incorporates all the features of
252 ido-ubiquitous that are actually just generic improvements to ido that
253 should probably always be enabled. It implements these fixes in a
254 single function `ido-completing-read+`, which should be suitable as a
255 drop-in replacement for either `ido-completing-read` or
256 `completing-read`. Notably, unlike the original `ido-completing-read`,
257 `ido-completing-read+` should always do something useful, by falling
258 back to normal completion when ido completion won't work.
259 Additionally, it allows you to manually fall back using C-f and C-b,
260 in the same way you can use those keys to switch between file and
261 buffer completion in ido. As a user, you don't really need to know
262 anything about ido-cr+. However, if you are writing an Emacs package
263 and would like to incorporate ido completion, you may wish to use
264 ido-cr+ to get more robust completion with fewer weird edge cases.
0 ;;; ido-completing-read+.el --- A completing-read-function using ido -*- lexical-binding: t -*-
1
2 ;; Copyright (C) 2015 Ryan C. Thompson
3
4 ;; Filename: ido-completing-read+.el
5 ;; Author: Ryan Thompson
6 ;; Created: Sat Apr 4 13:41:20 2015 (-0700)
7 ;; Version: 3.14
8 ;; Package-Requires: ((emacs "24.1") (cl-lib "0.5"))
9 ;; URL: https://github.com/DarwinAwardWinner/ido-ubiquitous
10 ;; Keywords: ido, completion, convenience
11
12 ;; This file is NOT part of GNU Emacs.
13
14 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15 ;;
16 ;;; Commentary:
17
18 ;; This package implements the `ido-completing-read+' function, which
19 ;; is a wrapper for `ido-completing-read'. Importantly, it detects
20 ;; edge cases that ordinary ido cannot handle and either adjusts them
21 ;; so ido *can* handle them, or else simply falls back to Emacs'
22 ;; standard completion instead.
23
24 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25 ;;
26 ;; This program is free software: you can redistribute it and/or modify
27 ;; it under the terms of the GNU General Public License as published by
28 ;; the Free Software Foundation, either version 3 of the License, or (at
29 ;; your option) any later version.
30 ;;
31 ;; This program is distributed in the hope that it will be useful, but
32 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
33 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
34 ;; General Public License for more details.
35 ;;
36 ;; You should have received a copy of the GNU General Public License
37 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
38 ;;
39 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
40 ;;
41 ;;; Code:
42
43 (defconst ido-completing-read+-version "3.14"
44 "Currently running version of ido-ubiquitous.
45
46 Note that when you update ido-completing-read+, this variable may
47 not be updated until you restart Emacs.")
48
49 (require 'ido)
50 (require 'cl-lib)
51
52 ;;; Debug messages
53
54 (define-minor-mode ido-cr+-debug-mode
55 "If non-nil, ido-cr+ will print debug info.
56
57 Debug info is printed to the *Messages* buffer."
58 nil
59 :global t
60 :group 'ido-completing-read-plus)
61
62 ;; Defined as a macro for efficiency (args are not evaluated unless
63 ;; debug mode is on)
64 (defmacro ido-cr+--debug-message (format-string &rest args)
65 `(when ido-cr+-debug-mode
66 (message (concat "ido-completing-read+: " ,format-string) ,@args)))
67
68 ;;; Core code
69
70 ;;;###autoload
71 (defvar ido-cr+-enable-next-call nil
72 "If non-nil, then the next call to `ido-completing-read' is by `ido-completing-read+'.")
73 ;;;###autoload
74 (defvar ido-cr+-enable-this-call nil
75 "If non-nil, then the current call to `ido-completing-read' is by `ido-completing-read+'")
76
77 (defgroup ido-completing-read-plus nil
78 "Extra features and compatibility for `ido-completing-read'."
79 :group 'ido)
80
81 (defcustom ido-cr+-fallback-function
82 ;; Initialize to the current value of `completing-read-function',
83 ;; unless that is already set to the ido completer, in which case
84 ;; use `completing-read-default'.
85 (if (memq completing-read-function
86 '(ido-completing-read+
87 ido-completing-read
88 ;; Current ido-ubiquitous function
89 completing-read-ido-ubiquitous
90 ;; Old ido-ubiquitous functions that shouldn't be used
91 completing-read-ido
92 ido-ubiquitous-completing-read))
93 'completing-read-default
94 completing-read-function)
95 "Alternate completing-read function to use when ido is not wanted.
96
97 This will be used for functions that are incompatible with ido
98 or if ido cannot handle the completion arguments. It will also be
99 used when the user requests non-ido completion manually via C-f
100 or C-b."
101 :type '(choice (const :tag "Standard emacs completion"
102 completing-read-default)
103 (function :tag "Other function"))
104 :group 'ido-completing-read-plus)
105
106 (defcustom ido-cr+-max-items 30000
107 "Max collection size to use ido-cr+ on.
108
109 If `ido-completing-read+' is called on a collection larger than
110 this, the fallback completion method will be used instead. To
111 disable fallback based on collection size, set this to nil."
112 :type '(choice (const :tag "No limit" nil)
113 (integer
114 :tag "Limit" :value 30000
115 :validate
116 (lambda (widget)
117 (let ((v (widget-value widget)))
118 (if (and (integerp v)
119 (> v 0))
120 nil
121 (widget-put widget :error "This field should contain a positive integer")
122 widget)))))
123 :group 'ido-completing-read-plus)
124
125 ;;;###autoload
126 (defcustom ido-cr+-replace-completely nil
127 "If non-nil, replace `ido-completeing-read' completely with ido-cr+.
128
129 Enabling this may interfere with or cause errors in other
130 packages that use `ido-completing-read'. If you discover any such
131 incompatibilities, please file a bug report at
132 https://github.com/DarwinAwardWinner/ido-ubiquitous/issues"
133 :type 'boolean)
134
135 ;; Signal used to trigger fallback
136 (put 'ido-cr+-fallback 'error-conditions '(ido-cr+-fallback error))
137 (put 'ido-cr+-fallback 'error-message "ido-cr+-fallback")
138
139 (defun ido-cr+--explain-fallback (arg)
140 ;; This function accepts a string, or an ido-cr+-fallback
141 ;; signal.
142 (when ido-cr+-debug-mode
143 (when (and (listp arg)
144 (eq (car arg) 'ido-cr+-fallback))
145 (setq arg (cdr arg)))
146 (ido-cr+--debug-message "Falling back to `%s' because %s."
147 ido-cr+-fallback-function arg)))
148
149 ;;;###autoload
150 (defun ido-completing-read+ (prompt collection &optional predicate
151 require-match initial-input
152 hist def inherit-input-method)
153 "ido-based method for reading from the minibuffer with completion.
154
155 See `completing-read' for the meaning of the arguments.
156
157 This function is a wrapper for `ido-completing-read' designed to
158 be used as the value of `completing-read-function'. Importantly,
159 it detects edge cases that ido cannot handle and uses normal
160 completion for them."
161 (let (;; Save the original arguments in case we need to do the
162 ;; fallback
163 (orig-args
164 (list prompt collection predicate require-match
165 initial-input hist def inherit-input-method)))
166 (condition-case sig
167 (progn
168 (cond
169 (inherit-input-method
170 (signal 'ido-cr+-fallback
171 "ido cannot handle non-nil INHERIT-INPUT-METHOD"))
172 ((bound-and-true-p completion-extra-properties)
173 (signal 'ido-cr+-fallback
174 "ido cannot handle non-nil `completion-extra-properties'"))
175 ((functionp collection)
176 (signal 'ido-cr+-fallback
177 "ido cannot handle COLLECTION being a function")))
178 ;; Expand all possible completions
179 (setq collection (all-completions "" collection predicate))
180 ;; Check for excessively large collection
181 (when (and ido-cr+-max-items
182 (> (length collection) ido-cr+-max-items))
183 (signal 'ido-cr+-fallback
184 (format
185 "there are more than %i items in COLLECTION (see `ido-cr+-max-items')"
186 ido-cr+-max-items)))
187 ;; ido doesn't natively handle DEF being a list. If DEF is a
188 ;; list, prepend it to COLLECTION and set DEF to just the
189 ;; car of the default list.
190 (when (and def (listp def))
191 (setq collection
192 (append def
193 (nreverse (cl-set-difference collection def)))
194 def (car def)))
195 ;; Work around a bug in ido when both INITIAL-INPUT and
196 ;; DEF are provided.
197 (let ((initial
198 (or (if (consp initial-input)
199 (car initial-input)
200 initial-input)
201 "")))
202 (when (and def initial
203 (stringp initial)
204 (not (string= initial "")))
205 ;; Both default and initial input were provided. So keep
206 ;; the initial input and preprocess the collection list
207 ;; to put the default at the head, then proceed with
208 ;; default = nil.
209 (setq collection (cons def (remove def collection))
210 def nil)))
211 ;; Ready to do actual ido completion
212 (prog1
213 (let ((ido-cr+-enable-next-call t))
214 (ido-completing-read
215 prompt collection
216 predicate require-match initial-input hist def
217 inherit-input-method))
218 ;; This detects when the user triggered fallback mode
219 ;; manually.
220 (when (eq ido-exit 'fallback)
221 (signal 'ido-cr+-fallback "user manually triggered fallback"))))
222 ;; Handler for ido-cr+-fallback signal
223 (ido-cr+-fallback
224 (ido-cr+--explain-fallback sig)
225 (apply ido-cr+-fallback-function orig-args)))))
226
227 ;;;###autoload
228 (defadvice ido-completing-read (around ido-cr+ activate)
229 "This advice handles application of ido-completing-read+ features.
230
231 First, it ensures that `ido-cr+-enable-this-call' is set
232 properly. This variable should be non-nil during execution of
233 `ido-completing-read' if it was called from
234 `ido-completing-read+'.
235
236 Second, if `ido-cr+-replace-completely' is non-nil, then this
237 advice completely replaces `ido-completing-read' with
238 `ido-completing-read+'."
239 ;; If this advice is autoloaded, then we need to force loading of
240 ;; the rest of the file so all the variables will be defined.
241 (when (not (featurep 'ido-completing-read+))
242 (require 'ido-completing-read+))
243 (let ((ido-cr+-enable-this-call ido-cr+-enable-next-call)
244 (ido-cr+-enable-next-call nil))
245 (if (or
246 ido-cr+-enable-this-call ; Avoid recursion
247 (not ido-cr+-replace-completely))
248 ad-do-it
249 (message "Replacing ido-completing-read")
250 (setq ad-return-value (apply #'ido-completing-read+ (ad-get-args 0))))))
251
252 ;; Fallback on magic C-f and C-b
253 ;;;###autoload
254 (defvar ido-context-switch-command nil
255 "Variable holding the command used for switching to another completion mode.
256
257 This variable is originally declared in `ido.el', but it is not
258 given a value (or a docstring). This documentation comes from a
259 re-declaration in `ido-completing-read+.el' that initializes it
260 to nil, which should suppress some byte-compilation warnings in
261 Emacs 25. Setting another package's variable is not safe in
262 general, but in this case it should be, because ido always
263 let-binds this variable before using it, so the initial value
264 shouldn't matter.")
265
266 (defadvice ido-magic-forward-char (before ido-cr+-fallback activate)
267 "Allow falling back in ido-completing-read+."
268 (when ido-cr+-enable-this-call
269 ;; `ido-context-switch-command' is already let-bound at this
270 ;; point.
271 (setq ido-context-switch-command #'ido-fallback-command)))
272
273 (defadvice ido-magic-backward-char (before ido-cr+-fallback activate)
274 "Allow falling back in ido-completing-read+."
275 (when ido-cr+-enable-this-call
276 ;; `ido-context-switch-command' is already let-bound at this
277 ;; point.
278 (setq ido-context-switch-command #'ido-fallback-command)))
279
280 ;;; Workaround for https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/93
281
282 (defadvice ido-select-text (around fix-require-match-behavior activate)
283 "Fix ido behavior when `require-match' is non-nil.
284
285 Standard ido will allow C-j to exit with an incomplete completion
286 even when `require-match' is non-nil. Ordinary completion does
287 not allow this. In ordinary completion, RET on an incomplete
288 match is equivalent to TAB, and C-j selects the first match.
289 Since RET in ido already selects the first match, this advice
290 sets up C-j to be equivalent to TAB in the same situation."
291 (if (and
292 ;; Only override C-j behavior if...
293 ;; We're using ico-cr+
294 ido-cr+-enable-this-call
295 ;; Require-match is non-nil
296 (with-no-warnings ido-require-match)
297 ;; A default was provided, or ido-text is non-empty
298 (or (with-no-warnings ido-default-item)
299 (not (string= ido-text "")))
300 ;; Only if current text is not a complete choice
301 (not (member ido-text (with-no-warnings ido-cur-list))))
302 (progn
303 (ido-cr+--debug-message
304 "Overriding C-j behavior for require-match: performing completion instead of exiting.")
305 (ido-complete))
306 ad-do-it))
307
308 (provide 'ido-completing-read+)
309
310 ;;; ido-completing-read+.el ends here
0 ;;; ido-ubiquitous.el --- Use ido (nearly) everywhere. -*- lexical-binding: t -*-
1
2 ;; Copyright (C) 2011-2015 Ryan C. Thompson
3
4 ;; Author: Ryan C. Thompson
5 ;; URL: https://github.com/DarwinAwardWinner/ido-ubiquitous
6 ;; Version: 3.14
7 ;; Created: 2011-09-01
8 ;; Keywords: convenience, completion, ido
9 ;; EmacsWiki: InteractivelyDoThings
10 ;; Package-Requires: ((emacs "24.1") (ido-completing-read+ "3.14") (cl-lib "0.5"))
11 ;; Filename: ido-ubiquitous.el
12
13 ;; This file is NOT part of GNU Emacs.
14
15 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16 ;;
17 ;;; Commentary:
18
19 ;; 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.
51
52 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
53 ;;
54 ;; This program is free software: you can redistribute it and/or modify
55 ;; it under the terms of the GNU General Public License as published by
56 ;; the Free Software Foundation, either version 3 of the License, or (at
57 ;; your option) any later version.
58 ;;
59 ;; This program is distributed in the hope that it will be useful, but
60 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
61 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
62 ;; General Public License for more details.
63 ;;
64 ;; You should have received a copy of the GNU General Public License
65 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
66 ;;
67 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
68 ;;
69 ;;; Code:
70
71 (defconst ido-ubiquitous-version "3.14"
72 "Currently running version of ido-ubiquitous.
73
74 Note that when you update ido-ubiquitous, this variable may not
75 be updated until you restart Emacs.")
76
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)
86 (require 'ido-completing-read+)
87
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)
92
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 ;; Defined as a macro for efficiency (args are not evaluated unless
105 ;; debug mode is on)
106 (defmacro ido-ubiquitous--debug-message (format-string &rest args)
107 `(when ido-ubiquitous-debug-mode
108 (message (concat "ido-ubiquitous: " ,format-string) ,@args)))
109
110 (defun ido-ubiquitous--explain-fallback (arg)
111 ;; This function accepts a string, or an ido-ubiquitous-fallback
112 ;; signal.
113 (when ido-ubiquitous-debug-mode
114 (when (and (listp arg)
115 (eq (car arg) 'ido-ubiquitous-fallback))
116 (setq arg (cdr arg)))
117 (ido-ubiquitous--debug-message "Falling back to `%s' because %s."
118 ido-cr+-fallback-function arg)))
119
120 ;;; Internal utility functions
121
122 (defun ido-ubiquitous--as-string (sym-or-str)
123 "Return name of symbol, return string as is."
124 (if (symbolp sym-or-str)
125 (symbol-name sym-or-str)
126 sym-or-str))
127
128 (defun ido-ubiquitous--as-symbol (sym-or-str)
129 "Return string as symbol, return symbol as is."
130 (if (symbolp sym-or-str)
131 sym-or-str
132 (intern sym-or-str)))
133
134 ;;; Custom widget definitions
135
136 ;; We need to define some custom widget types for use in the override
137 ;; variables.
138
139 (define-widget 'lazy-notag 'lazy
140 "Like lazy widget, but does not display its tag, only its value."
141 :format "%v")
142
143 ;; Define matcher functions and widgets for match specifications
144 (defvar ido-ubiquitous-match-spec-widget-types nil
145 "List of widget names for match specs.")
146 (defvar ido-ubiquitous-spec-matchers nil
147 "Alist of functions for matching function specs against function names.")
148 (cl-loop for (widget-name widget-tag key field-type matcher) in
149 '((exact-match "Exact match" exact string string=)
150 (prefix-match "Prefix match" prefix string string-prefix-p)
151 (regexp-match "Regexp match" regexp regexp string-match-p))
152 do (define-widget (ido-ubiquitous--as-symbol widget-name) 'lazy-notag widget-tag
153 :menu-tag widget-tag
154 :type `(list :tag ,widget-tag :format "%v"
155 (const :format ""
156 :tag ,widget-tag
157 ,key)
158 (,field-type :tag ,widget-tag)))
159 do (add-to-list 'ido-ubiquitous-match-spec-widget-types
160 widget-name 'append)
161 do (add-to-list 'ido-ubiquitous-spec-matchers
162 (cons key matcher) 'append))
163
164 (define-widget 'ido-ubiquitous-match-spec 'lazy-notag
165 "Choice of exact, prefix, or regexp match."
166 :type `(choice :tag "Match type"
167 ,@ido-ubiquitous-match-spec-widget-types))
168
169 (define-widget 'ido-ubiquitous-command-override-spec 'lazy-notag
170 "Choice of override action plus match specification."
171 :type '(cons :tag "Override rule"
172 (choice :tag "For matching commands"
173 (const :menu-tag "Disable"
174 :tag "Disable ido-ubiquitous"
175 disable)
176 (const :menu-tag "Enable"
177 :tag "Enable ido-ubiquitous in normal default mode"
178 enable)
179 (const :menu-tag "Enable old-style default"
180 :tag "Enable ido-ubiquitous in old-style default mode"
181 enable-old))
182 ido-ubiquitous-match-spec))
183
184 (define-widget 'ido-ubiquitous-function-override-spec 'lazy-notag
185 "Choice of override action and function name. (Exact match only.)"
186 :type '(list :tag "Override rule"
187 (choice :tag "Do the following"
188 (const :menu-tag "Disable"
189 :tag "Disable ido-ubiquitous"
190 disable)
191 (const :menu-tag "Enable"
192 :tag "Enable ido-ubiquitous in normal default mode"
193 enable)
194 (const :menu-tag "Enable old-style default"
195 :tag "Enable ido-ubiquitous in old-style default mode"
196 enable-old))
197 (const :format "" exact)
198 (string :tag "For function")))
199
200 ;;; Custom Declarations
201
202 (defgroup ido-ubiquitous nil
203 "Use ido for (almost) all completion."
204 :group 'ido
205 :group 'ido-completing-read-plus)
206
207 ;;;###autoload
208 (define-obsolete-variable-alias 'ido-ubiquitous
209 'ido-ubiquitous-mode "ido-ubiquitous 0.8")
210 ;;;###autoload
211 (define-obsolete-function-alias 'ido-ubiquitous
212 'ido-ubiquitous-mode "ido-ubiquitous 0.8")
213
214 ;;;###autoload
215 (define-minor-mode ido-ubiquitous-mode
216 "Use `ido-completing-read' instead of `completing-read' almost everywhere.
217
218 If this mode causes problems for a function, you can customize
219 when ido completion is or is not used by customizing
220 `ido-ubiquitous-command-overrides' or
221 `ido-ubiquitous-function-overrides'."
222 nil
223 :global t
224 :group 'ido-ubiquitous
225 ;; Actually enable/disable the mode by setting
226 ;; `completing-read-function'.
227 (setq completing-read-function
228 (if ido-ubiquitous-mode
229 #'completing-read-ido-ubiquitous
230 ido-cr+-fallback-function)))
231
232 ;; Variables for functionality that has moved to ido-completing-read+
233 (define-obsolete-variable-alias
234 'ido-ubiquitous-max-items
235 'ido-cr+-max-items
236 "ido-ubiquitous 3.0")
237 (define-obsolete-variable-alias
238 'ido-ubiquitous-fallback-completing-read-function
239 'ido-cr+-fallback-function
240 "ido-ubiquitous 3.0")
241
242 (define-obsolete-variable-alias
243 'ido-ubiquitous-enable-compatibility-globally
244 'ido-ubiquitous-enable-old-style-default
245 "ido-ubiquitous 2.0")
246
247 (defcustom ido-ubiquitous-default-state 'enable
248 "Default ido-ubiquitous mode of operation for commands with no override.
249
250 This can be set to one of three options:
251
252 * `enable': use normal ido completion;
253 * `enable-old': use ido completion, but with emulation of the
254 old-style default selection of `completing-read';
255 * `disable': use non-ido completion.
256
257 Command-specific and function-specific overrides are available to
258 override this default for specific commands/functions. See
259 `ido-ubiquitous-command-overrides' and
260 `ido-ubiquitous-function-overrides'.
261
262 The `enable-old' option swaps the behavior of RET and C-j but
263 only for the first keypress after beginning completion.
264 Specifically, on the first keypress, RET will return an empty
265 string and C-j will return the first item on the list. The
266 purpose of this is to emulate a legacy compatibility quirk of
267 `completing-read'. From the `completing-read' docstring:
268
269 > If the input is null, `completing-read' returns DEF, or the
270 > first element of the list of default values, or an empty string
271 > if DEF is nil, regardless of the value of REQUIRE-MATCH.
272
273 This odd behavior is required for compatibility with an old-style
274 usage pattern whereby the default was requested by returning an
275 empty string. In this mode, the caller receives the empty string
276 and handles the default case manually, while `completing-read'
277 never has any knowledge of the default. This is a problem for
278 ido, which normally returns the first element in the list, not an
279 empty string, when the input is empty and you press RET. Without
280 knowledge of the default, it cannot ensure that the default is
281 first on the list, so returning the first item is not the correct
282 behavior. Instead, it must return an empty string like
283 `completing-read'.
284
285 The `disable' mode is available as a default, which seems
286 counterintuitive. But this allows you, if you so desire, to
287 enable ido-ubiquitous selectively for only a few specific commands
288 using overrides and disable it for everything else."
289 :type '(choice :tag "Default mode"
290 (const :menu-tag "Disable"
291 :tag "Disable ido-ubiquitous"
292 disable)
293 (const :menu-tag "Enable"
294 :tag "Enable ido-ubiquitous in normal default mode"
295 enable)
296 (const :menu-tag "Enable old-style default"
297 :tag "Enable ido-ubiquitous in old-style default mode"
298 enable-old))
299 :group 'ido-ubiquitous)
300
301 (make-obsolete-variable
302 'ido-ubiquitous-enable-old-style-default
303 "This variable no longer has any effect. Set
304 `ido-ubiquitous-default-state' to `enable-old' instead."
305 "ido-ubiquitous 3.0")
306
307 (defconst ido-ubiquitous-default-command-overrides
308 '(;; If you want ido for M-x, install smex
309 (disable exact "execute-extended-command")
310 ;; Wanderlust uses new-style default
311 (enable prefix "wl-")
312 ;; Info functions use old-style default selection
313 (enable-old prefix "Info-")
314 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/4
315 (enable exact "webjump")
316 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/28
317 (enable regexp "\\`\\(find\\|load\\|locate\\)-library\\'")
318 ;; https://github.com/bbatsov/prelude/issues/488
319 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/44
320 ;; tmm implements its own non-standard completion mechanics
321 (disable prefix "tmm-")
322 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/47
323 ;; theme functions don't need old-style compatibility
324 (enable regexp "\\`\\(load\\|enable\\|disable\\|describe\\|custom-theme-visit\\)-theme\\'")
325 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/79
326 (enable-old prefix "bbdb-")
327 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/83
328 (enable-old exact "where-is")
329 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/60
330 (disable exact "todo-add-category")
331 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/51
332 (enable exact "find-tag")
333 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/89
334 (enable prefix "etags-select-")
335 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/110
336 (enable regexp "\\`describe-\\(function\\|variable\\)\\'")
337 ) ; Close paren on separate line for better VC diffs
338 "Default value of `ido-ubiquitous-command-overrides'.
339
340 You can restore these using the command `ido-ubiquitous-restore-default-overrides'.")
341
342 (defconst ido-ubiquitous-default-function-overrides
343 '((disable exact "read-file-name")
344 (disable exact "read-file-name-internal")
345 (disable exact "read-buffer")
346 (disable exact "gnus-emacs-completing-read")
347 (disable exact "gnus-iswitchb-completing-read")
348 (disable exact "grep-read-files")
349 (disable exact "magit-builtin-completing-read")
350 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/36
351 (enable exact "bookmark-completing-read")
352 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/4
353 (enable-old exact "webjump-read-choice")
354 (enable-old exact "webjump-read-url-choice")
355 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/9
356 (disable exact "isearchp-read-unicode-char")
357 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/38
358 (enable exact "read-char-by-name")
359 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/39
360 (disable exact "Info-read-node-name")
361 ;; https://github.com/purcell/emacs.d/issues/182#issuecomment-44212927
362 (disable exact "tmm-menubar")
363 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/58
364 ;; https://github.com/mooz/js2-mode/issues/181
365 (enable exact "imenu--completion-buffer")
366 ;; https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/74
367 (enable-old exact "auto-insert")
368 ) ; Close paren on separate line for better VC diffs
369 "Default value of `ido-ubiquitous-function-overrides'.
370
371 You can restore these using the command `ido-ubiquitous-restore-default-overrides'.")
372
373 (defcustom ido-ubiquitous-command-overrides ido-ubiquitous-default-command-overrides
374 "List of command override specifications for ido-ubiquitous
375
376 Each override specification describes how ido-ubiquitous should
377 behave one or many commands. A specification has the
378 form `(BEHAVIOR MATCH-TYPE MATCH-TEXT)'. BEHAVIOR is one of the
379 following:
380
381 * `disable': ido-ubiquitous should not be used at all for the
382 specified commands;
383 * `enable': ido-ubiquitous may be used with the specified
384 commands, without emulating the old-style default selection
385 of `completing-read';
386 * `enable-old': ido-ubiquitous may be used with the specified
387 commands, and should emulate the old-style default selection
388 of `completing-read'.
389
390 MATCH-TYPE affects how MATCH-TEXT is interpreted, as follows:
391
392 * `exact': the specification only affects the one command
393 whose name is MATCH-TEXT;
394 * `prefix': the specification affects any command whose name
395 starts with MATCH-TEXT (This is useful for specifying a
396 certain behavior for an entire package);
397 * `regexp': the specification affects any command whose name
398 matches MATCH-TEXT (with MATCH-TEXT being interpreted as a
399 regular expression)
400
401 MATCH-TEXT should be a string.
402
403 Since this variable's has a somewhat complex structure, it is
404 recommended that you set this variable through Customize.
405
406 Note that this variable only affects *commands*, which are
407 functions marked as interactive. See
408 `ido-ubiquitous-function-overrides' for how to modify the
409 behavior of ido-ubiquitous for arbitrary functions.
410
411 Note: If multiple overrides match the same commmand, the first
412 one in the list will take precedence.
413
414 If you need to add a new specification to this list, please also
415 file a bug report at https://github.com/DarwinAwardWinner/ido-ubiquitous/issues"
416 :type '(repeat ido-ubiquitous-command-override-spec)
417 :group 'ido-ubiquitous)
418
419 (defmacro ido-ubiquitous-with-override (override &rest body)
420 "Eval BODY with specified OVERRIDE in place.
421
422 The OVERRIDE argument is evaluated normally, so if it is a
423 literal symbol, it must be quoted.
424
425 See `ido-ubiquitous-command-overrides' for valid override types."
426 (declare (indent 1))
427 ;; Eval override
428 `(let ((ido-ubiquitous-next-override ,override))
429 ,@body))
430
431 (defun ido-ubiquitous-apply-function-override (func override)
432 "Set the override property on FUNC to OVERRIDE and set up advice to apply the override."
433 (setq func (ido-ubiquitous--as-symbol func)
434 override (ido-ubiquitous--as-symbol override))
435 (if (memq override '(disable enable enable-old nil))
436 (progn
437 (put func 'ido-ubiquitous-override override)
438 (when override
439 (let ((docstring
440 (format "Override ido-ubiquitous behavior in %s if its `ido-ubiquitous-override' property is non-nil." func)))
441 (eval
442 `(defadvice ,func (around ido-ubiquitous-override activate)
443 ,docstring
444 (let* ((func ',func)
445 (override (get func 'ido-ubiquitous-override)))
446 (when override
447 (ido-ubiquitous--debug-message
448 "Using override `%s' for function `%s'"
449 override func))
450 (ido-ubiquitous-with-override override
451 ad-do-it)))))))
452 (display-warning
453 'ido-ubiquitous
454 (format "Ignoring invalid override action `%s' for function `%s' found in `ido-ubiquitous-function-overrides'."
455 override func)
456 :warning)))
457
458 (defun ido-ubiquitous-set-function-overrides (sym newval)
459 "Custom setter function for `ido-ubiquitous-function-overrides'.
460
461 In addition to setting the variable, this also sets up advice on
462 each function to apply the appropriate override."
463 ;; Unset all previous overrides
464 (when (boundp sym)
465 (let ((oldval (eval sym)))
466 (cl-loop for (_action _match-type func) in oldval
467 do (ido-ubiquitous-apply-function-override func nil))))
468 ;; Ensure that function names are strings, not symbols
469 (setq newval
470 (cl-loop for (action match-type func) in newval
471 collect (list action match-type
472 (ido-ubiquitous--as-string func))))
473 ;; set new overrides
474 (cl-loop for override in newval
475 for (action match-type func) = override
476
477 ;; Remove duplicate overrides
478 if (member func overridden-functions)
479 do (display-warning
480 'ido-ubiquitous
481 (format
482 "Removing duplicate override for function `%s'" func))
483
484 ;; Apply valid overrides
485 else if (eq match-type 'exact)
486 do (ido-ubiquitous-apply-function-override func action)
487 and collect func into overridden-functions
488 and collect override into final-value
489
490 ;; Remove invalid overrides
491 else
492 do (display-warning
493 'ido-ubiquitous
494 (format
495 "Removing invalid function override match-type `%s' for function `%s'; only match-type `exact' is supported in `ido-ubiquitous-function-overrides'."
496 match-type func))
497
498 ;; Set the value to only the overrides that were actually
499 ;; applied.
500 finally return
501 (set-default sym final-value)))
502
503 (defcustom ido-ubiquitous-auto-update-overrides 'notify
504 "Whether to add new overrides when updating ido-ubiquitous.
505
506 Ido-ubiquitous comes with a default set of overrides for commands
507 that are known to require them. New versions of ido-ubiquitous
508 may come with updates to the default overrides as more commands
509 are discovered to require them. However, customizing your own
510 overrides would normally prevent you from receiving these
511 updates, since Emacs will not overwrite your customizations.
512
513 To resolve this problem, you can set this variable to `t', and
514 then ido-ubiquitous can automatically add any new built-in
515 overrides whenever it is updated. (Actually, the update will
516 happen the next time Emacs is restarted after the update.) This
517 allows you to add your own overrides but still receive updates to
518 the default set. The default overrides will always be added with
519 lower precedence than user-added ones.
520
521 If you want ido-ubiquitous to just notify you about new default
522 overrides instead of adding them itself, set this variable to
523 `notify'. If you don't want this auto-update behavior at all, set
524 it to `nil'.
525
526 (Note that having this option enabled effectively prevents you
527 from removing any of the built-in default overrides, since they
528 will simply be re-added the next time Emacs starts. However, your
529 custom overrides will still take precedence, so this shouldn't be
530 a problem.)"
531 :type '(choice :tag "When new overrides are available:"
532 (const :menu-tag "Auto-add"
533 :tag "Add them automatically"
534 t)
535 (const :menu-tag "Notify"
536 :tag "Notify the user about them"
537 notify)
538 (const :menu-tag "Ignore"
539 :tag "Ignore them"
540 nil))
541 :group 'ido-ubiquitous)
542
543 (defcustom ido-ubiquitous-function-overrides ido-ubiquitous-default-function-overrides
544 "List of function override specifications for ido-ubiquitous
545
546 Function override specifications have a similar structure to
547 command override specifications (see
548 `ido-ubiquitous-command-overrides'). A function override
549 specification has the form `(BEHAVIOR MATCH-TYPE MATCH-TEXT)'.
550 However, `MATCH-TYPE' may ONLY be `exact'; No other match type is
551 supported.
552
553 Note: If multiple overrides are set for the same function, the
554 first one in the list will take precedence, and the rest will be
555 ignored and deleted from the override list, with a warning.
556 Invalid override specifications will also be deleted with a
557 warning.
558
559 If you need to add a new specification to this list, please also file a
560 bug report at https://github.com/DarwinAwardWinner/ido-ubiquitous/issues
561
562 Setting this variable directly has no effect. You must set it
563 through Customize."
564 :type '(repeat ido-ubiquitous-function-override-spec)
565 :set 'ido-ubiquitous-set-function-overrides
566 :group 'ido-ubiquitous)
567
568 (defcustom ido-ubiquitous-allow-on-functional-collection nil
569 "Allow ido completion when COLLECTION is a function.
570
571 The `completing-read' function allows its COLLECTION argument to
572 be a function instead of a list of choices. Some such functions
573 simply return a list of completions and are suitable for use with
574 ido, but others implement more complex behavior and will result
575 in incorrect behavior if used with ido. Since there is no way to
576 tell the difference, this preference defaults to nil, which means
577 that ido-ubiquitous will not work when COLLECTION is a function
578 unless there is a specific override in effect. To disable this
579 safeguard and GUARANTEE ERRORS on some functions, you may set
580 this to non-nil, but this is not recommended."
581 :type 'boolean
582 :group 'ido-ubiquitous)
583
584 ;;; ido-ubiquitous core
585
586 ;; These variable are used to make ido-ubiquitous work properly in the
587 ;; case that `completing-read' is called recursively (which is
588 ;; possible when `enable-recursive-minibuffers' is non-nil.)
589 (defvar ido-ubiquitous-enable-next-call nil
590 "If non-nil, then the next call to `ido-completing-read' is by ido-ubiquitous.")
591 (defvar ido-ubiquitous-enable-this-call nil
592 "If non-nil, then the current call to `ido-completing-read' is by ido-ubiquitous.")
593 (defvar ido-ubiquitous-next-override nil
594 "This holds the override to be applied on the next call to `completing-read'.
595
596 It's value can be nil or one of the symbols `disable', `enable', or
597 `enable-old'.
598
599 You should not modify this variable directly. Instead use the
600 macro `ido-ubiquitous-with-override'.")
601 (defvar ido-ubiquitous-active-override nil
602 "This holds the override being applied to the current call to `completing-read'.
603
604 It's value can be nil or one of the symbols `disable', `enable', or
605 `enable-old'.
606
607 You should not modify this variable directly. Instead use the
608 macro `ido-ubiquitous-with-override'.")
609 (defvar ido-ubiquitous-active-state nil
610 "This holds the ido-ubiquitous mode of operation for the current call to `completing-read'.
611
612 It's value can be nil or one of the symbols `disable', `enable', or
613 `enable-old'.
614
615 You should not modify this variable directly.")
616
617 (defadvice ido-completing-read (around ido-ubiquitous activate)
618 "Enable ido-ubiquitous features if this call was done through ido-ubiquitous.
619
620 This advice ensures that `ido-ubiquitous-enable-this-call' is set
621 properly while `ido-completing-read' is executing. This variable
622 is used to determine whether to enable certain behaviors only for
623 ido-ubiquitous, not for ordinary ido completion."
624 ;; Set "this" and clear "next" so it doesn't apply to nested calls.
625 (let* ((ido-ubiquitous-enable-this-call ido-ubiquitous-enable-next-call)
626 (ido-ubiquitous-enable-next-call nil)
627 (ido-ubiquitous-initial-item nil))
628 ad-do-it))
629
630 ;; Signal used to trigger fallback (don't use `define-error' because
631 ;; it's only supported in 24.4 and up)
632 (put 'ido-ubiquitous-fallback 'error-conditions '(ido-ubiquitous-fallback error))
633 (put 'ido-ubiquitous-fallback 'error-message "ido-ubiquitous-fallback")
634
635 (defun completing-read-ido-ubiquitous
636 (prompt collection &optional predicate
637 require-match initial-input
638 hist def inherit-input-method)
639 "ido-based method for reading from the minibuffer with completion.
640
641 See `completing-read' for the meaning of the arguments.
642
643 This function is a wrapper for `ido-completing-read' designed to
644 be used as the value of `completing-read-function'. Importantly,
645 it detects edge cases that ido cannot handle and uses normal
646 completion for them."
647 (let (;; Save the original arguments in case we need to do the
648 ;; fallback
649 (orig-args
650 (list prompt collection predicate require-match
651 initial-input hist def inherit-input-method)))
652 ;; Outer `condition-case' is the fallback handler
653 (condition-case sig
654 ;; Inner `condition-case' converts any unexpected errors into
655 ;; fallback signals.
656 (condition-case err
657 (let* (;; Set the active override and clear the "next" one so it
658 ;; doesn't apply to nested calls.
659 (ido-ubiquitous-active-override ido-ubiquitous-next-override)
660 (ido-ubiquitous-next-override nil)
661 ;; Apply the active override, if any
662 (ido-ubiquitous-active-state
663 (or ido-ubiquitous-active-override
664 ido-ubiquitous-default-state
665 'enable)))
666 ;; If ido-ubiquitous is disabled this time, fall back
667 (when (eq ido-ubiquitous-active-state 'disable)
668 (signal 'ido-ubiquitous-fallback
669 "`ido-ubiquitous-active-state' is `disable'"))
670 ;; Handle a collection that is a function: either expand
671 ;; completion list now or fall back
672 (when (functionp collection)
673 (if (or ido-ubiquitous-allow-on-functional-collection
674 (memq ido-ubiquitous-active-override
675 '(enable enable-old)))
676 (setq collection (all-completions "" collection predicate)
677 ;; `all-completions' will apply the predicate,
678 ;; so it now becomes redundant.
679 predicate nil)
680 (signal 'ido-ubiquitous-fallback
681 "COLLECTION is a function and there is no override")))
682 (let ((ido-ubiquitous-enable-next-call t))
683 (ido-completing-read+
684 prompt collection predicate require-match
685 initial-input hist def inherit-input-method)))
686 (error
687 (signal 'ido-ubiquitous-fallback
688 (format "ido-ubiquitous encountered an unexpected error: %S"
689 err))))
690 ;; Handler for ido-ubiquitous-fallback signal
691 (ido-ubiquitous-fallback
692 (ido-ubiquitous--explain-fallback sig)
693 (apply ido-cr+-fallback-function orig-args)))))
694 (define-obsolete-function-alias 'completing-read-ido 'completing-read-ido-ubiquitous
695 "ido-ubiquitous 3.0")
696
697 ;;; Old-style default support
698
699 (defvar ido-ubiquitous-initial-item nil
700 "The first item selected when ido starts.
701
702 This is initialized to the first item in the list of completions
703 when ido starts, and is cleared when any character is entered
704 into the prompt or the list is cycled. If it is non-nil and still
705 equal to the first item in the completion list when ido exits,
706 then if `ido-ubiquitous-active-state' is `enable-old', ido
707 returns an empty string instead of the first item on the list.")
708
709 (defmacro ido-ubiquitous-set-initial-item (item)
710 "Wrapper for `(setq ido-ubiquitous-initial-item ITEM)'.
711
712 This wrapper differs from simply doing `(setq
713 ido-ubiquitous-initial-item ITEM)' in several ways. First, it has
714 no effect (and does not evaluate ITEM) unless
715 `ido-ubiquitous-active-state' is `enable-old'. Second, it emits
716 appropriate debug messages."
717 `(when (eq ido-ubiquitous-active-state 'enable-old)
718 (let ((item ,item))
719 (cond
720 (item
721 (ido-ubiquitous--debug-message
722 "Setting `ido-ubiquitous-initial-item' to `%S'."
723 item))
724 (ido-ubiquitous-initial-item
725 (ido-ubiquitous--debug-message "Clearing `ido-ubiquitous-initial-item'.")))
726 (setq ido-ubiquitous-initial-item item))))
727
728 (defadvice ido-read-internal (before ido-ubiquitous-clear-initial-item activate)
729 (ido-ubiquitous-set-initial-item nil))
730
731 (defadvice ido-make-choice-list (after ido-ubiquitous-set-initial-item activate)
732 (ido-ubiquitous-set-initial-item
733 (when (and ad-return-value (listp ad-return-value))
734 (car ad-return-value))))
735
736 (defadvice ido-next-match (after ido-ubiquitous-clear-initial-item activate)
737 (ido-ubiquitous-set-initial-item nil))
738
739 (defadvice ido-prev-match (after ido-ubiquitous-clear-initial-item activate)
740 (ido-ubiquitous-set-initial-item nil))
741
742 ;; Clear initial item after `self-insert-command'
743 (defun ido-ubiquitous-post-insert-hook ()
744 (eval '(ido-ubiquitous-set-initial-item nil)))
745
746 (defun ido-ubiquitous-ido-minibuffer-setup-hook ()
747 (add-hook
748 'post-self-insert-hook
749 #'ido-ubiquitous-post-insert-hook
750 nil
751 'local))
752
753 (add-hook 'ido-minibuffer-setup-hook
754 #'ido-ubiquitous-ido-minibuffer-setup-hook)
755
756 (defun ido-ubiquitous-should-use-old-style-default ()
757 "Returns non nil if ido-ubiquitous should emulate old-style default.
758
759 This function simply encapsulates all the checks that need to be
760 done in order to decide whether to swap RET and C-j. See
761 `ido-ubiquitous-default-state' for more information."
762 ;; These checks outside the loop don't produce debug messages
763 (and
764 ;; Only if old-style default enabled
765 (eq ido-ubiquitous-active-state 'enable-old)
766 ;; This loop is just an implementation of `and' that reports which
767 ;; arg was nil for debugging purposes.
768 (cl-loop
769 for test in
770 '((bound-and-true-p ido-cur-item)
771 ;; Only if completing a list, not a buffer or file
772 (eq ido-cur-item 'list)
773 ;; Only if this call was done through ido-ubiquitous
774 ido-ubiquitous-enable-this-call
775 ;; Only if default is nil
776 (null ido-default-item)
777 ;; Only if input is empty
778 (string= ido-text "")
779 ;; Only if `ido-ubiquitous-initial-item' hasn't been cleared
780 ido-ubiquitous-initial-item
781 ;; Only if initial item hasn't changed
782 (string= (car ido-cur-list)
783 ido-ubiquitous-initial-item))
784 for test-result = (eval test)
785 if (not test-result)
786 do (ido-ubiquitous--debug-message
787 "Not enabling old-style default selection because `%S' is nil"
788 test)
789 and return nil
790 finally do (ido-ubiquitous--debug-message
791 "Enabling old-style default selection")
792 finally return t)))
793
794 (defadvice ido-exit-minibuffer (around ido-ubiquitous-old-style-default-compat activate)
795 "Emulate a quirk of `completing-read'.
796
797 > If the input is null, `completing-read' returns DEF, or the
798 > first element of the list of default values, or an empty string
799 > if DEF is nil, regardless of the value of REQUIRE-MATCH.
800
801 See `ido-ubiquitous-default-state', which controls whether this
802 advice has any effect."
803 (condition-case nil
804 (if (ido-ubiquitous-should-use-old-style-default)
805 (let ((ido-ubiquitous-active-state 'enable))
806 (ido-select-text))
807 ad-do-it)
808 (error
809 (display-warning 'ido-ubiquitous "Advice on `ido-exit-minibuffer' failed." :warning)
810 ad-do-it))
811 (ido-ubiquitous-set-initial-item nil))
812
813 (defadvice ido-select-text (around ido-ubiquitous-old-style-default-compat activate)
814 "Emulate a quirk of `completing-read'.
815
816 > If the input is null, `completing-read' returns DEF, or the
817 > first element of the list of default values, or an empty string
818 > if DEF is nil, regardless of the value of REQUIRE-MATCH.
819
820 See `ido-ubiquitous-default-state', which controls whether this
821 advice has any effect."
822 (condition-case nil
823 (if (ido-ubiquitous-should-use-old-style-default)
824 (let ((ido-ubiquitous-active-state 'enable))
825 (ido-exit-minibuffer))
826 ad-do-it)
827 (error
828 (display-warning 'ido-ubiquitous "Advice on `ido-select-text' failed." :warning)
829 ad-do-it))
830 (ido-ubiquitous-set-initial-item nil))
831
832 ;;; Overrides
833
834 (defun ido-ubiquitous--overrides-have-same-target-p (o1 o2)
835 (cl-destructuring-bind (oride1 type1 text1) o1
836 (cl-destructuring-bind(oride2 type2 text2) o2
837 ;; Avoid warnings about unused vars
838 oride1 oride2
839 (and (string= text1 text2)
840 (eq type1 type2)))))
841
842 (defun ido-ubiquitous--combine-override-lists (olist1 olist2)
843 "Append OLIST2 to OLIST1, but remove redundant elements.
844
845 Redundancy is determined using
846 `ido-ubiquitous--overrides-have-same-target-p'."
847 (let ((olist2
848 (cl-remove-if
849 (lambda (o2) (cl-member
850 o2 olist1
851 :test #'ido-ubiquitous--overrides-have-same-target-p))
852 olist2)))
853 (append olist1 olist2)))
854
855 (defun ido-ubiquitous-update-overrides (&optional save quiet)
856 "Re-add the default overrides without erasing custom overrides.
857
858 This is useful after an update of ido-ubiquitous that adds new
859 default overrides. See `ido-ubiquitous-auto-update-overrides' for
860 more information.
861
862 If SAVE is non-nil, also save the overrides to the user's custom
863 file (but only if they were already customized). When called
864 interactively, a prefix argument triggers a save.
865
866 When called from Lisp code, this function returns the list of
867 variables whose values were modified. In particular, it returns
868 non-nil if any variables were modified, and nil if no modifications
869 were made."
870 (interactive "P")
871 (let ((unmodified-vars nil)
872 (updated-vars nil)
873 (final-message-lines nil)
874 (final-message-is-warning nil))
875 (cl-loop
876 for (var def) in
877 '((ido-ubiquitous-command-overrides
878 ido-ubiquitous-default-command-overrides)
879 (ido-ubiquitous-function-overrides
880 ido-ubiquitous-default-function-overrides))
881 do (let* ((var-state (custom-variable-state var (eval var)))
882 (curval (eval var))
883 (defval (eval def))
884 (newval (ido-ubiquitous--combine-override-lists
885 curval defval)))
886 (cond
887 ;; Nothing to add to var, do nothing
888 ((and (equal curval newval)
889 (eq var-state 'saved))
890 (ido-ubiquitous--debug-message
891 "No need to modify value of option `%s'"
892 var)
893 (push var unmodified-vars))
894 ;; Var is not customized, just set the new default
895 ((eq var-state 'standard)
896 (ido-ubiquitous--debug-message
897 "Setting uncustomized option `%s' to its default value"
898 var)
899 (push var unmodified-vars)
900 (set var defval))
901 ;; Var is saved to custom.el, set and save new value (if
902 ;; SAVE is t)
903 ((and save
904 (eq var-state 'saved))
905 (ido-ubiquitous--debug-message
906 "Updating option `%s' with new overrides and saving it."
907 var)
908 (push var updated-vars)
909 (customize-save-variable var newval))
910 ;; Var is modified but not saved (or SAVE is nil), update it
911 ;; but don't save it
912 (t
913 (ido-ubiquitous--debug-message
914 "Updating option `%s' with new overrides but not saving it for future sessions."
915 var)
916 (push var updated-vars)
917 (customize-set-variable var newval)))))
918 (unless quiet
919 ;; Now compose a single message that summarizes what was done
920 (if (null updated-vars)
921 (push "No updates to ido-ubiquitous override variables were needed."
922 final-message-lines)
923 (push
924 (format "Updated the following ido-ubiquitous override variables: %S"
925 (sort updated-vars #'string<))
926 final-message-lines)
927 (if save
928 (push
929 "All updated variables were successfully saved."
930 final-message-lines)
931 (push
932 "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'."
933 final-message-lines)
934 (setq final-message-is-warning t)))
935 (if final-message-is-warning
936 (display-warning 'ido-ubiquitous
937 (mapconcat 'identity (nreverse final-message-lines) "\n"))
938 (message (mapconcat 'identity (nreverse final-message-lines) "\n"))))
939 updated-vars))
940
941 (defun ido-ubiquitous--find-override-updates (current-value available-updates)
942 (cl-set-difference (ido-ubiquitous--combine-override-lists
943 current-value available-updates)
944 current-value))
945
946 (defun ido-ubiquitous--maybe-update-overrides ()
947 "Maybe call `ido-ubiquitous-update-overrides.
948
949 See `ido-ubiquitous-auto-update-overrides."
950 (if ido-ubiquitous-auto-update-overrides
951 (let* ((command-override-updates
952 (ido-ubiquitous--find-override-updates
953 ido-ubiquitous-command-overrides
954 ido-ubiquitous-default-command-overrides))
955 (function-override-updates
956 (ido-ubiquitous--find-override-updates
957 ido-ubiquitous-function-overrides
958 ido-ubiquitous-default-function-overrides))
959 (update-count
960 (+ (length command-override-updates)
961 (length function-override-updates))))
962 (if (> update-count 0)
963 (if (eq ido-ubiquitous-auto-update-overrides 'notify)
964 (display-warning
965 'ido-ubiquitous
966 (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.)"
967 update-count))
968 (ido-ubiquitous--debug-message "Applying override updates.")
969 (ido-ubiquitous-update-overrides t))
970 (ido-ubiquitous--debug-message "No override updates availble.")))
971 (ido-ubiquitous--debug-message "Skipping override updates by user preference.")))
972
973 (define-obsolete-function-alias
974 'ido-ubiquitous-restore-default-overrides
975 'ido-ubiquitous-update-overrides
976 "ido-ubiquitous 3.9")
977
978 (defun ido-ubiquitous-spec-match (spec symbol)
979 "Returns t if SPEC matches SYMBOL (which should be a function name).
980
981 See `ido-ubiquitous-command-overrides'. If the match spec is
982 invalid or any other error occurs, the error is demoted to a
983 warning and the function returns nil."
984 (condition-case err
985 (when (and symbol (symbolp symbol))
986 (cl-destructuring-bind (type text) spec
987 (let ((matcher (cdr (assoc type ido-ubiquitous-spec-matchers)))
988 (text (ido-ubiquitous--as-string text))
989 (symname (ido-ubiquitous--as-string symbol)))
990 (if matcher
991 (funcall matcher text symname)
992 ;; If the matcher is invalid, issue a warning and return
993 ;; nil.
994 (error "Unknown match spec type \"%s\". See `ido-ubiquitous-spec-matchers' for valid types." type)
995 nil))))
996 (error
997 (display-warning 'ido-ubiquitous "Error during ido-ubiquitous spec matching: %S" err)
998 nil)))
999
1000 (defun ido-ubiquitous-get-command-override (cmd)
1001 "Return the override associated with the command CMD.
1002
1003 If there is no override set for CMD in
1004 `ido-ubiquitous-command-overrides', return nil."
1005 (when (and cmd (symbolp cmd))
1006 (cl-loop for override in ido-ubiquitous-command-overrides
1007 for (action . spec) = override
1008 for valid-action = (and (memq action '(disable enable enable-old nil))
1009 (assoc (car spec) ido-ubiquitous-spec-matchers))
1010 unless valid-action
1011 do (progn
1012 (display-warning
1013 'ido-ubiquitous
1014 (format "Removing invalid override `%S' from `ido-ubiquitous-command-overrides'"
1015 (cons action spec))
1016 :warning)
1017 (setq ido-ubiquitous-command-overrides
1018 (remove override ido-ubiquitous-command-overrides)))
1019 when (and valid-action (ido-ubiquitous-spec-match spec cmd))
1020 return action
1021
1022 finally return nil)))
1023
1024 ;;; Workaround for https://github.com/DarwinAwardWinner/ido-ubiquitous/issues/24
1025
1026 ;; When `call-interactively' is advised, `called-interactively-p'
1027 ;; always returns nil. So we redefine it (and `interactive-p') to test
1028 ;; the correct condition.
1029
1030 (defsubst ido-ubiquitous--looks-like-advised-orig (func)
1031 "Returns t if FUNC is a symbol starting with \"ad-Orig-\".
1032
1033 Such symbols are used to store the original definitions of
1034 functions that have been advised by `defadvice' or similar."
1035 (and (symbolp func)
1036 (string-prefix-p "ad-Orig-" (symbol-name func))))
1037
1038 (defsubst ido-ubiquitous--looks-like-call-interactively (func)
1039 "Returns t if FUNC looks like the function `call-interactively'.
1040
1041 FUNC \"looks like\" `call-interactively' if it is the literal
1042 symbol `call-interactively', or the value of `(symbol-function
1043 'call-interactively)', or a symbol whose `symbol-function' is the
1044 same as that of `call-interactively'.
1045
1046 This function is used to determine whether a given function was
1047 \"called by\" `call-interactively' and therefore was called
1048 interactively."
1049 (when func
1050 (eq (symbol-function 'call-interactively)
1051 (if (symbolp func)
1052 (symbol-function func)
1053 func))))
1054
1055 (defun ido-ubiquitous--backtrace-from (fun)
1056 "Return all backtrace frames, starting with the one for FUN.
1057
1058 FUN may be a list of functions, in which case the first one found
1059 on the stack will be used."
1060 (let ((stack
1061 (cl-loop for i upfrom 0
1062 for frame = (backtrace-frame i)
1063 while frame
1064 collect frame))
1065 (funcs (if (functionp fun)
1066 (list fun)
1067 fun)))
1068 (while (and stack
1069 (not (memq (cl-cadar stack) funcs)))
1070 (setq stack (cdr stack)))
1071 stack))
1072
1073 (defun ido-ubiquitous--clean-advice-from-backtrace (stack)
1074 "Takes a stack trace and cleans all evidence of advice.
1075
1076 Specifically, for each call to a function starting with
1077 \"ad-Orig-\", that call and all prior calls up to but not
1078 including the advised function's original name are deleted from
1079 the stack."
1080 (let ((skipping-until nil))
1081 (cl-loop for frame in stack
1082 for func = (cadr frame)
1083 ;; Check if we found the frame we we're skipping to
1084 if (and skipping-until
1085 (eq func skipping-until))
1086 do (setq skipping-until nil)
1087 ;; If we're looking at an the original form of an advised
1088 ;; function, skip until the real name of that function.
1089 if (and (not skipping-until)
1090 (ido-ubiquitous--looks-like-advised-orig func))
1091 do (setq skipping-until
1092 (intern
1093 (substring (symbol-name func)
1094 (eval-when-compile (length "ad-Orig-")))))
1095 unless skipping-until collect frame)))
1096
1097 (defsubst ido-ubiquitous--interactive-internal ()
1098 "Equivalent of the INTERACTIVE macro in the Emacs C source.
1099
1100 This is an internal function that should never be called
1101 directly.
1102
1103 See the C source for the logic behind this function."
1104 (and (not executing-kbd-macro)
1105 (not noninteractive)))
1106
1107 (defun ido-ubiquitous--interactive-p-internal ()
1108 "Equivalent of C function \"interactive_p\".
1109
1110 This is an internal function that should never be called
1111 directly.
1112
1113 See the C source for the logic behind this function."
1114 (let ((stack
1115 ;; We clean advice from the backtrace. This ensures that we
1116 ;; get the right answer even if `call-interactively' has been
1117 ;; advised.
1118 (ido-ubiquitous--clean-advice-from-backtrace
1119 (cdr
1120 (ido-ubiquitous--backtrace-from
1121 '(called-interactively-p interactive-p))))))
1122 ;; See comments in the C function for the logic here.
1123 (while (and stack
1124 (or (eq (cl-cadar stack) 'bytecode)
1125 (null (caar stack))))
1126 (setq stack (cdr stack)))
1127 ;; Top of stack is now the function that we want to know
1128 ;; about. Pop it, then check if the next function is
1129 ;; `call-interactively', using a more permissive test than the default.
1130 (ido-ubiquitous--looks-like-call-interactively (cl-cadadr stack))))
1131
1132 (defadvice call-interactively (around ido-ubiquitous activate)
1133 "Implements the behavior specified in `ido-ubiquitous-command-overrides'."
1134 (let* ((cmd (ad-get-arg 0))
1135 (override (ido-ubiquitous-get-command-override cmd)))
1136 (when override
1137 (ido-ubiquitous--debug-message "Using override `%s' for command `%s'"
1138 override cmd))
1139 (ido-ubiquitous-with-override override
1140 ad-do-it)))
1141
1142 ;; Work around `called-interactively-p' in Emacs 24.3 and earlier,
1143 ;; which always returns nil when `call-interactively' is advised.
1144 (when (not (and (featurep 'nadvice)
1145 (boundp 'called-interactively-p-functions)))
1146
1147 (defadvice interactive-p (around ido-ubiquitous activate)
1148 "Return the correct result when `call-interactively' is advised.
1149
1150 This advice completely overrides the original definition."
1151 (condition-case nil
1152 (setq ad-return-value
1153 (and (ido-ubiquitous--interactive-internal)
1154 (ido-ubiquitous--interactive-p-internal)))
1155 ;; In case of error in the advice, fall back to the default
1156 ;; implementation
1157 (error ad-do-it)))
1158
1159 (defadvice called-interactively-p (around ido-ubiquitous activate)
1160 "Return the correct result when `call-interactively' is advised.
1161
1162 This advice completely overrides the original definition."
1163 (condition-case nil
1164 (setq ad-return-value
1165 (and (or (ido-ubiquitous--interactive-internal)
1166 (not (eq kind 'interactive)))
1167 (ido-ubiquitous--interactive-p-internal)))
1168 ;; In case of error in the advice, fall back to the default
1169 ;; implementation
1170 (error ad-do-it))))
1171
1172 ;;; Other
1173
1174 (defsubst ido-ubiquitous--fixup-old-advice ()
1175 ;; Clean up old versions of ido-ubiquitous advice if they exist
1176 (ignore-errors (ad-remove-advice 'completing-read 'around 'ido-ubiquitous))
1177 (ignore-errors (ad-remove-advice 'ido-completing-read 'around 'detect-replacing-cr))
1178 (ignore-errors (ad-remove-advice 'ido-magic-forward-char 'before 'ido-ubiquitous-fallback))
1179 (ignore-errors (ad-remove-advice 'ido-magic-backward-char 'before 'ido-ubiquitous-fallback))
1180 (ignore-errors (ad-remove-advice 'ido-exit-minibuffer 'around 'compatibility))
1181 (ad-activate-all))
1182
1183 (defsubst ido-ubiquitous--fixup-old-magit-overrides ()
1184 (let ((old-override '(disable prefix "magit-"))
1185 (new-override '(disable exact "magit-builtin-completing-read")))
1186 (when (member old-override
1187 ido-ubiquitous-command-overrides)
1188 (customize-set-variable
1189 'ido-ubiquitous-command-overrides
1190 (remove old-override ido-ubiquitous-command-overrides))
1191 (unless (member new-override ido-ubiquitous-function-overrides)
1192 (customize-set-variable 'ido-ubiquitous-function-overrides
1193 (append ido-ubiquitous-function-overrides
1194 (list new-override))))
1195 (display-warning
1196 'ido-ubiquitous
1197 "Fixing obsolete magit overrides.
1198
1199 Magit has changed recently such that the old override that
1200 ido-ubiquitous defined for it now causes problems. This old
1201 override has been automatically removed and the new one added.
1202 Please use `M-x customize-group ido-ubiquitous' and review the
1203 override variables and save them to your customization file."
1204 :warning))))
1205
1206 (defun ido-ubiquitous-initialize ()
1207 "Do initial setup for ido-ubiquitous.
1208
1209 This only needs to be called once when the file is first loaded.
1210 It cleans up any traces of old versions of ido-ubiquitous and
1211 then sets up the mode."
1212 (ido-ubiquitous--fixup-old-advice)
1213 (ido-ubiquitous--fixup-old-magit-overrides)
1214 (ido-ubiquitous--maybe-update-overrides)
1215 ;; Make sure the mode is turned on/off as specified by the value of
1216 ;; the mode variable
1217 (ido-ubiquitous-mode (if ido-ubiquitous-mode 1 0)))
1218 (ido-ubiquitous-initialize)
1219
1220 (provide 'ido-ubiquitous)
1221 ;; Local Variables:
1222 ;; indent-tabs-mode: nil
1223 ;; End:
1224 ;;; ido-ubiquitous.el ends here
0 #!/bin/bash
1
2 TARGET_VERSION="$1"
3 if [ -n "$TARGET_VERSION" ]; then
4 echo "Updating version to $TARGET_VERSION";
5 perl -i'orig_*' -lape "s/Version: [0-9.]+/Version: $TARGET_VERSION/g;" \
6 -e "s/((?:defconst|defvar|setq).*-version\s+)\"[0-9.]+\"/\${1}\"$TARGET_VERSION\"/g;" \
7 -e "s/(Package-Requires.*\(ido-completing-read\+\s+)\"[0-9.]+\"\)/\${1}\"${TARGET_VERSION}\")/g;" \
8 *.el
9 else
10 echo "Usage: $0 VERSION_NUMBER"
11 fi
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 (idu-bindings
107 (cl-loop for var in ido-ubiquitous-options collect
108 (list var
109 (list 'quote
110 (eval (car (get var 'standard-value))))))))
111 `(with-mode ido-ubiquitous-mode 1
112 (let ,idu-bindings ,@body))))
113
114 (defmacro collection-as-function (collection)
115 "Return a function equivalent to COLLECTION.
116
117 The returned function will work equivalently to COLLECTION when
118 passed to `all-completions' and `try-completion'."
119 `(completion-table-dynamic (lambda (string) (all-completions string ,collection))))
120
121 (cl-defmacro should-with-tag (form &key tag)
122 "Equivalent to `(should FORM)' but with a TAG on the output.
123
124 This is useful if the same `should' form will be called multiple
125 times in different contexts. Each test can pass a different tag
126 so it's clear in the ERT output which context is causing the
127 failure.
128
129 Note that although this is a macro, the TAG argument is evaluated normally."
130 `(let ((tagvalue ,tag))
131 (condition-case err
132 (should ,form)
133 (ert-test-failed
134 (message "Error symbol: %S" (car err))
135 (message "Error data: %S" (cdr err))
136 (when tagvalue
137 (setf (cadr err) (append (cadr err) (list :tag tagvalue))))
138 (message "New error data: %S" (cdr err))
139 (signal (car err) (cdr err))))))
140
141 (defun plist-delete (plist property)
142 "Delete PROPERTY from PLIST.
143 This is in contrast to merely setting it to 0."
144 (let (p)
145 (while plist
146 (if (not (eq property (car plist)))
147 (setq p (plist-put p (car plist) (nth 1 plist))))
148 (setq plist (cddr plist)))
149 p))
150
151 (cl-defmacro should-error-with-tag (form &rest other-keys &key tag &allow-other-keys)
152 "Equivalent to `(should FORM)' but with a TAG on the output.
153 See `should-with-tag'.
154
155 Note that although this is a macro, the TAG argument is evaluated normally."
156 (setq other-keys (plist-delete other-keys :tag))
157 `(let ((tagvalue ,tag))
158 (condition-case err
159 (should-error ,form ,@other-keys)
160 (ert-test-failed
161 (message "Error symbol: %S" (car err))
162 (message "Error data: %S" (cdr err))
163 (when tagvalue
164 (setf (cadr err) (append (cadr err) (list :tag tagvalue))))
165 (message "New error data: %S" (cdr err))
166 (signal (car err) (cdr err))))))
167
168 (defun test-ido-ubiquitous-expected-mode (override &optional tag)
169 "Test whether observed ido-ubiquitous behavior matches OVERRIDE."
170 (declare (indent 1))
171 (if (eq override 'disable)
172 (progn
173 (should-with-tag
174 ;; Verify that we get standard completion
175 (string=
176 "g"
177 (with-simulated-input "g RET"
178 (completing-read "Prompt: " '("blue" "yellow" "green"))))
179 :tag tag)
180 (should-with-tag
181 (string=
182 "green"
183 (with-simulated-input "g RET"
184 (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
185 :tag tag)
186 ;; Standard completion should refuse to finish with incomplete
187 ;; input if match is required
188 (should-error-with-tag
189 (with-simulated-input "b RET"
190 (completing-read "Prompt: " '("brown" "blue" "yellow" "green") nil t))
191 :type 'error
192 :tag tag))
193 ;; Common tests whenever ido-ubiquitous is enabled in any way
194 (should-with-tag
195 ;; Verify that ido completion is active
196 (string=
197 "green"
198 (with-simulated-input "g RET"
199 (completing-read "Prompt: " '("blue" "yellow" "green"))))
200 :tag tag)
201 ;; Verify that C-j is working correctly
202 (should-with-tag
203 (string=
204 "g"
205 (with-simulated-input "g C-j"
206 (completing-read "Prompt: " '("blue" "yellow" "green"))))
207 :tag tag)
208 (let ((collection '("brown" "blue" "yellow" "green")))
209 (should-with-tag
210 (member
211 (with-simulated-input "b RET"
212 (completing-read "Prompt: " collection))
213 (all-completions "b" collection))
214 :tag tag))
215 (case override
216 (enable
217 ;; Test for new style
218 (should-with-tag
219 (string=
220 "blue"
221 (with-simulated-input "RET"
222 (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
223 :tag tag)
224 (should-with-tag
225 (string=
226 ""
227 (with-simulated-input "C-j"
228 (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
229 :tag tag))
230 (enable-old
231 (should-with-tag
232 (string=
233 ""
234 (with-simulated-input "RET"
235 (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
236 :tag tag)
237 (should-with-tag
238 (string=
239 "blue"
240 (with-simulated-input "C-j"
241 (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
242 :tag tag)
243 ;; Verify that doing other stuff reverts RET and C-j to standard
244 ;; meanings
245 (should-with-tag
246 (string=
247 "blue"
248 (with-simulated-input "g DEL RET"
249 (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
250 :tag tag)
251 (should-with-tag
252 (string=
253 "blue"
254 (with-simulated-input "<right> <left> RET"
255 (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
256 :tag tag)
257 (should-with-tag
258 (string=
259 ""
260 (with-simulated-input "g DEL C-j"
261 (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
262 :tag tag)
263 (should-with-tag
264 (string=
265 ""
266 (with-simulated-input "<right> <left> C-j"
267 (completing-read "Prompt: " '("blue" "yellow" "green") nil t)))
268 :tag tag))
269 (otherwise (error "Unknown override %S" override)))))
270
271 (defvar original-completing-read (symbol-function #'completing-read))
272
273 (defun test-ido-ubiquitous-expected-mode-on-functional-collection (override &optional tag)
274 "Test whether observed ido-ubiquitous behavior on functional collection matches OVERRIDE."
275 (declare (indent 1))
276 ;; This just temporarily replaces `completing-read' with a wrapper
277 ;; that always converts the collection argument to an equivalent
278 ;; function. That way, any use of `completing-read' will always see
279 ;; a functional collection.
280 (cl-letf (((symbol-function 'completing-read)
281 (lambda (prompt collection &rest args)
282 (apply original-completing-read prompt
283 (collection-as-function collection)
284 args))))
285 (test-ido-ubiquitous-expected-mode override tag)))
286
287 (ert-deftest ido-ubiquitous-test-simple ()
288 :tags '(ido ido-ubiquitous)
289 "Test that basic ido-ubiquitous functionality is working."
290 (with-ido-ubiquitous-standard-env
291 (ido-ubiquitous-mode 1)
292 (test-ido-ubiquitous-expected-mode 'enable
293 :simple-enable)
294 (ido-ubiquitous-mode 0)
295 (test-ido-ubiquitous-expected-mode 'disable
296 :simple-disable)))
297
298 (ert-deftest ido-ubiquitous-test-oldstyle ()
299 :tags '(ido ido-ubiquitous)
300 "Test whether old-style completion works as expected."
301 (with-ido-ubiquitous-standard-env
302 (let ((ido-ubiquitous-default-state 'enable-old))
303 (test-ido-ubiquitous-expected-mode 'enable-old
304 :simple-oldstyle))))
305
306 (ert-deftest ido-ubiquitous-test-maxitems ()
307 :tags '(ido ido-ubiquitous)
308 "Test whether the large-collection fallback works."
309 (with-ido-ubiquitous-standard-env
310 (let ((ido-cr+-max-items -1))
311 (test-ido-ubiquitous-expected-mode 'disable
312 :maxitems))))
313
314 (ert-deftest ido-ubiquitous-test-override ()
315 :tags '(ido ido-ubiquitous)
316 "Test whether ido-ubiquitous overrides work."
317 (with-ido-ubiquitous-standard-env
318 (ido-ubiquitous-with-override 'enable
319 (test-ido-ubiquitous-expected-mode 'enable
320 :override-enable))
321 (ido-ubiquitous-with-override 'enable-old
322 (test-ido-ubiquitous-expected-mode 'enable-old
323 :override-enable-old))
324 (ido-ubiquitous-with-override 'disable
325 (test-ido-ubiquitous-expected-mode 'disable
326 :override-disable))))
327
328 (ert-deftest ido-ubiquitous-test-functional-collection ()
329 :tags '(ido ido-ubiquitous)
330 "Test whether ido-ubiquitous overrides work when collection is a function."
331 (with-ido-ubiquitous-standard-env
332 (test-ido-ubiquitous-expected-mode-on-functional-collection 'disable
333 :collfunc)
334 (ido-ubiquitous-with-override 'enable
335 (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable
336 :override-enable-collfunc))
337 (ido-ubiquitous-with-override 'enable-old
338 (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable-old
339 :override-enable-old-collfunc))))
340
341 (ert-deftest ido-cr+-require-match ()
342 :tags '(ido ido-cr+)
343 "Test whether require-match works."
344 ;; "C-j" should be allowed to return an empty string even if
345 ;; require-match is non-nil, as long as default is nil
346 (should
347 (string=
348 ""
349 (with-simulated-input "C-j"
350 (ido-completing-read+
351 "Prompt: "
352 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t))))
353 ;; "C-j" should NOT be allowed to return an empty string if
354 ;; require-match and default are both non-nil.
355 (should-error
356 (with-simulated-input "C-j"
357 (ido-completing-read+
358 "Prompt: "
359 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t nil nil "yellow")))
360 ;; Multiple presses of C-j won't just select the first match
361 (should-error
362 (with-simulated-input "b C-j C-j C-j"
363 (ido-completing-read+
364 "Prompt: "
365 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t)))
366 ;; First press of C-j should complete unique common prefix after the
367 ;; first b, but then get stuck on the choice for the second b.
368 (should-error
369 (with-simulated-input "b C-j b C-j C-j"
370 (ido-completing-read+
371 "Prompt: "
372 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t)))
373 ;; This should complete to "blueberry" via 2 rounds of unique common
374 ;; prefix completion, and then return on the 3rd "C-j"
375 (should
376 (string=
377 "blueberry"
378 (with-simulated-input "b C-j b C-j e C-j C-j"
379 (ido-completing-read+
380 "Prompt: "
381 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t))))
382 ;; The "C-j" should complete to "bluegrass" but should
383 ;; not return.
384 (should-error
385 (with-simulated-input "b l u e g C-j"
386 (ido-completing-read+
387 "Prompt: "
388 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t)))
389 ;; The first "C-j" should complete to "bluegrass", and the second
390 ;; should return.
391 (should
392 (string=
393 "bluegrass"
394 (with-simulated-input "b l u e g C-j C-j"
395 (ido-completing-read+
396 "Prompt: "
397 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t))))
398 ;; Finally, a few tests for the expected wrong behavior without
399 ;; ido-cr+. If ido.el ever fixes this bug, it will cause this test
400 ;; to fail as a signal that the workaround can be phased out.
401 (should
402 (string=
403 ""
404 (with-simulated-input "C-j"
405 (ido-completing-read
406 "Prompt: "
407 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t))))
408 (should
409 (string=
410 "b"
411 (with-simulated-input "b C-j"
412 (ido-completing-read
413 "Prompt: "
414 '("bluebird" "blues" "bluegrass" "blueberry" "yellow ""green") nil t)))))
415
416 ;; Functions to define overrides on for testing
417 (defun idu-no-override-testfunc ()
418 (test-ido-ubiquitous-expected-mode 'enable
419 :func-override-none)
420 (test-ido-ubiquitous-expected-mode-on-functional-collection 'disable
421 :func-override-none-collfunc))
422 (defun idu-enabled-testfunc (&rest args)
423 (test-ido-ubiquitous-expected-mode 'enable
424 :func-override-enable)
425 (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable
426 :func-override-enable-collfunc))
427 (defun idu-disabled-testfunc (&rest args)
428 (test-ido-ubiquitous-expected-mode 'disable
429 :func-override-disable)
430 (test-ido-ubiquitous-expected-mode-on-functional-collection 'disable
431 :func-override-disable-collfunc))
432 (defun idu-enabled-oldstyle-testfunc (&rest args)
433 (test-ido-ubiquitous-expected-mode 'enable-old
434 :func-override-enable-old)
435 (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable-old
436 :func-override-enable-old-collfunc))
437
438 ;; commands to define overrides on for testing
439 (defun idu-no-override-testcmd (&rest args)
440 (interactive
441 (list
442 (test-ido-ubiquitous-expected-mode 'enable
443 :cmd-override-none)
444 (test-ido-ubiquitous-expected-mode-on-functional-collection 'disable
445 :cmd-override-none-collfunc)))
446 (test-ido-ubiquitous-expected-mode 'enable
447 :cmd-override-none)
448 (test-ido-ubiquitous-expected-mode-on-functional-collection 'disable
449 :cmd-override-non-collfunc))
450 (defun idu-enabled-testcmd (&rest args)
451 (interactive
452 (list
453 (test-ido-ubiquitous-expected-mode 'enable
454 :cmd-override-enable)
455 (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable
456 :cmd-override-enable-collfunc)))
457 (test-ido-ubiquitous-expected-mode 'enable
458 :cmd-override-enable)
459 (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable
460 :cmd-override-enable-collfunc))
461 (defun idu-disabled-testcmd (&rest args)
462 (interactive
463 (list
464 (test-ido-ubiquitous-expected-mode 'disable
465 :cmd-override-disable)
466 (test-ido-ubiquitous-expected-mode-on-functional-collection 'disable
467 :cmd-override-disable-collfunc)))
468 (test-ido-ubiquitous-expected-mode 'disable
469 :cmd-override-disable)
470 (test-ido-ubiquitous-expected-mode-on-functional-collection 'disable
471 :cmd-override-disable-collfunc))
472 (defun idu-enabled-oldstyle-testcmd (&rest args)
473 (interactive
474 (list
475 (test-ido-ubiquitous-expected-mode 'enable-old
476 :cmd-override-enable-old)
477 (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable-old
478 :cmd-override-enable-old-collfunc)))
479 (test-ido-ubiquitous-expected-mode 'enable-old
480 :cmd-override-enable-old)
481 (test-ido-ubiquitous-expected-mode-on-functional-collection 'enable-old
482 :cmd-override-enable-old-collfunc))
483
484 (ert-deftest ido-ubiquitous-test-command-and-function-overrides ()
485 :tags '(ido ido-ubiquitous)
486 "Test whether command- and function-specific overrides work."
487 (let ((orig-func-overrides ido-ubiquitous-function-overrides)
488 (orig-cmd-overrides ido-ubiquitous-command-overrides))
489 (unwind-protect
490 (with-ido-ubiquitous-standard-env
491 (customize-set-variable
492 'ido-ubiquitous-function-overrides
493 (append ido-ubiquitous-function-overrides
494 '((enable exact "idu-enabled-testfunc")
495 (disable exact "idu-disabled-testfunc")
496 (enable-old exact "idu-enabled-oldstyle-testfunc"))))
497 (cl-loop for func in
498 '(idu-no-override-testfunc
499 idu-enabled-testfunc
500 idu-disabled-testfunc
501 idu-enabled-oldstyle-testfunc)
502 do (funcall func))
503 (customize-set-variable
504 'ido-ubiquitous-command-overrides
505 (append ido-ubiquitous-command-overrides
506 '((enable exact "idu-enabled-testcmd")
507 (disable exact "idu-disabled-testcmd")
508 (enable-old exact "idu-enabled-oldstyle-testcmd"))))
509 (cl-loop for cmd in
510 '(idu-no-override-testcmd
511 idu-enabled-testcmd
512 idu-disabled-testcmd
513 idu-enabled-oldstyle-testcmd)
514 do (call-interactively cmd)))
515 (customize-set-variable 'ido-ubiquitous-function-overrides orig-func-overrides)
516 (customize-set-variable 'ido-ubiquitous-command-overrides orig-cmd-overrides))))
517
518 (ert-deftest ido-ubiquitous-test-fallback ()
519 :tags '(ido ido-ubiquitous)
520 "Test whether manually invoking fallback works."
521 (with-ido-ubiquitous-standard-env
522 (should
523 ;; C-b/f not at beginning/end of input should not fall back
524 (string=
525 "green"
526 (with-simulated-input "g C-b C-f RET"
527 (completing-read "Prompt: " '("blue" "yellow" "green")))))
528 (should
529 ;; C-f at end of input should fall back
530 (string=
531 "g"
532 (with-simulated-input "g C-f RET"
533 (completing-read "Prompt: " '("blue" "yellow" "green")))))
534 (should
535 ;; Repeated C-b should not fall back
536 (string=
537 "green"
538 (with-simulated-input "g C-b C-b C-b C-b RET"
539 (completing-read "Prompt: " '("blue" "yellow" "green")))))
540 (should
541 ;; C-b at beginning of line should fall back (if previous action
542 ;; was not also C-b)
543 (string=
544 "g"
545 (with-simulated-input "g C-b x DEL C-b RET"
546 (completing-read "Prompt: " '("blue" "yellow" "green")))))))
547
548 (defun ido-ubiquitous-run-all-tests ()
549 (interactive)
550 (ert "^ido-\\(ubiquitous\\|cr\\+\\)-"))
551
552 (provide 'ido-ubiquitous-test)
553
554 ;;; ido-ubiquitous-test.el ends here
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 ;; Version:
8 ;; Package-Requires: ()
9 ;; URL:
10 ;; Keywords:
11
12 ;; This file is NOT part of GNU Emacs.
13
14 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15 ;;
16 ;;; Commentary:
17
18 ;;
19
20 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21 ;;
22 ;; This program is free software: you can redistribute it and/or modify
23 ;; it under the terms of the GNU General Public License as published by
24 ;; the Free Software Foundation, either version 3 of the License, or (at
25 ;; your option) any later version.
26 ;;
27 ;; This program is distributed in the hope that it will be useful, but
28 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
29 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30 ;; General Public License for more details.
31 ;;
32 ;; You should have received a copy of the GNU General Public License
33 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
34 ;;
35 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
36 ;;
37 ;;; Code:
38
39 (require 'f)
40
41 (defvar test-path
42 (f-dirname (f-this-file)))
43
44 (defvar code-path
45 (f-parent test-path))
46
47 (add-to-list 'load-path code-path)
48
49 (require 'ido-completing-read+)
50 (require 'ido-ubiquitous)
51
52 (provide 'test-helper)
53
54 ;;; test-helper.el ends here