ido-completing-read+.el 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159
  1. ;;; ido-completing-read+.el --- A completing-read-function using ido -*- lexical-binding: t -*-
  2. ;; Copyright (C) 2011-2017 Ryan C. Thompson
  3. ;; Filename: ido-completing-read+.el
  4. ;; Author: Ryan Thompson
  5. ;; Created: Sat Apr 4 13:41:20 2015 (-0700)
  6. ;; Version: 4.3
  7. ;; Package-Requires: ((emacs "24.4") (cl-lib "0.5") (s "0.1"))
  8. ;; URL: https://github.com/DarwinAwardWinner/ido-completing-read-plus
  9. ;; Keywords: ido, completion, convenience
  10. ;; This file is NOT part of GNU Emacs.
  11. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  12. ;;
  13. ;;; Commentary:
  14. ;; If you use the excellent `ido-mode' for efficient completion of
  15. ;; file names and buffers, you might wonder if you can get ido-style
  16. ;; completion everywhere else too. Well, that's what this package
  17. ;; does! ido-ubiquitous is here to enable ido-style completion for
  18. ;; (almost) every function that uses the standard completion function
  19. ;; `completing-read'.
  20. ;; This package implements the `ido-completing-read+' function, which
  21. ;; is a wrapper for `ido-completing-read'. Importantly, it detects
  22. ;; edge cases that ordinary ido cannot handle and either adjusts them
  23. ;; so ido *can* handle them, or else simply falls back to Emacs'
  24. ;; standard completion instead. Hence, you can safely set
  25. ;; `completing-read-function' to `ido-completing-read+' without
  26. ;; worrying about breaking completion features that are incompatible
  27. ;; with ido.
  28. ;; To use this package, call `ido-ubiquitous-mode' to enable the mode,
  29. ;; or use `M-x customize-variable ido-ubiquitous-mode' it to enable it
  30. ;; permanently. Once the mode is enabled, most functions that use
  31. ;; `completing-read' will now have ido completion. If you decide in
  32. ;; the middle of a command that you would rather not use ido, just use
  33. ;; C-f or C-b at the end/beginning of the input to fall back to
  34. ;; non-ido completion (this is the same shortcut as when using ido for
  35. ;; buffers or files).
  36. ;; Note that `completing-read-default' is a very general function with
  37. ;; many complex behaviors that ido cannot emulate. This package
  38. ;; attempts to detect some of these cases and avoid using ido when it
  39. ;; sees them. So some functions will not have ido completion even when
  40. ;; this mode is enabled. Some other functions have ido disabled in
  41. ;; them because their packages already provide support for ido via
  42. ;; other means (for example, magit). See `M-x describe-variable
  43. ;; ido-cr+-function-blacklist' for more information.
  44. ;; ido-completing-read+ version 4.0 is a major update. The formerly
  45. ;; separate package ido-ubiquitous has been subsumed into
  46. ;; ido-completing-read+, so ido-ubiquitous 4.0 is just a wrapper that
  47. ;; loads ido-completing-read+ and displays a warning about being
  48. ;; obsolete. If you have previously customized ido-ubiquitous, be sure
  49. ;; to check out `M-x customize-group ido-completing-read-plus' after
  50. ;; updating to 4.0 and make sure the new settings are to your liking.
  51. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  52. ;;
  53. ;; This program is free software: you can redistribute it and/or modify
  54. ;; it under the terms of the GNU General Public License as published by
  55. ;; the Free Software Foundation, either version 3 of the License, or (at
  56. ;; your option) any later version.
  57. ;;
  58. ;; This program is distributed in the hope that it will be useful, but
  59. ;; WITHOUT ANY WARRANTY; without even the implied warranty of
  60. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  61. ;; General Public License for more details.
  62. ;;
  63. ;; You should have received a copy of the GNU General Public License
  64. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  65. ;;
  66. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  67. ;;
  68. ;;; Code:
  69. (defconst ido-completing-read+-version "4.3"
  70. "Currently running version of ido-completing-read+.
  71. Note that when you update ido-completing-read+, this variable may
  72. not be updated until you restart Emacs.")
  73. (require 'ido)
  74. (require 'cl-lib)
  75. (require 'cus-edit)
  76. (require 's)
  77. ;;; Debug messages
  78. (define-minor-mode ido-cr+-debug-mode
  79. "If non-nil, ido-cr+ will print debug info.
  80. Debug info is printed to the *Messages* buffer."
  81. nil
  82. :global t
  83. :group 'ido-completing-read-plus)
  84. (defsubst ido-cr+--debug-message (format-string &rest args)
  85. (when ido-cr+-debug-mode
  86. (apply #'message (concat "ido-completing-read+: " format-string) args)))
  87. ;;; Ido variables
  88. ;; For unknown reasons, these variables need to be re-declared here to
  89. ;; silence byte-compiler warnings, despite already being declared in
  90. ;; ido.el.
  91. (defmacro define-ido-internal-var (symbol &optional initvalue docstring)
  92. "Declare and initialize an ido internal variable.
  93. This is used to suppress byte-compilation warnings about
  94. reference to free variables when ido-cr+ attempts to access
  95. internal ido variables with no initial value set. Such variables
  96. are originally declared like `(defvar VARNAME)'.
  97. This is a wrapper for `defvar' that supplies a default for the
  98. INITVALUE and DOCSTRING arguments."
  99. `(defvar ,symbol ,initvalue
  100. ,(or docstring
  101. "Internal ido variable.
  102. This variable was originally declared in `ido.el' without an
  103. initial value or docstring. The documentation you're reading
  104. comes from re-declaring it in `ido-completing-read+.el' in order
  105. to suppress some byte-compilation warnings. Setting another
  106. package's variable is not safe in general, but in this case it
  107. should be, because ido always let-binds this variable before
  108. using it, so the initial value shouldn't matter.")))
  109. (define-ido-internal-var ido-context-switch-command)
  110. (define-ido-internal-var ido-cur-list)
  111. (define-ido-internal-var ido-require-match)
  112. ;;;###autoload
  113. (defvar ido-cr+-minibuffer-depth -1
  114. "Minibuffer depth of the most recent ido-cr+ activation.
  115. If this equals the current minibuffer depth, then the minibuffer
  116. is currently being used by ido-cr+, and ido-cr+ feature will be
  117. active. Otherwise, something else is using the minibuffer and
  118. ido-cr+ features will be deactivated to avoid interfering with
  119. the other command.
  120. This is set to -1 by default, since `(minibuffer-depth)' should
  121. never return this value.")
  122. (defvar ido-cr+-assume-static-collection nil
  123. "If non-nil, ido-cr+ will assume that the collection is static.
  124. This is used to avoid unnecessary work in the case where the
  125. collection is a function, since a function collection could
  126. potentially change the set of completion candidates
  127. dynamically.")
  128. (defvar ido-cr+-current-command nil
  129. "Command most recently invoked by `call-interactively'.
  130. This is necessary because `command-execute' and
  131. `call-interactively' do not set `this-command'. Instead, the C
  132. code that calls `command-execute' sets it beforehand, so using
  133. either of those functions directly won't set `this-command'.")
  134. (defvar ido-cr+-dynamic-collection nil
  135. "Stores the collection argument if it is a function.
  136. This allows ido-cr+ to update the set of completion candidates
  137. dynamically.")
  138. (defvar ido-cr+-previous-dynamic-update-texts nil
  139. "Values of `ido-text' for the last few dynamic collection updates.
  140. This is used in `ido-cr+-update-dynamic-collection' as an LRU
  141. cache of recent values of `ido-text' in order to skip re-checking
  142. prefixes of these strings.")
  143. (defvar ido-cr+-dynamic-update-idle-time 0.25
  144. "Time to wait before updating dynamic completion list.")
  145. (defvar ido-cr+-dynamic-update-timer nil
  146. "Idle timer for updating dynamic completion list.")
  147. (defvar ido-cr+-exhibit-pending nil
  148. "This is non-nil after calling `ido-tidy' until the next call to `ido-exhibit'.
  149. Typically this is non-nil while any command is running and nil at all
  150. other times, since those two functions are in `pre-command-hook'
  151. and `post-command-hook' respectively. In particular, this will
  152. generally be nil while running an idle timer.")
  153. (make-obsolete-variable
  154. 'ido-cr+-no-default-action
  155. " This variable no longer has any effect. Customize `ido-cr+-nil-def-alternate-behavior-list' instead."
  156. "4.2")
  157. (defvar ido-cr+-orig-completing-read-args nil
  158. "Original arguments passed to `ido-completing-read+'.
  159. These are used for falling back to `completing-read-default'.")
  160. (defgroup ido-completing-read-plus nil
  161. "Extra features and compatibility for `ido-completing-read'."
  162. :group 'ido)
  163. (defcustom ido-cr+-fallback-function
  164. ;; Initialize to the current value of `completing-read-function',
  165. ;; unless that is already set to the ido completer, in which case
  166. ;; use `completing-read-default'.
  167. (if (memq completing-read-function
  168. '(ido-completing-read+
  169. ido-completing-read
  170. ;; Current ido-ubiquitous function
  171. completing-read-ido-ubiquitous
  172. ;; Old ido-ubiquitous functions that shouldn't be used
  173. completing-read-ido
  174. ido-ubiquitous-completing-read))
  175. 'completing-read-default
  176. completing-read-function)
  177. "Alternate completing-read function to use when ido is not wanted.
  178. This will be used for functions that are incompatible with ido
  179. or if ido cannot handle the completion arguments. It will also be
  180. used when the user requests non-ido completion manually via C-f
  181. or C-b."
  182. :type '(choice (const :tag "Standard emacs completion"
  183. completing-read-default)
  184. (function :tag "Other function"))
  185. :group 'ido-completing-read-plus)
  186. (defcustom ido-cr+-max-items 30000
  187. "Max collection size to use ido-cr+ on.
  188. If `ido-completing-read+' is called on a collection larger than
  189. this, the fallback completion method will be used instead. To
  190. disable fallback based on collection size, set this to nil."
  191. :type '(choice (const :tag "No limit" nil)
  192. (integer
  193. :tag "Limit" :value 30000
  194. :validate
  195. (lambda (widget)
  196. (let ((v (widget-value widget)))
  197. (if (and (integerp v)
  198. (> v 0))
  199. nil
  200. (widget-put widget :error "This field should contain a positive integer")
  201. widget)))))
  202. :group 'ido-completing-read-plus)
  203. (defcustom ido-cr+-function-blacklist
  204. '(read-file-name-internal
  205. read-buffer
  206. ;; https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues/60
  207. todo-add-category
  208. ;; Gnus already supports ido on its own
  209. gnus-emacs-completing-read
  210. gnus-iswitchb-completing-read
  211. grep-read-files
  212. ;; Magit already supports ido on its own
  213. magit-builtin-completing-read
  214. ;; ESS already supports ido on its own
  215. ess-completing-read
  216. ;; https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues/39
  217. Info-read-node-name
  218. ;; https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues/44
  219. tmm-prompt)
  220. "Functions & commands for which ido-cr+ should be disabled.
  221. Each entry can be either a symbol or a string. A symbol means to
  222. fall back specifically for the named function. A regular
  223. expression means to fall back for any function whose name matches
  224. that regular expression. When ido-cr+ is called through
  225. `completing-read', if any function in the call stack of the
  226. current command matches any of the blacklist entries, ido-cr+
  227. will be disabled for that command. Additionally, if the
  228. collection in the call to `completing-read' matches any of the
  229. blacklist entries, ido-cr+ will be disabled.
  230. Note that using specific function names is generally preferable
  231. to regular expressions, because the associated function
  232. definitions will be compared directly, so if the same function is
  233. called by another name, it should still trigger the fallback. For
  234. regular expressions, only name-based matching is possible."
  235. :group 'ido-completing-read-plus
  236. :type '(repeat (choice (symbol :tag "Function or command name")
  237. (string :tag "Regexp"))))
  238. (defcustom ido-cr+-function-whitelist
  239. nil
  240. "Functions & commands for which ido-cr+ should be enabled.
  241. If this variable is nil, the whitelist will not be used, and
  242. ido-cr+ will be allowed in all functions/commands not listed in
  243. `ido-cr+-function-backlist'.
  244. If this variable is non-nil, ido-cr+'s whitelisting mode will be
  245. enabled, and ido-cr+ will be disabled for *all* functions unless
  246. they match one of the entries. Matching is done in the same
  247. manner as `ido-cr+-function-blacklist', and blacklisting takes
  248. precedence over whitelisting."
  249. :group 'ido-completing-read-plus
  250. :type '(repeat (choice (symbol :tag "Function or command name")
  251. (string :tag "Regexp"))))
  252. (defcustom ido-cr+-nil-def-alternate-behavior-list
  253. '("\\`describe-\\(function\\|variable\\)\\'"
  254. "\\`wl-"
  255. ;; https://github.com/mrkkrp/ebal/issues/12
  256. "\\`ebal-"
  257. ;; https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues/4
  258. webjump
  259. ;; https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues/83
  260. where-is
  261. ;; https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues/51
  262. find-tag
  263. ;; https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues/89
  264. "\\`etags-select-"
  265. ;; https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues/58
  266. imenu--completion-buffer
  267. ;; https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues/116
  268. project--completing-read-strict
  269. ;; https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues/127#issuecomment-319463217
  270. bookmark-completing-read
  271. )
  272. "Functions & commands with alternate behavior when DEF is nil.
  273. This variable has the same format as
  274. `ido-cr+-function-blacklist'. When `ido-completing-read+` is
  275. called through `completing-read' by/with any command, function,
  276. or collection matched by entries in this list, it will behave
  277. differently when DEF is nil. Instead of using the empty string as
  278. the default value, it will use the first element of COLLECTION.
  279. This is needed for optimal compatibility with commands written
  280. under the assumption that REQUIRE-MATCH means that a match is
  281. required."
  282. :group 'ido-completing-read-plus
  283. :type '(repeat (choice (symbol :tag "Function or command name")
  284. (string :tag "Regexp"))))
  285. (defvaralias 'ido-cr+-nil-def-wall-of-shame 'ido-cr+-nil-def-alternate-behavior-list
  286. "Functions and commands whose authors need to read the docstring for `completing-read'.
  287. Many functions that call `completing-read' are written with the
  288. assumption that the setting the REQUIRE-MATCH argument of
  289. `completing-read' to t means it is required to return a match.
  290. While that would make logical sense, it's wrong. the docstring
  291. for `completing-read' describes the correct behavior.
  292. > If the input is null, ‘completing-read’ returns DEF, or the
  293. > first element of the list of default values, or an empty string
  294. > if DEF is nil, regardless of the value of REQUIRE-MATCH.
  295. This can be avoided by passing an element of COLLECTION as DEF
  296. instead of leaving it as nil.")
  297. ;;;###autoload
  298. (defcustom ido-cr+-replace-completely nil
  299. "If non-nil, replace `ido-completeing-read' completely with ido-cr+.
  300. Enabling this may interfere with or cause errors in other
  301. packages that use `ido-completing-read'. If you discover any such
  302. incompatibilities, please file a bug report at
  303. https://github.com/DarwinAwardWinner/ido-completing-read-plus/issues"
  304. :type 'boolean)
  305. ;; Signal used to trigger fallback
  306. (define-error 'ido-cr+-fallback "ido-cr+-fallback")
  307. (defsubst ido-cr+--explain-fallback (arg)
  308. ;; This function accepts a string, or an ido-cr+-fallback
  309. ;; signal.
  310. (when ido-cr+-debug-mode
  311. (when (and (listp arg)
  312. (eq (car arg) 'ido-cr+-fallback))
  313. (setq arg (cadr arg)))
  314. (ido-cr+--debug-message "Falling back to `%s' because %s."
  315. ido-cr+-fallback-function arg)))
  316. ;;;###autoload
  317. (defsubst ido-cr+-active ()
  318. "Returns non-nil if ido-cr+ is currently using the minibuffer."
  319. (>= ido-cr+-minibuffer-depth (minibuffer-depth)))
  320. (defsubst ido-cr+-default-was-provided ()
  321. "Returns non-nil if ido-cr+ was passed a non-nil default argument."
  322. (and (nth 6 ido-cr+-orig-completing-read-args)))
  323. (defun ido-cr+--called-from-completing-read ()
  324. "Returns non-nil if the most recent call to ido-cr+ was from `completing-read'."
  325. (equal (cadr (backtrace-frame 1 'ido-completing-read+))
  326. 'completing-read))
  327. (defmacro ido-cr+-function-is-in-list (fun fun-list &optional list-name)
  328. "Return non-nil if FUN matches an entry in FUN-LIST.
  329. This is used to check for matches to `ido-cr+-function-blacklist'
  330. and `ido-cr+-function-whitelist'. Read those docstrings to see
  331. how the matching is done.
  332. This is declared as macro only in order to extract the variable
  333. name used for the second argument so it can be used in a debug
  334. message. It should be called as if it were a normal function."
  335. (when (null list-name)
  336. (if (symbolp fun-list)
  337. (setq list-name (symbol-name fun-list))
  338. (setq list-name "list")))
  339. `(cl-loop
  340. for entry in ,fun-list
  341. if (cond
  342. ;; Nil: Never matches anything
  343. ((null entry)
  344. nil)
  345. ;; Symbol: Compare names and function definitions
  346. ((symbolp entry)
  347. (or (eq entry ,fun)
  348. (let ((entry-def (ignore-errors (indirect-function entry)))
  349. (fun-def (ignore-errors (indirect-function ,fun))))
  350. (and
  351. fun-def entry-def
  352. (eq
  353. (indirect-function entry-def)
  354. (indirect-function fun-def))))))
  355. ;; String: Do regexp matching against function name if it is a
  356. ;; symbol
  357. ((stringp entry)
  358. (and (symbolp ,fun)
  359. (string-match-p entry (symbol-name ,fun))))
  360. ;; Anything else: invalid blacklist entry
  361. (t
  362. (ido-cr+--debug-message "Ignoring invalid entry in %s: `%S'" ,list-name entry)
  363. nil))
  364. return entry
  365. ;; If no blacklist entry matches, return nil
  366. finally return nil))
  367. (defun ido-cr+-function-is-blacklisted (fun)
  368. "Return non-nil if FUN is blacklisted.
  369. See `ido-cr+-function-blacklist'."
  370. (ido-cr+-function-is-in-list fun ido-cr+-function-blacklist))
  371. (defun ido-cr+-function-is-whitelisted (fun)
  372. "Return non-nil if FUN is whitelisted.
  373. See `ido-cr+-function-whitelist'."
  374. (or (null ido-cr+-function-whitelist)
  375. (ido-cr+-function-is-in-list fun ido-cr+-function-whitelist)))
  376. ;;;###autoload
  377. (defun ido-completing-read+ (prompt collection &optional predicate
  378. require-match initial-input
  379. hist def inherit-input-method)
  380. "ido-based method for reading from the minibuffer with completion.
  381. See `completing-read' for the meaning of the arguments.
  382. This function is a wrapper for `ido-completing-read' designed to
  383. be used as the value of `completing-read-function'. Importantly,
  384. it detects edge cases that ido cannot handle and uses normal
  385. completion for them."
  386. (let (;; Save the original arguments in case we need to do the
  387. ;; fallback
  388. (ido-cr+-orig-completing-read-args
  389. (list prompt collection predicate require-match
  390. initial-input hist def inherit-input-method))
  391. ;; Need to save this since activating the minibuffer once will
  392. ;; clear out any temporary minibuffer hooks, which need to get
  393. ;; restored before falling back.
  394. (orig-minibuffer-setup-hook minibuffer-setup-hook)
  395. ;; Need just the string part of INITIAL-INPUT
  396. (initial-input-string
  397. (cond
  398. ((consp initial-input)
  399. (car initial-input))
  400. ((stringp initial-input)
  401. initial-input)
  402. ((null initial-input)
  403. "")
  404. (t
  405. (signal 'wrong-type-argument (list 'stringp initial-input)))))
  406. ;; If collection is a function, save it for later, unless
  407. ;; instructed not to
  408. (ido-cr+-dynamic-collection
  409. (when (and (not ido-cr+-assume-static-collection)
  410. (functionp collection))
  411. collection))
  412. ;; If the whitelist is empty, everything is whitelisted
  413. (whitelisted (not ido-cr+-function-whitelist))
  414. ;; If non-nil, we need alternate nil DEF handling
  415. (alt-nil-def nil))
  416. (condition-case sig
  417. (progn
  418. ;; Check a bunch of fallback conditions
  419. (when inherit-input-method
  420. (signal 'ido-cr+-fallback
  421. '("ido cannot handle non-nil INHERIT-INPUT-METHOD")))
  422. (when (bound-and-true-p completion-extra-properties)
  423. (signal 'ido-cr+-fallback
  424. '("ido cannot handle non-nil `completion-extra-properties'")))
  425. ;; Check for black/white-listed collection function
  426. (when (functionp collection)
  427. ;; Blacklist
  428. (when (ido-cr+-function-is-blacklisted collection)
  429. (if (symbolp collection)
  430. (signal 'ido-cr+-fallback
  431. (list (format "collection function `%S' is blacklisted" collection)))
  432. (signal 'ido-cr+-fallback
  433. (list "collection function is blacklisted"))))
  434. ;; Whitelist
  435. (when (and (not whitelisted)
  436. (ido-cr+-function-is-whitelisted collection))
  437. (ido-cr+--debug-message
  438. (if (symbolp collection)
  439. (format "Collection function `%S' is whitelisted" collection)
  440. "Collection function is whitelisted"))
  441. (setq whitelisted t))
  442. ;; nil DEF list
  443. (when (and
  444. require-match (null def)
  445. (ido-cr+-function-is-in-list
  446. collection
  447. ido-cr+-nil-def-alternate-behavior-list))
  448. (ido-cr+--debug-message
  449. (if (symbolp collection)
  450. (format "Using alternate nil DEF handling for collection function `%S'" collection)
  451. "Using alternate nil DEF handling for collection function"))
  452. (setq alt-nil-def t)))
  453. ;; Expand all currently-known completions.
  454. (setq collection
  455. (if ido-cr+-assume-static-collection
  456. (all-completions "" collection predicate)
  457. (ido-cr+-all-dynamic-completions
  458. initial-input-string collection predicate)))
  459. ;; No point in using ido unless there's a collection
  460. (when (and (= (length collection) 0)
  461. (not ido-cr+-dynamic-collection))
  462. (signal 'ido-cr+-fallback '("ido is not needed for an empty collection")))
  463. ;; Check for excessively large collection
  464. (when (and ido-cr+-max-items
  465. (> (length collection) ido-cr+-max-items))
  466. (signal 'ido-cr+-fallback
  467. (list
  468. (format
  469. "there are more than %i items in COLLECTION (see `ido-cr+-max-items')"
  470. ido-cr+-max-items))))
  471. ;; If called from `completing-read', check for
  472. ;; black/white-listed commands/callers
  473. (when (ido-cr+--called-from-completing-read)
  474. ;; Check calling command and `ido-cr+-current-command'
  475. (cl-loop
  476. for cmd in (list this-command ido-cr+-current-command)
  477. if (ido-cr+-function-is-blacklisted cmd)
  478. do (signal 'ido-cr+-fallback
  479. (list "calling command `%S' is blacklisted" cmd))
  480. if (and (not whitelisted)
  481. (ido-cr+-function-is-whitelisted cmd))
  482. do (progn
  483. (ido-cr+--debug-message "Command `%S' is whitelisted" cmd)
  484. (setq whitelisted t))
  485. if (and
  486. require-match (null def) (not alt-nil-def)
  487. (ido-cr+-function-is-in-list
  488. cmd ido-cr+-nil-def-alternate-behavior-list))
  489. do (progn
  490. (ido-cr+--debug-message
  491. "Using alternate nil DEF handling for command `%S'" cmd)
  492. (setq alt-nil-def t)))
  493. ;; Check every function in the call stack starting after
  494. ;; `completing-read' until to the first
  495. ;; `funcall-interactively' (for a call from the function
  496. ;; body) or `call-interactively' (for a call from the
  497. ;; interactive form, in which the function hasn't actually
  498. ;; been called yet, so `funcall-interactively' won't be on
  499. ;; the stack.)
  500. (cl-loop for i upfrom 1
  501. for caller = (cadr (backtrace-frame i 'completing-read))
  502. while caller
  503. while (not (memq (indirect-function caller)
  504. '(internal--funcall-interactively
  505. (indirect-function 'call-interactively))))
  506. if (ido-cr+-function-is-blacklisted caller)
  507. do (signal 'ido-cr+-fallback
  508. (list (if (symbolp caller)
  509. (format "calling function `%S' is blacklisted" caller)
  510. "a calling function is blacklisted")))
  511. if (and (not whitelisted)
  512. (ido-cr+-function-is-whitelisted caller))
  513. do (progn
  514. (ido-cr+--debug-message
  515. (if (symbolp caller)
  516. (format "Calling function `%S' is whitelisted" caller)
  517. "A calling function is whitelisted"))
  518. (setq whitelisted t))
  519. if (and require-match (null def) (not alt-nil-def)
  520. (ido-cr+-function-is-in-list
  521. caller ido-cr+-nil-def-alternate-behavior-list))
  522. do (progn
  523. (ido-cr+--debug-message
  524. (if (symbolp caller)
  525. (format "Using alternate nil DEF handling for calling function `%S'" caller)
  526. "Using alternate nil DEF handling for a calling function"))
  527. (setq alt-nil-def t))))
  528. (unless whitelisted
  529. (signal 'ido-cr+-fallback
  530. (list "no functions or commands matched the whitelist for this call")))
  531. (when (and require-match (null def))
  532. ;; Replace nil with "" for DEF if match is required, unless
  533. ;; alternate nil DEF handling is enabled
  534. (if alt-nil-def
  535. (ido-cr+--debug-message
  536. "Leaving the default at nil because alternate nil DEF handling is enabled.")
  537. (ido-cr+--debug-message
  538. "Adding \"\" as the default completion since no default was provided.")
  539. (setq def (list ""))))
  540. ;; In ido, the semantics of "default" are simply "put it at
  541. ;; the front of the list". Furthermore, ido can't handle a
  542. ;; list of defaults, nor can it handle both DEF and
  543. ;; INITIAL-INPUT being non-nil. So, just pre-process the
  544. ;; collection to put the default(s) at the front and then
  545. ;; set DEF to nil in the call to ido to avoid these issues.
  546. (unless (listp def)
  547. ;; Ensure DEF is a list
  548. (setq def (list def)))
  549. (when def
  550. ;; Ensure DEF are strings
  551. (setq def (mapcar (apply-partially #'format "%s") def))
  552. ;; Prepend DEF to COLLECTION and remove duplicates
  553. (setq collection (delete-dups (append def collection)))
  554. def nil)
  555. ;; Check for a specific bug
  556. (when (and ido-enable-dot-prefix
  557. (version< emacs-version "26.1")
  558. (member "" collection))
  559. (signal 'ido-cr+-fallback
  560. '("ido cannot handle the empty string as an option when `ido-enable-dot-prefix' is non-nil; see https://debbugs.gnu.org/cgi/bugreport.cgi?bug=26997")))
  561. ;; Fix ido handling of cons-style INITIAL-INPUT. TODO add a
  562. ;; version check after this bug is fixed:
  563. ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27807
  564. (when (consp initial-input)
  565. ;; `completing-read' uses 0-based index while
  566. ;; `read-from-minibuffer' uses 1-based index.
  567. (cl-incf (cdr initial-input)))
  568. ;; Finally ready to do actual ido completion
  569. (prog1
  570. (let ((ido-cr+-minibuffer-depth (1+ (minibuffer-depth)))
  571. ;; Initialize dynamic update vars
  572. (ido-cr+-previous-dynamic-update-texts
  573. (list initial-input-string))
  574. (ido-cr+-dynamic-update-timer nil)
  575. (ido-cr+-exhibit-pending t)
  576. ;; Reset these for the next call to ido-cr+
  577. (ido-cr+-no-default-action 'prepend-empty-string)
  578. (ido-cr+-assume-static-collection nil))
  579. (unwind-protect
  580. (ido-completing-read
  581. prompt collection
  582. predicate require-match initial-input hist def
  583. inherit-input-method)
  584. (when ido-cr+-dynamic-update-timer
  585. (cancel-timer ido-cr+-dynamic-update-timer)
  586. (setq ido-cr+-dynamic-update-timer nil))))
  587. ;; This detects when the user triggered fallback mode
  588. ;; manually.
  589. (when (eq ido-exit 'fallback)
  590. (signal 'ido-cr+-fallback '("user manually triggered fallback")))))
  591. ;; Handler for ido-cr+-fallback signal
  592. (ido-cr+-fallback
  593. (let (;; Reset `minibuffer-setup-hook' to original value
  594. (minibuffer-setup-hook orig-minibuffer-setup-hook)
  595. ;; Reset these for the next call to ido-cr+
  596. (ido-cr+-no-default-action 'prepend-empty-string)
  597. (ido-cr+-assume-static-collection nil))
  598. (ido-cr+--explain-fallback sig)
  599. (apply ido-cr+-fallback-function ido-cr+-orig-completing-read-args))))))
  600. ;;;###autoload
  601. (defun ido-completing-read@ido-cr+-replace (orig-fun &rest args)
  602. "This advice allows ido-cr+ to completely replace `ido-completing-read'.
  603. See the varaible `ido-cr+-replace-completely' for more information."
  604. ;; If this advice is autoloaded, then we need to force loading of
  605. ;; the rest of the file so all the variables will be defined.
  606. (when (not (featurep 'ido-completing-read+))
  607. (require 'ido-completing-read+))
  608. (if (or (ido-cr+-active)
  609. (not ido-cr+-replace-completely))
  610. ;; ido-cr+ has either already activated or isn't going to
  611. ;; activate, so just run the function as normal
  612. (apply orig-fun args)
  613. ;; Otherwise, we need to activate ido-cr+.
  614. (apply #'ido-completing-read+ args)))
  615. ;;;###autoload
  616. (advice-add 'ido-completing-read :around
  617. #'ido-completing-read@ido-cr+-replace)
  618. ;;;###autoload
  619. (defun call-interactively@ido-cr+-record-current-command
  620. (orig-fun command &rest args)
  621. "Let-bind the command being interactively called.
  622. See `ido-cr+-current-command' for more information."
  623. (let ((ido-cr+-current-command command))
  624. (apply orig-fun command args)))
  625. ;;;###autoload
  626. (advice-add 'call-interactively :around
  627. #'call-interactively@ido-cr+-record-current-command)
  628. ;; Fallback on magic C-f and C-b
  629. (defun ido-magic-forward-char@ido-cr+-fallback (&rest args)
  630. "Allow falling back in ido-completing-read+."
  631. (when (ido-cr+-active)
  632. ;; `ido-context-switch-command' is already let-bound at this
  633. ;; point.
  634. (setq ido-context-switch-command #'ido-fallback-command)))
  635. (advice-add 'ido-magic-forward-char :before
  636. #'ido-magic-forward-char@ido-cr+-fallback)
  637. (defun ido-magic-backward-char@ido-cr+-fallback (&rest args)
  638. "Allow falling back in ido-completing-read+."
  639. (when (ido-cr+-active)
  640. ;; `ido-context-switch-command' is already let-bound at this
  641. ;; point.
  642. (setq ido-context-switch-command #'ido-fallback-command)))
  643. (advice-add 'ido-magic-backward-char :before
  644. #'ido-magic-backward-char@ido-cr+-fallback)
  645. (defun ido-select-text@ido-cr+-fix-require-match (orig-fun &rest args)
  646. "Fix ido behavior when `require-match' is non-nil.
  647. Standard ido will allow C-j to exit with an incomplete completion
  648. even when `require-match' is non-nil. Ordinary completion does
  649. not allow this. In ordinary completion, RET on an incomplete
  650. match is equivalent to TAB, and C-j selects the first match.
  651. Since RET in ido already selects the first match, this advice
  652. sets up C-j to be equivalent to TAB in the same situation.
  653. This advice only activates if the current ido completion was
  654. called through ido-cr+."
  655. (if (and
  656. ;; Only override C-j behavior if...
  657. ;; We're using ico-cr+, and...
  658. (ido-cr+-active)
  659. ;; Require-match is non-nil, and...
  660. ido-require-match
  661. ;; The current input doesn't exactly match a known option, and...
  662. (not (member ido-text ido-cur-list))
  663. ;; The current input doesn't exactly match an option according
  664. ;; to `try-completion' (or the collection is not dynamic).
  665. (or (not ido-cr+-dynamic-collection)
  666. (eq t (try-completion ido-text ido-cr+-dynamic-collection
  667. (nth 2 ido-cr+-orig-completing-read-args)))))
  668. (progn
  669. (ido-cr+--debug-message
  670. "Overriding C-j behavior for require-match: performing completion instead of exiting with current text. (This might still exit with a match if `ido-confirm-unique-completion' is nil)")
  671. (ido-complete))
  672. (apply orig-fun args)))
  673. (advice-add 'ido-select-text :around
  674. #'ido-select-text@ido-cr+-fix-require-match)
  675. (defun ido-tidy@ido-cr+-set-exhibit-pending (&rest args)
  676. (setq ido-cr+-exhibit-pending t))
  677. (advice-add 'ido-tidy :after 'ido-tidy@ido-cr+-set-exhibit-pending)
  678. (defun ido-exhibit@ido-cr+-clear-exhibit-pending (&rest args)
  679. (setq ido-cr+-exhibit-pending nil))
  680. (advice-add 'ido-exhibit :before 'ido-exhibit@ido-cr+-clear-exhibit-pending)
  681. (cl-defun ido-cr+-all-dynamic-completions
  682. (string collection &optional predicate
  683. &key prev-string (rmdups t))
  684. "Run `all-completions' on every prefix of STRING.
  685. Arguments COLLECTION and PREDICATE are as in `all-completions'.
  686. Note that \"all prefixes\" includes both STRING itself and the
  687. empty string.
  688. If keyword argument RMDUPS is non-nil, call `delete-dups' on the
  689. result before returning. This is the default. You can pass nil
  690. for this argument if the caller is already going to do its own
  691. duplicate removal.
  692. As an optimization, if keyword argument PREV-STRING is non-nil,
  693. then prefixes of STRING that are also prefixes of PREV-STRING
  694. will be skipped. This is used to avoid duplicating work if the
  695. caller already knows about the completions for PREV-STRING.
  696. PREV-STRING can also be a list of previous strings, in which case
  697. all prefixes of all previous strings will be skipped. In
  698. particular, note that if PREV-STRING equals STRING, this function
  699. will return nil.
  700. This function is only useful if COLLECTION is a function that
  701. might return additional completions for certain non-empty strings
  702. that it wouldn't return for the empty string. If COLLECTION is
  703. not a function, this is equivalent to
  704. `(all-completions \"\" COLELCTION PREDICATE)'."
  705. (cond
  706. ;; Dynamic collection.
  707. ((functionp collection)
  708. (let ((prev-strings (if (listp prev-string)
  709. prev-string
  710. (list prev-string)))
  711. (common-prefix-length -1))
  712. ;; Get the length of the longest common prefix, or -1 if no
  713. ;; previous strings.
  714. (cl-loop for ps in prev-strings
  715. for common-prefix = (s-shared-start ps string)
  716. maximize (length common-prefix) into prefix-length
  717. finally do (setq common-prefix-length
  718. (or prefix-length -1)))
  719. ;; Get completions for all prefixes starting after the longest
  720. ;; previous prefix, or starting from "" if no previous prefix.
  721. (cl-loop
  722. with start-index = (1+ common-prefix-length)
  723. ;; This might execute zero times, if common-prefix = string
  724. for i from start-index upto (length string)
  725. append (all-completions
  726. (s-left i string)
  727. collection
  728. predicate)
  729. into completion-list
  730. finally return (when completion-list
  731. (funcall
  732. (if rmdups #'delete-dups #'identity)
  733. completion-list)))))
  734. ;; If COLLECTION is not a function and PREV-STRING is non-nil, then
  735. ;; the caller already has all the possible completions, so return
  736. ;; nil.
  737. (prev-string
  738. nil)
  739. ;; Otherwise, just call `all-completions' on the empty string to
  740. ;; get every possible completions for a static COLLECTION.
  741. (t
  742. (unless prev-string
  743. (all-completions "" collection predicate)))))
  744. (defun ido-cr+-update-dynamic-collection ()
  745. "Update the set of completions for a dynamic collection.
  746. This has no effect unless `ido-cr+-dynamic-collection' is non-nil."
  747. (when (and (ido-cr+-active)
  748. ido-cr+-dynamic-collection)
  749. (let* ((ido-text
  750. (buffer-substring-no-properties (minibuffer-prompt-end)
  751. ido-eoinput))
  752. (predicate (nth 2 ido-cr+-orig-completing-read-args))
  753. (first-match (car ido-matches))
  754. (remembered-new-string nil)
  755. (strings-to-check
  756. ;; If `ido-text' is a prefix of `first-match', then we
  757. ;; only need to check the latter, because that will
  758. ;; implicitly check the former as well.
  759. (cond
  760. ((null first-match)
  761. (list ido-text))
  762. ((and first-match
  763. (s-prefix? ido-text first-match))
  764. (list first-match))
  765. (t
  766. (list ido-text first-match))))
  767. (new-completions
  768. (cl-loop
  769. with checked-strings = '()
  770. for string in strings-to-check
  771. nconc
  772. (ido-cr+-all-dynamic-completions
  773. string ido-cr+-dynamic-collection predicate
  774. :rmdups nil
  775. :prev-string (append checked-strings
  776. ido-cr+-previous-dynamic-update-texts))
  777. into result
  778. collect string into checked-strings
  779. finally return result)))
  780. (when new-completions
  781. ;; Merge new completions into `ido-cur-list'
  782. (setq
  783. ido-cur-list
  784. (delete-dups (nconc ido-cur-list new-completions)))
  785. ;; Ensure that the currently-selected match is still at the head
  786. ;; of the list
  787. (let ((current-match (car ido-matches)))
  788. (when (and current-match (member current-match ido-cur-list))
  789. (setq ido-cur-list (ido-chop ido-cur-list current-match))))
  790. (ido-cr+--debug-message
  791. "Updated completion candidates for dynamic collection because `ido-text' changed to %S. `ido-cur-list' now has %s elements"
  792. ido-text (length ido-cur-list))
  793. ;; Recompute matches with new completions
  794. (setq ido-rescan t)
  795. (ido-set-matches)
  796. ;; Rebuild the completion display unless ido is already planning
  797. ;; to do it anyway
  798. (unless ido-cr+-exhibit-pending
  799. (ido-tidy)
  800. (ido-exhibit)))
  801. ;; Add `ido-text' and/or `first-match' to the list of remembered
  802. ;; previous update texts. This is used to avoid re-computing
  803. ;; completions on previously-seen string prefixes (since those
  804. ;; completions have already been added to `ido-cur-list')
  805. (cl-loop
  806. for new-text in strings-to-check
  807. do
  808. (cond
  809. ;; Common case optimization: if eitehr new element or first
  810. ;; element of list is a prefix of the other, just keep the
  811. ;; longer one.
  812. ((s-prefix? new-text (car ido-cr+-previous-dynamic-update-texts))
  813. nil)
  814. ((s-prefix? (car ido-cr+-previous-dynamic-update-texts) new-text)
  815. (setf (car ido-cr+-previous-dynamic-update-texts) new-text))
  816. ;; General case: just prepend it to the list
  817. (t
  818. (setq remembered-new-string t)
  819. (push new-text ido-cr+-previous-dynamic-update-texts))))
  820. ;; Remove duplicates and trim the list down to the last 5
  821. ;; remembered texts
  822. (when remembered-new-string
  823. (setq
  824. ido-cr+-previous-dynamic-update-texts
  825. ;; Elisp doesn't seem to have a "take first N elements"
  826. ;; function that returns the entire list if it's shorter than
  827. ;; N instead of signaling an error
  828. (cl-loop
  829. with result = '()
  830. with n-taken = 0
  831. for item in ido-cr+-previous-dynamic-update-texts
  832. if (not (member item result))
  833. collect item into result and
  834. sum 1 into n-taken
  835. if (>= n-taken 5)
  836. return result
  837. finally return result))))))
  838. ;; Always cancel an active timer when this function is called.
  839. (when ido-cr+-dynamic-update-timer
  840. (cancel-timer ido-cr+-dynamic-update-timer)
  841. (setq ido-cr+-dynamic-update-timer nil))
  842. (defun ido-cr+-schedule-dynamic-collection-update ()
  843. "Schedule a dynamic collection update for now or in the future."
  844. (when (and (ido-cr+-active)
  845. ido-cr+-dynamic-collection)
  846. ;; Cancel the previous timer
  847. (when ido-cr+-dynamic-update-timer
  848. (cancel-timer ido-cr+-dynamic-update-timer)
  849. (setq ido-cr+-dynamic-update-timer nil))
  850. (if (<= (length ido-matches) 1)
  851. ;; If we've narrowed it down to zero or one matches, update
  852. ;; immediately.
  853. (ido-cr+-update-dynamic-collection)
  854. ;; If there are still several choices, defer update until idle
  855. (setq ido-cr+-dynamic-update-timer
  856. (run-with-idle-timer (max 0.01 ido-cr+-dynamic-update-idle-time) nil
  857. #'ido-cr+-update-dynamic-collection)))))
  858. (defun ido-cr+-minibuffer-setup ()
  859. "set up minibuffer `post-command-hook' for ido-cr+ "
  860. (when (ido-cr+-active)
  861. (add-hook 'post-command-hook
  862. 'ido-cr+-schedule-dynamic-collection-update)))
  863. (add-hook 'ido-minibuffer-setup-hook
  864. 'ido-cr+-minibuffer-setup)
  865. ;; (defadvice ido-complete (around dynamic activate)
  866. ;; (let ((ido-confirm-unique-completion
  867. ;; (if ido-cr+-dynamic-collection
  868. ;; t
  869. ;; ido-confirm-unique-completion)))
  870. ;; ad-do-it))
  871. ;; Also need to update dynamic collections on TAB, and do so *before*
  872. ;; deciding to exit based on `ido-confirm-unique-completion'
  873. (defun ido-complete@ido-cr+-update-dynamic-collection (oldfun &rest args)
  874. "Maybe update the set of completions when pressing TAB."
  875. (when ido-cr+-dynamic-collection
  876. ;; First run with `ido-confirm-unique-completion' non-nil so it
  877. ;; can't exit
  878. (let ((ido-confirm-unique-completion t))
  879. (apply oldfun args))
  880. ;; Update `ido-eoinput'
  881. (setq ido-eoinput (point-max))
  882. ;; Now do update
  883. (ido-cr+-update-dynamic-collection))
  884. ;; After maybe updating the dynamic collection, if there's still
  885. ;; only one completion, now it's allowed to exit
  886. (apply oldfun args))
  887. (advice-add 'ido-complete :around 'ido-complete@ido-cr+-update-dynamic-collection)
  888. ;; Interoperation with minibuffer-electric-default-mode: only show the
  889. ;; default when the input is empty and the empty string is the
  890. ;; selected choice
  891. (defun minibuf-eldef-update-minibuffer@ido-cr+-compat (orig-fun &rest args)
  892. "This advice allows minibuffer-electric-default-mode to work with ido-cr+."
  893. (if (ido-cr+-active)
  894. (unless (eq minibuf-eldef-showing-default-in-prompt
  895. (and (string= (car ido-cur-list) "")
  896. (string= ido-text "")))
  897. ;; Swap state.
  898. (setq minibuf-eldef-showing-default-in-prompt
  899. (not minibuf-eldef-showing-default-in-prompt))
  900. (overlay-put minibuf-eldef-overlay 'invisible
  901. (not minibuf-eldef-showing-default-in-prompt)))
  902. (apply orig-fun args)))
  903. (advice-add 'minibuf-eldef-update-minibuffer :around
  904. #'minibuf-eldef-update-minibuffer@ido-cr+-compat)
  905. ;;;###autoload
  906. (define-minor-mode ido-ubiquitous-mode
  907. "Use ido completion instead of standard completion almost everywhere.
  908. If this mode causes problems for a function, you can customize
  909. when ido completion is or is not used by customizing
  910. `ido-cr+-function-blacklist'."
  911. nil
  912. :global t
  913. :group 'ido-completing-read-plus
  914. ;; Actually enable/disable the mode by setting
  915. ;; `completing-read-function'.
  916. (setq completing-read-function
  917. (if ido-ubiquitous-mode
  918. #'ido-completing-read+
  919. ido-cr+-fallback-function)))
  920. (defcustom ido-cr+-auto-update-blacklist 'notify
  921. "Whether to add new overrides when updating ido-cr+.
  922. This variable has 3 possible values, with the following meanings:
  923. `t': Auto-update the blacklist
  924. `notify': Notify you about updates but do not apply them
  925. `nil': Ignore all blacklist updates
  926. Ido-cr+ comes with a default blacklist for commands that are
  927. known to be incompatible with ido completion. New versions of
  928. ido-cr+ may come with updates to this blacklist as more
  929. incompatible commands are discovered. However, customizing your
  930. own overrides would normally prevent you from receiving these
  931. updates, since Emacs will not overwrite your customizations.
  932. To resolve this problem, you can set this variable to `t', and
  933. then ido-cr+ can automatically add any new built-in overrides
  934. whenever it is updated. (Actually, the update will happen the
  935. next time Emacs is restarted after the update.) This allows you
  936. to add your own overrides but still receive updates to the
  937. default set.
  938. If you want ido-cr+ to just notify you about new default
  939. overrides instead of adding them itself, set this variable to
  940. `notify'. If you don't want this auto-update behavior at all, set
  941. it to `nil'.
  942. (Note that having this option enabled effectively prevents you
  943. from removing any of the built-in default blacklist entries,
  944. since they will simply be re-added the next time Emacs starts.)"
  945. :type '(choice :tag "When new overrides are available:"
  946. (const :menu-tag "Auto-add"
  947. :tag "Add them automatically"
  948. t)
  949. (const :menu-tag "Notify"
  950. :tag "Notify me about them"
  951. notify)
  952. (const :menu-tag "Ignore"
  953. :tag "Ignore them"
  954. nil))
  955. :group 'ido-completing-read-plus)
  956. (defun ido-cr+-update-blacklist (&optional save quiet)
  957. "Re-add any missing default blacklist entries.
  958. This is useful after an update of ido-ubiquitous that adds new
  959. default overrides. See `ido-cr+-auto-update-blacklist' for more
  960. information.
  961. If SAVE is non-nil, also save the new blacklist to the user's
  962. Custom file (but only if it was already customized beforehand).
  963. When called interactively, a prefix argument triggers a save.
  964. When called from Lisp code, this function returns non-nil if the
  965. blacklist was modified."
  966. (interactive "P")
  967. (let* ((var-state (custom-variable-state 'ido-cr+-function-blacklist
  968. ido-cr+-function-blacklist))
  969. (curval ido-cr+-function-blacklist)
  970. (defval (eval (car (get 'ido-cr+-function-blacklist 'standard-value))))
  971. (newval (delete-dups (append defval curval)))
  972. (new-entries (cl-set-difference defval curval :test #'equal))
  973. (modified nil)
  974. (saved nil)
  975. (message-lines ()))
  976. (cl-case var-state
  977. (standard
  978. ;; Var is not customized, just set the new default
  979. (ido-cr+--debug-message "Blacklist was not customized, so it has been updated to the new default value.")
  980. (setq ido-cr+-function-blacklist defval
  981. modified new-entries))
  982. ((saved set changed)
  983. ;; Var has been customized and saved by the user, so set the
  984. ;; new value and maybe save it
  985. (ido-cr+--debug-message "Updating user-customized blacklist with new default entries.")
  986. (setq ido-cr+-function-blacklist newval
  987. modified t)
  988. (when (and save (eq var-state 'saved))
  989. (ido-cr+--debug-message "Saving new blacklist value to Custom file.")
  990. (customize-save-variable 'ido-cr+-function-blacklist ido-cr+-function-blacklist)
  991. (setq saved t)))
  992. (otherwise
  993. (ido-cr+--debug-message "Customization status of blacklist is unknown. Not modifying it.")))
  994. (if (and modified (not quiet))
  995. (progn
  996. (push (format "Added the following entries to `ido-cr+-function-blacklist': %S" new-entries)
  997. message-lines)
  998. (if saved
  999. (push "Saved the new value of `ido-cr+-function-blacklist' to your Custom file."
  1000. message-lines)
  1001. (push "However, the new value of `ido-cr+-function-blacklist' has not yet been saved for future sessions. To save it. re-run this command with a prefix argument: `C-u M-x ido-cr+-update-blacklist'; or else manually inspect and save the value using `M-x customize-variable ido-cr+-function-blacklist'."
  1002. message-lines)))
  1003. (push "No updates were required to `ido-cr+-function-blacklist'." message-lines))
  1004. (unless quiet
  1005. (message (mapconcat #'identity (nreverse message-lines) "\n")))
  1006. modified))
  1007. (defun ido-cr+-maybe-update-blacklist ()
  1008. "Maybe call `ico-cr+-update-blacklist.
  1009. See `ido-cr+-auto-update-blacklist' for more information."
  1010. (if ido-cr+-auto-update-blacklist
  1011. (let* ((curval ido-cr+-function-blacklist)
  1012. (defval (eval (car (get 'ido-cr+-function-blacklist 'standard-value))))
  1013. (new-entries (cl-set-difference curval defval :test #'equal)))
  1014. (if new-entries
  1015. (if (eq ido-cr+-auto-update-blacklist 'notify)
  1016. (display-warning 'ido-completing-read+ "There are %s new blacklist entries available. Use `M-x ido-cr+-update-blacklist' to install them. (See `ido-cr+-auto-update-blacklist' for more information.)")
  1017. (ido-cr+--debug-message "Initiating blacklist update.")
  1018. (ido-cr+-update-blacklist t))
  1019. (ido-cr+--debug-message "No blacklist updates available.")))
  1020. (ido-cr+--debug-message "Skipping blacklist update by user request.")))
  1021. (ido-cr+-maybe-update-blacklist)
  1022. (provide 'ido-completing-read+)
  1023. ;;; ido-completing-read+.el ends here