ido-ubiquitous.el 20 KB

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