ido-ubiquitous.el 20 KB

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