New upstream version 3.14
Lev Lamberov
7 years ago
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 |