ido-ubiquitous.el 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. ;;; ido-ubiquitous.el --- Use ido (nearly) everywhere.
  2. ;; Author: Ryan C. Thompson
  3. ;; URL: https://github.com/DarwinAwardWinner/ido-ubiquitous
  4. ;; Version: 0.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. ;;; License:
  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, or (at your option)
  29. ;; any later version.
  30. ;;
  31. ;; This program is distributed in the hope that it will be useful,
  32. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  33. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  34. ;; GNU 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; see the file COPYING. If not, write to the
  38. ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  39. ;; Boston, MA 02110-1301, USA.
  40. ;;; Code:
  41. (require 'ido)
  42. ;;;###autoload
  43. (defgroup ido-ubiquitous nil
  44. "Use ido for (almost) all completion."
  45. :group 'ido)
  46. ;;;###autoload
  47. (define-minor-mode ido-ubiquitous-mode
  48. "Use `ido-completing-read' instead of `completing-read' almost everywhere.
  49. This mode has no effect unles `ido-mode' is also enabled.
  50. If this mode causes problems for a function, you can force the
  51. function to use the original completing read by using the macro
  52. `ido-ubiquitous-disable-in'. For example, if a
  53. function `foo' cannot work with ido-style completion, evaluate
  54. the following (for example by putting it in your .emacs file):
  55. (ido-ubiquitous-disable-in foo)"
  56. nil
  57. :global t
  58. :group 'ido-ubiquitous)
  59. ;;;###autoload
  60. (define-obsolete-variable-alias 'ido-ubiquitous
  61. 'ido-ubiquitous-mode "0.8")
  62. ;;;###autoload
  63. (define-obsolete-function-alias 'ido-ubiquitous
  64. 'ido-ubiquitous-mode "0.8")
  65. ;;;###autoload
  66. (defcustom ido-ubiquitous-command-exceptions '()
  67. "List of commands that should not be affected by `ido-ubiquitous'.
  68. Even when `ido-ubiquitous' mode is enabled, these commands will
  69. continue to use `completing-read' instead of
  70. `ido-completing-read'.
  71. Only *interactive* commands should go here. To disable
  72. ido-ubiquitous in non-interactive functions, customize
  73. `ido-ubiquitous-function-exceptions'."
  74. :type '(repeat (symbol :tag "Command"))
  75. :group 'ido-ubiquitous)
  76. ;;;###autoload
  77. (define-obsolete-variable-alias 'ido-ubiquitous-exceptions
  78. 'ido-ubiquitous-command-exceptions "0.4")
  79. (defadvice completing-read (around ido-ubiquitous activate)
  80. (if (or (not ido-mode)
  81. (not ido-ubiquitous-mode)
  82. (memq this-command ido-ubiquitous-command-exceptions)
  83. ;; Avoid infinite recursion from ido calling completing-read
  84. (boundp 'ido-cur-item))
  85. ad-do-it
  86. (let ((allcomp (all-completions "" collection predicate)))
  87. ;; Only use ido completion if there are actually any completions
  88. ;; to offer.
  89. (if allcomp
  90. (setq ad-return-value
  91. (ido-completing-read prompt allcomp
  92. nil require-match initial-input hist def))
  93. ad-do-it))))
  94. (defmacro ido-ubiquitous-disable-in (func)
  95. "Disable ido-ubiquitous in FUNC."
  96. (let ((docstring
  97. (format "Disable ido-ubiquitous in %s" func)))
  98. `(defadvice ,func (around disable-ido-ubiquitous activate)
  99. ,docstring
  100. (let (ido-ubiquitous-mode) ad-do-it))))
  101. (define-obsolete-function-alias
  102. 'disable-ido-ubiquitous-in
  103. 'ido-ubiquitous-disable-in
  104. "0.4")
  105. (defmacro ido-ubiquitous-enable-in (func)
  106. "Re-enable ido-ubiquitous in FUNC.
  107. This reverses the effect of `ido-ubiquitous-disable-in'."
  108. ;; In my experience, simply using `ad-remove-advice' or
  109. ;; `ad-disable-advice' doesn't work correctly (in Emacs 23).
  110. ;; Instead, I've found that one must redefine the advice under the
  111. ;; same name ("disable-ido-ubiquitous") to simply call the original
  112. ;; function with no modifications. This has the same effect
  113. ;; (disables the advice), but is presumably less efficient.
  114. (let ((docstring
  115. (format "DO NOT disable ido-ubiquitous in %s" func)))
  116. `(defadvice ,func (around disable-ido-ubiquitous activate)
  117. ,docstring
  118. ad-do-it)))
  119. (define-obsolete-function-alias
  120. 'enable-ido-ubiquitous-in
  121. 'ido-ubiquitous-enable-in
  122. "0.4")
  123. ;; Always disable ido-ubiquitous in `find-file' and similar functions,
  124. ;; because they are not supposed to use ido.
  125. (defvar ido-ubiquitous-permanent-function-exceptions
  126. '(read-file-name)
  127. "Functions in which ido-ubiquitous should always be disabled.
  128. If you want to disable ido in a specific function or command, do
  129. not modify this variable. Instead, try `M-x customize-group
  130. ido-ubiquitous..")
  131. (dolist (func ido-ubiquitous-permanent-function-exceptions)
  132. (eval `(ido-ubiquitous-disable-in ,func)))
  133. (defun ido-ubiquitous--set-difference (list1 list2)
  134. "Replacement for `set-difference' from `cl'."
  135. (apply #'nconc
  136. (mapcar (lambda (elt) (unless (memq elt list2) (list elt)))
  137. list1)))
  138. (defun ido-ubiquitous-set-function-exceptions (sym newval)
  139. (let* ((oldval (when (boundp sym) (eval sym))))
  140. ;; Filter out permanent fixtures
  141. (setq oldval (ido-ubiquitous--set-difference oldval ido-ubiquitous-permanent-function-exceptions))
  142. (setq newval (ido-ubiquitous--set-difference newval ido-ubiquitous-permanent-function-exceptions))
  143. ;; Re-enable ido-ubiquitous on all old functions, in case they
  144. ;; were removed from the list.
  145. (dolist (oldfun oldval)
  146. (eval `(ido-ubiquitous-enable-in ,oldfun)))
  147. ;; Set the new value
  148. (set-default sym newval)
  149. ;; Disable ido-ubiquitous on all new functions
  150. (dolist (newfun newval)
  151. (eval `(ido-ubiquitous-disable-in ,newfun)))))
  152. ;;;###autoload
  153. (defcustom ido-ubiquitous-function-exceptions
  154. '(grep-read-files)
  155. "List of functions in which to disable ido-ubiquitous.
  156. Certain functions, such as `read-file-name', always have
  157. ido-ubiquitous disabled, and cannot be added here. (They are
  158. effectively permanently part of this list already.)"
  159. :group 'ido-ubiquitous
  160. :type '(repeat :tag "Functions"
  161. (symbol :tag "Function"))
  162. :set 'ido-ubiquitous-set-function-exceptions)
  163. (defadvice ido-exit-minibuffer (around required-allow-empty-string activate)
  164. "Emulate a quirk of `completing-read'.
  165. Apparently, `completing-read' used to request the default item by
  166. returning an empty string when RET was pressed with an empty input.
  167. This forces `ido-completing-read' to do the same (instead of returning
  168. the first choice in the list).
  169. This has no effect when ido is completing buffers or files."
  170. (if (and (eq ido-cur-item 'list)
  171. ido-require-match
  172. (null ido-default-item)
  173. (string= ido-text ""))
  174. (ido-select-text)
  175. ad-do-it))
  176. (provide 'ido-ubiquitous) ;;; ido-ubiquitous.el ends here