ido-ubiquitous.el 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. ;;; ido-ubiquitous.el --- Use ido (nearly) everywhere.
  2. ;; Author: Ryan C. Thompson
  3. ;; URL: https://github.com/DarwinAwardWinner/ido-ubiquitous
  4. ;; Version: 2.0
  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. ;; Check for required feature
  45. (eval-when-compile
  46. (when (not (boundp 'completing-read-function))
  47. (error "Could not find 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.6.")))
  48. (require 'ido)
  49. (require 'advice)
  50. (require 'cl)
  51. ;;; Custom Declarations
  52. ;;;###autoload
  53. (defgroup ido-ubiquitous nil
  54. "Use ido for (almost) all completion."
  55. :group 'ido)
  56. ;;;###autoload
  57. (define-minor-mode ido-ubiquitous-mode
  58. "Use `ido-completing-read' instead of `completing-read' almost everywhere.
  59. This mode has no effect unles `ido-mode' is also enabled.
  60. If this mode causes problems for a function, you can force the
  61. function to use the original completing read by using the macro
  62. `ido-ubiquitous-disable-in'. For example, if a
  63. function `foo' cannot work with ido-style completion, evaluate
  64. the following (for example by putting it in your .emacs file):
  65. (ido-ubiquitous-disable-in foo)"
  66. nil
  67. :global t
  68. :group 'ido-ubiquitous
  69. ;; Handle warning about ido disabled
  70. (when ido-ubiquitous-mode
  71. (unless (bound-and-true-p ido-mode)
  72. (if after-init-time
  73. (ido-ubiquitous-warn-about-ido-disabled)
  74. (add-hook 'after-init-hook 'ido-ubiquitous-warn-about-ido-disabled))))
  75. ;; Ensure emacs 23 code disabled
  76. (ignore-errors
  77. (ad-disable-advice 'completing-read 'around 'ido-ubiquitous-legacy)
  78. (ad-activate 'completing-read))
  79. ;; Actually enable/disable the mode
  80. (setq completing-read-function
  81. (if ido-ubiquitous-mode
  82. 'completing-read-ido
  83. ido-ubiquitous-fallback-completing-read-function)))
  84. ;;;###autoload
  85. (define-obsolete-variable-alias 'ido-ubiquitous
  86. 'ido-ubiquitous-mode "0.8")
  87. ;;;###autoload
  88. (define-obsolete-function-alias 'ido-ubiquitous
  89. 'ido-ubiquitous-mode "0.8")
  90. ;;;###autoload
  91. (defcustom ido-ubiquitous-fallback-completing-read-function
  92. ;; Initialize to the current value of `completing-read-function',
  93. ;; unless that is already set to the ido completer, in which case
  94. ;; use `completing-read-default'.
  95. (if (eq completing-read-function 'completing-read-ido)
  96. 'completing-read-default
  97. completing-read-function)
  98. "Alternate completing-read function to use when ido is not wanted.
  99. This will be used for functions that are incompatibile with ido
  100. or if ido cannot handle the completion arguments.
  101. If you turn off ido-ubiquitous mode, `completing-read-function'
  102. will be set to this."
  103. :type '(choice (const :tag "Standard emacs completion"
  104. completing-read-default)
  105. (function :tag "Other function"))
  106. :group 'ido-ubiquitous)
  107. ;;;###autoload
  108. (defcustom ido-ubiquitous-command-exceptions '()
  109. "List of commands that should not be affected by `ido-ubiquitous'.
  110. Even when `ido-ubiquitous' mode is enabled, these commands will
  111. continue to use `completing-read' instead of
  112. `ido-completing-read'.
  113. Only *interactive* commands should go here. To disable
  114. ido-ubiquitous in non-interactive functions, customize
  115. `ido-ubiquitous-function-exceptions'."
  116. ;; This isn't actually a hook, but it is a list of functions, so
  117. ;; that's close enough.
  118. :type 'hook
  119. :group 'ido-ubiquitous)
  120. ;;;###autoload
  121. (define-obsolete-variable-alias 'ido-ubiquitous-exceptions
  122. 'ido-ubiquitous-command-exceptions "0.4")
  123. ;;;###autoload
  124. (defvar ido-ubiquitous-default-function-exceptions
  125. '(read-file-name
  126. read-file-name-internal
  127. read-buffer
  128. gnus-emacs-completing-read
  129. gnus-iswitchb-completing-read
  130. man
  131. grep-read-files)
  132. "Default value of `ido-ubiquitous-function-exceptions'")
  133. (defun ido-ubiquitous-set-function-exceptions (sym newval)
  134. ;; Loop through all functions, enabling or disabling ido-ubiquitous
  135. ;; as appropriate.
  136. (mapatoms
  137. (lambda (sym)
  138. (if (memq sym newval)
  139. (eval `(ido-ubiquitous-disable-in ,sym))
  140. (eval `(ido-ubiquitous-enable-in ,sym)))))
  141. ;; Set the new value
  142. (set-default sym newval))
  143. (defmacro ido-ubiquitous-disable-in (func)
  144. "Disable ido-ubiquitous in FUNC."
  145. (put func 'ido-ubiquitous-disable t)
  146. (let ((docstring
  147. (format "Disable ido-ubiquitous in %s if its `idu-ubiquitous-disable' property is non-nil." func)))
  148. `(defadvice ,func (around disable-ido-ubiquitous activate)
  149. ,docstring
  150. (let ((ido-ubiquitous-mode
  151. (and ido-ubiquitous-mode
  152. (not (get ',func 'ido-ubiquitous-disable)))))
  153. ad-do-it))))
  154. (define-obsolete-function-alias
  155. 'disable-ido-ubiquitous-in
  156. 'ido-ubiquitous-disable-in
  157. "0.4")
  158. (defmacro ido-ubiquitous-enable-in (func)
  159. "Re-enable ido-ubiquitous in FUNC.
  160. This reverses the effect of a previous call to
  161. `ido-ubiquitous-disable-in' (if no such call was made, this is
  162. a no-op.)"
  163. `(when (get ',func 'ido-ubiquitous-disable)
  164. (put ,func 'ido-ubiquitous-disable nil)))
  165. (define-obsolete-function-alias
  166. 'enable-ido-ubiquitous-in
  167. 'ido-ubiquitous-enable-in
  168. "0.4")
  169. ;;;###autoload
  170. (defcustom ido-ubiquitous-function-exceptions
  171. ido-ubiquitous-default-function-exceptions
  172. "List of functions in which to disable ido-ubiquitous.
  173. If you need to add a function to this list, please also file a
  174. bug report at
  175. https://github.com/DarwinAwardWinner/ido-ubiquitous/issues
  176. Setting this variable directly has no effect. You must set it
  177. through Customize."
  178. :group 'ido-ubiquitous
  179. :type 'hook
  180. :options ido-ubiquitous-default-function-exceptions
  181. :set 'ido-ubiquitous-set-function-exceptions)
  182. ;;; Ido-ubiquitous core
  183. (defvar ido-ubiquitous-next-call-replaces-completing-read nil
  184. "If t, then the next call to ido-completing-read is by ido-ubiquitous.")
  185. (defvar ido-ubiquitous-this-call-replaces-completing-read nil
  186. "If t, then the current call to ido-completing-read is by ido-ubiquitous.")
  187. (defvar ido-ubiquitous-disable-for-one-command nil
  188. "If t, disable ido-ubiquitous for the next command.")
  189. (defun completing-read-ido (prompt collection &optional predicate
  190. require-match initial-input
  191. hist def inherit-input-method)
  192. "Ido-based method for reading from the minibuffer with completion.
  193. See `completing-read' for the meaning of the arguments.
  194. This function is a wrapper for `ido-completing-read' designed to
  195. be used as the value of `completing-read-function'."
  196. (let ((comp-read-fun
  197. (cond
  198. (ido-ubiquitous-disable-for-one-command
  199. (prog1
  200. ido-ubiquitous-fallback-completing-read-function
  201. (setq ido-ubiquitous-disable-for-one-command nil)))
  202. ((or inherit-input-method ; Can't handle this arg
  203. (bound-and-true-p completion-extra-properties) ; Can't handle this
  204. (not ido-mode)
  205. (not ido-ubiquitous-mode)
  206. (memq this-command ido-ubiquitous-command-exceptions))
  207. ido-ubiquitous-fallback-completing-read-function)
  208. ((let ((allcomp (all-completions "" collection predicate)))
  209. ;; Only use ido completion if there are actually any completions
  210. ;; to offer.
  211. (if allcomp
  212. (prog1 'ido-ubiquitous-completing-read
  213. (setq collection allcomp
  214. predicate nil))
  215. ido-ubiquitous-fallback-completing-read-function))))))
  216. (funcall comp-read-fun
  217. prompt collection predicate
  218. require-match initial-input
  219. hist def inherit-input-method)))
  220. (defun ido-ubiquitous-completing-read (&rest args)
  221. "Wrapper for `ido-completing-read' that enables ido-ubiquitous features."
  222. (let ((ido-ubiquitous-next-call-replaces-completing-read t))
  223. (apply 'ido-completing-read args)))
  224. (defadvice ido-completing-read (around detect-replacing-cr activate)
  225. "Detect whether this call was done through ido-ubiquitous.
  226. If so enable, extra features for ido-ubiquitous that handle
  227. special cases that `ido-completing-read' needs to handle to more
  228. fully emulate `completing-read'. This allows ido-ubiquitous extra
  229. features to avoid interfering with the normal operation of ido."
  230. (let* ((ido-ubiquitous-this-call-replaces-completing-read ido-ubiquitous-next-call-replaces-completing-read)
  231. (ido-ubiquitous-next-call-replaces-completing-read nil))
  232. (when ido-ubiquitous-this-call-replaces-completing-read
  233. ;; If DEF is a list, prepend it to CHOICES and set DEF to just the
  234. ;; car of the default list.
  235. (when (and def (listp def))
  236. (setq choices (delete-dups (append def choices))
  237. def (car def)))
  238. ;; Work around a bug in ido when both INITIAL-INPUT and DEF are provided
  239. ;; More info: https://github.com/technomancy/ido-ubiquitous/issues/18
  240. (let ((initial (cond ((null initial-input) "")
  241. ((stringp initial-input) initial-input)
  242. ((consp initial-input) (car initial-input))
  243. (t initial-input)))
  244. (deflist (if (listp def)
  245. def
  246. (list def))))
  247. (when (and deflist initial
  248. (stringp initial)
  249. (not (string= initial "")))
  250. ;; Both default and initial input were provided. So keep the
  251. ;; initial input and preprocess the choices list to put the
  252. ;; default at the head, then proceed with default = nil.
  253. (setq choices (delete-dups (append deflist (remove def choices)))
  254. def nil))))
  255. ad-do-it))
  256. ;;; Ido-ubiquitous interactive command exceptions
  257. ;; The following advices should allow ido-ubiquitous to apply to the
  258. ;; interactive forms of commands as well as their bodies.
  259. (defadvice call-interactively (around ido-ubiquitous-command-exceptions activate)
  260. (let ((ido-ubiquitous-disable-for-one-command
  261. (memq function ido-ubiquitous-command-exceptions)))
  262. ad-do-it))
  263. (defadvice command-execute (around ido-ubiquitous-command-exceptions activate)
  264. (let ((ido-ubiquitous-disable-for-one-command
  265. (and (commandp cmd t)
  266. (memq cmd ido-ubiquitous-command-exceptions))))
  267. ad-do-it))
  268. ;;; Ido-ubiquitous function exceptions
  269. ;;; Ido-ubiquitous compatibility with old completing-read
  270. ;;;###autoload
  271. (defgroup ido-ubiquitous-compatibility nil
  272. "Use ido for (almost) all completion."
  273. :group 'ido-ubiquitous)
  274. (defcustom ido-ubiquitous-enable-compatibility-globally t
  275. "Allow ido to emulate a quirk of `completing-read'.
  276. From the `completing-read' docstring:
  277. > If the input is null, `completing-read' returns DEF, or the
  278. > first element of the list of default values, or an empty string
  279. > if DEF is nil, regardless of the value of REQUIRE-MATCH.
  280. If this variable is non-nil, then ido-ubiquitous will attempt to
  281. emulate this behavior. Specifically, if RET is pressed
  282. immediately upon entering completion, an empty string will be
  283. returned instead of the first element in the list. This behavior
  284. is only enabled when ido is being used as a substitute for
  285. `completing-read', and not when it is used directly.
  286. This odd behavior is required for compatibility with an old-style
  287. usage pattern whereby the default was requested by returning an
  288. empty string. In this mode, the caller receives the empty string
  289. and handles the default case manually, while `completing-read'
  290. never has any knowledge of the default. This is a problem for
  291. ido, which always returns the first element in the list when the
  292. input is empty. Without knowledge of the default, it cannot
  293. ensure that the default is first on the list, so returning the
  294. first item is not the correct behavior. Instead, it must return
  295. an empty string like `completing-read'.
  296. When this mode is enabled, you can still select the first item on
  297. the list by prefixing \"RET\" with \"C-u\".
  298. If you want to enable compatibility selectively for specific
  299. commands or functions, see the other options in the
  300. `ido-ubiquitous-compatibility' group."
  301. :type 'boolean
  302. :group 'ido-ubiquitous-compatibility)
  303. ;;;###autoload
  304. (defcustom ido-ubiquitous-command-compatibility-list '()
  305. "List of commands in which to enable old-style compatibility.
  306. See `ido-ubiquitous-enable-compatibility-globally' for a
  307. description of the compatibility behavior. If ido doesn't
  308. properly select the default for a command, try adding it to this
  309. list.
  310. Only *interactive* commands should go here. To disable
  311. compatibility mode in non-interactive functions, customize
  312. `ido-ubiquitous-function-compatibility-exceptions'."
  313. :type 'hook
  314. :group 'ido-ubiquitous-compatibility)
  315. (defmacro ido-ubiquitous-enable-compatibility-in (func)
  316. "Enable ido-ubiquitous old-style compatibility in FUNC."
  317. (let ((docstring
  318. (format "Enable ido-ubiquitous old-style compatibility in %s if its `idu-ubiquitous-enable-compatibility' property is non-nil." func)))
  319. `(progn
  320. (defadvice ,func (around disable-ido-ubiquitous activate)
  321. ,docstring
  322. (let ((ido-ubiquitous-enable-compatibility-globally
  323. (or ido-ubiquitous-enable-compatibility-globally
  324. (get ',func 'ido-ubiquitous-enable-compatibility))))
  325. ad-do-it))
  326. (put func 'ido-ubiquitous-enable-compatibility t))))
  327. (defmacro ido-ubiquitous-disable-compatibility-in (func)
  328. "Enable ido-ubiquitous old-style compatibility in FUNC.
  329. This reverses the effect of a previous call to
  330. `ido-ubiquitous-enable-compatibility-in' (if no such call was
  331. made, this is a no-op.)"
  332. `(when (get ',func 'ido-ubiquitous-enable-compatibility)
  333. (put ,func 'ido-ubiquitous-enable-compatibility nil)))
  334. (defun ido-ubiquitous-set-function-compatibility-list (sym newval)
  335. ;; Loop through all functions, enabling or disabling ido-ubiquitous
  336. ;; as appropriate.
  337. (mapatoms
  338. (lambda (sym)
  339. (if (memq sym newval)
  340. (eval `(ido-ubiquitous-enable-compatibility-in ,sym))
  341. (eval `(ido-ubiquitous-disable-compatibility-in ,sym)))))
  342. ;; Set the new value
  343. (set-default sym newval))
  344. ;;;###autoload
  345. (defcustom ido-ubiquitous-function-compatibility-list
  346. '()
  347. "List of functions in which to enable old-style compatibility.
  348. See `ido-ubiquitous-enable-compatibility-globally' for a
  349. description of the compatibility behavior. If ido doesn't
  350. properly select the default selection for a function, try adding
  351. it to this list.
  352. If you need to add a function to this list, please also file a
  353. bug report at
  354. https://github.com/DarwinAwardWinner/ido-ubiquitous/issues"
  355. :group 'ido-ubiquitous-compatibility
  356. :type 'hook
  357. :set 'ido-ubiquitous-set-function-compatibility-list)
  358. (defvar ido-ubiquitous-initial-item nil
  359. "The first item selected when ido starts.")
  360. (defadvice ido-read-internal (before clear-initial-item activate)
  361. (setq ido-ubiquitous-initial-item nil))
  362. (defadvice ido-make-choice-list (after set-initial-item activate)
  363. (when (and ad-return-value (listp ad-return-value))
  364. (setq ido-ubiquitous-initial-item (car ad-return-value))))
  365. (defadvice ido-next-match (after clear-initial-item activate)
  366. (setq ido-ubiquitous-initial-item nil))
  367. (defadvice ido-prev-match (after clear-initial-item activate)
  368. (setq ido-ubiquitous-initial-item nil))
  369. (defadvice ido-exit-minibuffer (around compatibility activate)
  370. "Emulate a quirk of `completing-read'.
  371. > If the input is null, `completing-read' returns DEF, or the
  372. > first element of the list of default values, or an empty string
  373. > if DEF is nil, regardless of the value of REQUIRE-MATCH.
  374. See `ido-ubiquitous-enable-compatibility-globally', which
  375. controls whether this advice has any effect."
  376. (if (and (eq ido-cur-item 'list)
  377. ;; Only enable if we are replacing `completing-read'
  378. ido-ubiquitous-this-call-replaces-completing-read
  379. ;; Compatibiliy enabled
  380. (or ido-ubiquitous-enable-compatibility-globally
  381. (memq this-command ido-ubiquitous-command-compatibility-list))
  382. ;; Input is empty
  383. (string= ido-text "")
  384. ;; Default is nil
  385. (null ido-default-item)
  386. ;; Prefix disables compatibility
  387. (not current-prefix-arg)
  388. (string= (car ido-cur-list)
  389. ido-ubiquitous-initial-item))
  390. (ido-select-text)
  391. ad-do-it)
  392. (setq ido-ubiquitous-initial-item nil))
  393. (defadvice call-interactively (around ido-ubiquitous-oldstyle-compatibility activate)
  394. (let ((ido-ubiquitous-enable-compatibility-globally
  395. (or ido-ubiquitous-enable-compatibility-globally
  396. (memq function ido-ubiquitous-command-compatibility-list))))
  397. ad-do-it))
  398. (defadvice command-execute (around ido-ubiquitous-oldstyle-compatibility activate)
  399. (let ((ido-ubiquitous-enable-compatibility-globally
  400. (or ido-ubiquitous-enable-compatibility-globally
  401. (memq function ido-ubiquitous-command-compatibility-list))))
  402. ad-do-it))
  403. ;;; Other
  404. (defun ido-ubiquitous-initialize ()
  405. "Do initial setup for ido-ubiquitous.
  406. This only needs to be called once when the file is first loaded."
  407. ;; Clean up old versions of ido-ubiquitous that defined advice on
  408. ;; `completing-read' instead of modifying
  409. ;; `completing-read-function'.
  410. (when (ad-find-advice 'completing-read 'around 'ido-ubiquitous)
  411. (ad-remove-advice 'completing-read 'around 'ido-ubiquitous)
  412. (ad-activate 'completing-read))
  413. ;; Make sure all exceptions are activated
  414. (ido-ubiquitous-set-function-exceptions
  415. 'ido-ubiquitous-function-exceptions
  416. ido-ubiquitous-function-exceptions)
  417. (ido-ubiquitous-set-function-compatibility-list
  418. 'ido-ubiquitous-function-compatibility-list
  419. ido-ubiquitous-function-compatibility-list)
  420. ;; Make sure the mode is turned on/off as specified by the value of
  421. ;; the mode variable
  422. (ido-ubiquitous-mode (if ido-ubiquitous-mode 1 0)))
  423. (ido-ubiquitous-initialize)
  424. (defun ido-ubiquitous-warn-about-ido-disabled ()
  425. "Warn if ido-ubiquitous is enabled without ido.
  426. Don't warn if emacs is still initializing, since ido-ubiquitous
  427. could be enabled first during init."
  428. (if (and after-init-time
  429. (not (bound-and-true-p ido-mode)))
  430. (warn "Ido-ubiquitous-mode enabled without ido mode. Ido-ubiquitous requires ido mode to be enabled.")))
  431. (provide 'ido-ubiquitous) ;;; ido-ubiquitous.el ends here