ido-ubiquitous.el 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. ;;; ido-ubiquitous.el --- Use ido (nearly) everywhere.
  2. ;; Author: Ryan C. Thompson
  3. ;; URL: https://github.com/DarwinAwardWinner/ido-ubiquitous
  4. ;; Version: 1.7
  5. ;; Created: 2011-09-01
  6. ;; Keywords: convenience
  7. ;; EmacsWiki: InteractivelyDoThings
  8. ;; This file is NOT part of GNU Emacs.
  9. ;;; Commentary:
  10. ;; You may have seen the `ido-everywhere' variable in ido.el and got
  11. ;; excited that you could use ido completion for everything. Then you
  12. ;; were probably disappointed when you realized that it only applied
  13. ;; to *file names* and nothing else. Well, ido-ubiquitous is here to
  14. ;; fulfill the original promise and let you use ido completion for
  15. ;; (almost) any command that uses `completing-read' to offer you a
  16. ;; choice of several alternatives.
  17. ;; This even works in M-x, but for that, you might prefer the "smex"
  18. ;; package instead.
  19. ;; As of version 0.7, this package also makes a small modification to
  20. ;; ido's behavior so as to support a strange corner case of
  21. ;; `completing-read' that some functions rely on. Since the goal of
  22. ;; this package is to replace `completing-read' everywhere instead of
  23. ;; just selectively (as ido itself does), compatibility with all the
  24. ;; quriks of `completing-read' is important here.
  25. ;; If you find a case where enabling ido-ubiquitous causes a command
  26. ;; not to work correctly, please report it by creating an issue on
  27. ;; GitHub: https://github.com/DarwinAwardWinner/ido-ubiquitous/issues
  28. ;;; License:
  29. ;; This program is free software; you can redistribute it and/or modify
  30. ;; it under the terms of the GNU General Public License as published by
  31. ;; the Free Software Foundation; either version 3, or (at your option)
  32. ;; any later version.
  33. ;;
  34. ;; This program is distributed in the hope that it will be useful,
  35. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  36. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  37. ;; GNU General Public License for more details.
  38. ;;
  39. ;; You should have received a copy of the GNU General Public License
  40. ;; along with GNU Emacs; see the file COPYING. If not, write to the
  41. ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  42. ;; Boston, MA 02110-1301, USA.
  43. ;;; Code:
  44. (require 'ido)
  45. (require 'advice)
  46. (defvar ido-ubiquitous-orig-completing-read-function
  47. (bound-and-true-p completing-read-function)
  48. "The value of `completing-read-function' before ido-ubiquitous-mode was enabled.
  49. This value will be restored when `ido-ubiquitous-mode' is
  50. deactivated. It will also be used as a fallback if ido-ubiquitous
  51. detects something that ido cannot handle.")
  52. ;;;###autoload
  53. (defgroup ido-ubiquitous nil
  54. "Use ido for (almost) all completion."
  55. :group 'ido)
  56. (defun ido-ubiquitous-warn-about-ido-disabled ()
  57. "Warn if ido-ubiquitous is enabled without ido."
  58. (if (and after-init-time
  59. (not (bound-and-true-p ido-mode)))
  60. (warn "Ido-ubiquitous-mode enabled without ido mode.")))
  61. ;;;###autoload
  62. (define-minor-mode ido-ubiquitous-mode
  63. "Use `ido-completing-read' instead of `completing-read' almost everywhere.
  64. This mode has no effect unles `ido-mode' is also enabled.
  65. If this mode causes problems for a function, you can force the
  66. function to use the original completing read by using the macro
  67. `ido-ubiquitous-disable-in'. For example, if a
  68. function `foo' cannot work with ido-style completion, evaluate
  69. the following (for example by putting it in your .emacs file):
  70. (ido-ubiquitous-disable-in foo)"
  71. nil
  72. :global t
  73. :group 'ido-ubiquitous
  74. (when ido-ubiquitous-mode
  75. (unless (bound-and-true-p ido-mode)
  76. (if after-init-time
  77. (ido-ubiquitous-warn-about-ido-disabled)
  78. (add-hook 'after-init-hook 'ido-ubiquitous-warn-about-ido-disabled))))
  79. (if (and (boundp 'completing-read-function)
  80. ido-ubiquitous-orig-completing-read-function)
  81. ;; Emacs 24 and later
  82. (progn
  83. ;; Ensure emacs 23 code disabled
  84. (ad-disable-advice 'completing-read 'around 'ido-ubiquitous-legacy)
  85. (ad-activate 'completing-read)
  86. (setq completing-read-function
  87. (if ido-ubiquitous-mode
  88. 'completing-read-ido
  89. ido-ubiquitous-orig-completing-read-function)))
  90. ;; Emacs 23 and earlier
  91. (funcall (if ido-ubiquitous-mode 'ad-enable-advice 'ad-disable-advice)
  92. 'completing-read 'around 'ido-ubiquitous-legacy)
  93. (ad-activate 'completing-read)))
  94. ;;;###autoload
  95. (define-obsolete-variable-alias 'ido-ubiquitous
  96. 'ido-ubiquitous-mode "0.8")
  97. ;;;###autoload
  98. (define-obsolete-function-alias 'ido-ubiquitous
  99. 'ido-ubiquitous-mode "0.8")
  100. ;;;###autoload
  101. (defcustom ido-ubiquitous-command-exceptions '()
  102. "List of commands that should not be affected by `ido-ubiquitous'.
  103. Even when `ido-ubiquitous' mode is enabled, these commands will
  104. continue to use `completing-read' instead of
  105. `ido-completing-read'.
  106. Only *interactive* commands should go here. To disable
  107. ido-ubiquitous in non-interactive functions, customize
  108. `ido-ubiquitous-function-exceptions'.
  109. Note: this feature depends on the variable `this-command' being
  110. properly set to the name of the currently executing command.
  111. Depending on how the command is onvoked, this may or may not
  112. happen, so this feature may simply not work in some cases."
  113. :type '(repeat (symbol :tag "Command"))
  114. :group 'ido-ubiquitous)
  115. ;;;###autoload
  116. (define-obsolete-variable-alias 'ido-ubiquitous-exceptions
  117. 'ido-ubiquitous-command-exceptions "0.4")
  118. (defvar ido-next-call-replaces-completing-read nil)
  119. (defvar ido-this-call-replaces-completing-read nil)
  120. ;; Emacs 23 and below
  121. (defadvice completing-read (around ido-ubiquitous-legacy activate)
  122. "Ido-based method for reading from the minibuffer with completion.
  123. See `completing-read' for the meaning of the arguments."
  124. (if (or inherit-input-method ; Can't handle this arg
  125. (not ido-mode)
  126. (not ido-ubiquitous-mode)
  127. ;; Avoid infinite recursion from ido calling completing-read
  128. (boundp 'ido-cur-item)
  129. (memq this-command ido-ubiquitous-command-exceptions))
  130. ad-do-it
  131. (let ((allcomp (all-completions "" collection predicate)))
  132. ;; Only use ido completion if there are actually any completions
  133. ;; to offer.
  134. (if allcomp
  135. (let ((ido-next-call-replaces-completing-read t))
  136. (setq ad-return-value
  137. (ido-completing-read prompt allcomp
  138. nil require-match initial-input hist def)))
  139. ad-do-it))))
  140. (ad-disable-advice 'completing-read 'around 'ido-ubiquitous-legacy)
  141. (ad-activate 'completing-read)
  142. ;; Emacs 24+
  143. (defun completing-read-ido (prompt collection &optional predicate
  144. require-match initial-input
  145. hist def inherit-input-method)
  146. "Ido-based method for reading from the minibuffer with completion.
  147. See `completing-read' for the meaning of the arguments.
  148. This function is a wrapper for `ido-completing-read' designed to
  149. be used as the value of `completing-read-function'."
  150. (if (or inherit-input-method ; Can't handle this arg
  151. (bound-and-true-p completion-extra-properties) ; Can't handle this
  152. (not ido-mode)
  153. (not ido-ubiquitous-mode)
  154. (memq this-command ido-ubiquitous-command-exceptions))
  155. (funcall ido-ubiquitous-orig-completing-read-function
  156. prompt collection predicate
  157. require-match initial-input
  158. hist def inherit-input-method)
  159. (let ((allcomp (all-completions "" collection predicate)))
  160. ;; Only use ido completion if there are actually any completions
  161. ;; to offer.
  162. (if allcomp
  163. (let ((ido-next-call-replaces-completing-read t))
  164. (ido-completing-read prompt allcomp
  165. nil require-match initial-input hist def))
  166. (funcall ido-ubiquitous-orig-completing-read-function
  167. prompt collection predicate
  168. require-match initial-input
  169. hist def inherit-input-method)))))
  170. (defadvice ido-completing-read (around detect-replacing-cr activate)
  171. "Detect whether this call was done through `completing-read-ido'."
  172. (let* ((ido-this-call-replaces-completing-read ido-next-call-replaces-completing-read)
  173. (ido-next-call-replaces-completing-read nil))
  174. (when ido-this-call-replaces-completing-read
  175. ;; If DEF is a list, prepend it to CHOICES and set DEF to just the
  176. ;; car of the default list.
  177. (when (and def (listp def))
  178. (setq choices (delete-dups (append def choices))
  179. def (car def))) ;; Work around a bug in ido when both INITIAL-INPUT and DEF are provided
  180. ;; More info: https://github.com/technomancy/ido-ubiquitous/issues/18
  181. (let ((initial (cond ((null initial-input) "")
  182. ((stringp initial-input) initial-input)
  183. ((consp initial-input) (car initial-input))
  184. (t initial-input)))
  185. (deflist (if (listp def)
  186. def
  187. (list def))))
  188. (when (and deflist initial
  189. (stringp initial)
  190. (not (string= initial "")))
  191. ;; Both default and initial input were provided. So keep the
  192. ;; initial input and preprocess the choices list to put the
  193. ;; default at the head, then proceed with default = nil.
  194. (setq choices (delete-dups (append deflist (remove def choices)))
  195. def nil))))
  196. ad-do-it))
  197. (defmacro ido-ubiquitous-disable-in (func)
  198. "Disable ido-ubiquitous in FUNC."
  199. (let ((docstring
  200. (format "Disable ido-ubiquitous in %s" func)))
  201. `(defadvice ,func (around disable-ido-ubiquitous activate)
  202. ,docstring
  203. (let (ido-ubiquitous-mode) ad-do-it))))
  204. (define-obsolete-function-alias
  205. 'disable-ido-ubiquitous-in
  206. 'ido-ubiquitous-disable-in
  207. "0.4")
  208. (defmacro ido-ubiquitous-enable-in (func)
  209. "Re-enable ido-ubiquitous in FUNC.
  210. This reverses the effect of a previous call to
  211. `ido-ubiquitous-disable-in'."
  212. `(when (ad-find-advice ',func 'around 'disable-ido-ubiquitous)
  213. (ad-disable-advice ',func 'around 'disable-ido-ubiquitous)
  214. (ad-activate ',func)))
  215. (define-obsolete-function-alias
  216. 'enable-ido-ubiquitous-in
  217. 'ido-ubiquitous-enable-in
  218. "0.4")
  219. ;; Always disable ido-ubiquitous in `find-file' and similar functions,
  220. ;; because they are not supposed to use ido.
  221. (defvar ido-ubiquitous-permanent-function-exceptions
  222. '(read-file-name
  223. read-file-name-internal
  224. read-buffer
  225. gnus-emacs-completing-read
  226. gnus-iswitchb-completing-read
  227. man)
  228. "Functions in which ido-ubiquitous should always be disabled.
  229. If you want to disable ido in a specific function or command, do
  230. not modify this variable. Instead, try `M-x customize-group
  231. ido-ubiquitous.")
  232. (dolist (func ido-ubiquitous-permanent-function-exceptions)
  233. (eval `(ido-ubiquitous-disable-in ,func)))
  234. (defun ido-ubiquitous--set-difference (list1 list2)
  235. "Replacement for `set-difference' from `cl'."
  236. (apply #'nconc
  237. (mapcar (lambda (elt) (unless (memq elt list2) (list elt)))
  238. list1)))
  239. (defun ido-ubiquitous-set-function-exceptions (sym newval)
  240. (let* ((oldval (when (boundp sym) (eval sym))))
  241. ;; Filter out the permanent exceptions so we never act on them.
  242. (setq oldval (ido-ubiquitous--set-difference oldval ido-ubiquitous-permanent-function-exceptions))
  243. (setq newval (ido-ubiquitous--set-difference newval ido-ubiquitous-permanent-function-exceptions))
  244. ;; Re-enable ido-ubiquitous on all old functions, in case they
  245. ;; were removed from the list.
  246. (dolist (oldfun oldval)
  247. (eval `(ido-ubiquitous-enable-in ,oldfun)))
  248. ;; Set the new value
  249. (set-default sym newval)
  250. ;; Disable ido-ubiquitous on all new functions
  251. (dolist (newfun newval)
  252. (eval `(ido-ubiquitous-disable-in ,newfun)))))
  253. ;;;###autoload
  254. (defcustom ido-ubiquitous-function-exceptions
  255. '(grep-read-files)
  256. "List of functions in which to disable ido-ubiquitous.
  257. If you need to add a function to this list, please also file a
  258. bug report at
  259. https://github.com/DarwinAwardWinner/ido-ubiquitous/issues
  260. Note that certain functions, such as `read-file-name', must
  261. always have ido-ubiquitous disabled, and cannot be added
  262. here. (They are effectively a permanent part of this list
  263. already.)"
  264. :group 'ido-ubiquitous
  265. :type '(repeat :tag "Functions"
  266. (symbol :tag "Function"))
  267. :set 'ido-ubiquitous-set-function-exceptions)
  268. (defcustom ido-ubiquitous-enable-compatibility t
  269. "Allow ido to emulate a quirk of `completing-read'.
  270. From the `completing-read' docstring:
  271. > If the input is null, `completing-read' returns DEF, or the
  272. > first element of the list of default values, or an empty string
  273. > if DEF is nil, regardless of the value of REQUIRE-MATCH.
  274. If this variable is non-nil, then ido-ubiquitous will attempt to
  275. emulate this behavior. Specifically, if RET is pressed
  276. immediately upon entering completion, an empty string will be
  277. returned instead of the first element in the list. This behavior
  278. is only enabled when ido is being used as a substitute for
  279. `completing-read', and not when it is used directly.
  280. This odd behavior is required for compatibility with an old-style
  281. usage pattern whereby the default was requested by returning an
  282. empty string. In this mode, the caller receives the empty string
  283. and handles the default case manually, while `completing-read'
  284. never has any knowledge of the default. This is a problem for
  285. ido, which always returns the first element in the list when the
  286. input is empty. Without knowledge of the default, it cannot
  287. ensure that the default is first on the list, so returning the
  288. first item is not the correct behavior. Instead, it must return
  289. an empty string like `completing-read'.
  290. When this mode is enabled, you can still select the first item on
  291. the list by prefixing \"RET\" with \"C-u\"."
  292. :type 'boolean
  293. :group 'ido-ubiquitous)
  294. ;;;###autoload
  295. (defcustom ido-ubiquitous-command-compatibility-exceptions '()
  296. "List of commands in which to disable compatibility.
  297. See `ido-ubiquitous-enable-compatibility' for a description of
  298. the compatibility behavior. If this behavior causes a command to
  299. break, add that command to this list to disable compatibility
  300. mode for just that command.
  301. Only *interactive* commands should go here. To disable
  302. compatibility mode in non-interactive functions, customize
  303. `ido-ubiquitous-function-compatibility-exceptions'."
  304. :type '(repeat (symbol :tag "Command"))
  305. :group 'ido-ubiquitous)
  306. (defvar ido-ubiquitous-initial-item nil
  307. "The first item selected when ido starts.")
  308. (defadvice ido-read-internal (before clear-initial-item activate)
  309. (setq ido-ubiquitous-initial-item nil))
  310. (defadvice ido-make-choice-list (after set-initial-item activate)
  311. (when (and ad-return-value (listp ad-return-value))
  312. (setq ido-ubiquitous-initial-item (car ad-return-value))))
  313. (defadvice ido-next-match (after clear-initial-item activate)
  314. (setq ido-ubiquitous-initial-item nil))
  315. (defadvice ido-prev-match (after clear-initial-item activate)
  316. (setq ido-ubiquitous-initial-item nil))
  317. (defadvice ido-exit-minibuffer (around compatibility activate)
  318. "Emulate a quirk of `completing-read'.
  319. > If the input is null, `completing-read' returns DEF, or the
  320. > first element of the list of default values, or an empty string
  321. > if DEF is nil, regardless of the value of REQUIRE-MATCH.
  322. See `ido-ubiquitous-enable-compatibility', which controls whether
  323. this advice has any effect."
  324. (if (and (eq ido-cur-item 'list)
  325. ido-ubiquitous-enable-compatibility
  326. ;; Only enable if we are replacing `completing-read'
  327. ido-this-call-replaces-completing-read
  328. ;; Disable in command exceptions
  329. (not (memq this-command ido-ubiquitous-command-compatibility-exceptions))
  330. ;; Input is empty
  331. (string= ido-text "")
  332. ;; Default is nil
  333. (null ido-default-item)
  334. ;; Prefix disables compatibility
  335. (not current-prefix-arg)
  336. (string= (car ido-cur-list)
  337. ido-ubiquitous-initial-item))
  338. (ido-select-text)
  339. ad-do-it)
  340. (setq ido-ubiquitous-initial-item nil))
  341. (defmacro ido-ubiquitous-disable-compatibility-in (func)
  342. "Disable ido-ubiquitous compatibility mode in FUNC."
  343. (let ((docstring
  344. (format "Disable ido-ubiquitous in %s" func)))
  345. `(defadvice ,func (around disable-ido-ubiquitous-compatibility activate)
  346. ,docstring
  347. (let (ido-ubiquitous-enable-compatibility) ad-do-it))))
  348. (defmacro ido-ubiquitous-enable-compatibility-in (func)
  349. "Re-enable ido-ubiquitous comaptibility mode in FUNC.
  350. This reverses the effect of a previous call to
  351. `ido-ubiquitous-disable-compatibility-in'."
  352. `(when (ad-find-advice ',func 'around 'disable-ido-ubiquitous-compatibility)
  353. (ad-disable-advice ',func 'around 'disable-ido-ubiquitous-compatibility)
  354. (ad-activate ',func)))
  355. (defun ido-ubiquitous-set-function-compatibility-exceptions (sym newval)
  356. (let* ((oldval (when (boundp sym) (eval sym))))
  357. ;; Re-enable compatibility on all old functions, in case they
  358. ;; were removed from the list.
  359. (dolist (oldfun oldval)
  360. (eval `(ido-ubiquitous-enable-compatibility-in ,oldfun)))
  361. ;; Set the new value
  362. (set-default sym newval)
  363. ;; Disable compatibility on all new functions
  364. (dolist (newfun newval)
  365. (eval `(ido-ubiquitous-disable-compatibility-in ,newfun)))))
  366. ;;;###autoload
  367. (defcustom ido-ubiquitous-function-compatibility-exceptions
  368. '()
  369. "List of functions in which to disable ido-ubiquitous compatibility mode.
  370. See `ido-ubiquitous-enable-compatibility' for a description of
  371. the compatibility behavior. If this behavior causes a function to
  372. break, add that function to this list to disable compatibility
  373. mode for just that command.
  374. If you need to add a function to this list, please also file a
  375. bug report at
  376. https://github.com/DarwinAwardWinner/ido-ubiquitous/issues"
  377. :group 'ido-ubiquitous
  378. :type '(repeat :tag "Functions"
  379. (symbol :tag "Function"))
  380. :set 'ido-ubiquitous-set-function-exceptions)
  381. (defun ido-ubiquitous-initialize ()
  382. "Do initial setup for ido-ubiquitous.
  383. This only needs to be called once when the file is first loaded."
  384. ;; Clean up old versions of ido-ubiquitous (1.3 and earlier) that
  385. ;; defined advice on `completing-read' instead of modifying
  386. ;; `completing-read-function'.
  387. (when (ad-find-advice 'completing-read 'around 'ido-ubiquitous)
  388. (ad-remove-advice 'completing-read 'around 'ido-ubiquitous)
  389. (ad-activate 'completing-read))
  390. ;; Make sure all exceptions are activated
  391. (ido-ubiquitous-set-function-exceptions
  392. 'ido-ubiquitous-function-exceptions
  393. ido-ubiquitous-function-exceptions)
  394. (ido-ubiquitous-set-function-compatibility-exceptions
  395. 'ido-ubiquitous-function-compatibility-exceptions
  396. ido-ubiquitous-function-compatibility-exceptions)
  397. ;; Make sure the mode is turned on/off as specified by the value of
  398. ;; the mode variable
  399. (ido-ubiquitous-mode (if ido-ubiquitous-mode 1 0)))
  400. (ido-ubiquitous-initialize)
  401. (provide 'ido-ubiquitous) ;;; ido-ubiquitous.el ends here