Question

I'm a big fan of ido-mode, so much so that I would like to use it for things like describe-function or find-tag and so on, without having to write something like in "Can I get ido-mode-style completion for searching tags in Emacs?" for each one.

Both

(defalias completing-read ido-completing-read)

and

(setf 'completing-read 'ido-completing-read)

don't work, at least partly because ido-completing-read calls completing-read in its body, so any simple redefinition would result in infinite recursion.

In theory, it should be possible, since the first line of the docstring for ido-completing-read is "Ido replacement for the built-in completing-read." I've looked around a bit and can't seem to find anyone else who has attempted or succeeded at it.

I realize that Icicles probably provides something like this, and I may end up going with that anyway, but it is a bit more of a plunge than I care to take right now.

Thanks for any help.

Was it helpful?

Solution

I don't think ido-mode is ready for this quite yet. In particular, ido-completing-read currently only works with strings, while completing-read supports alists as well. This is very important once you want to have a different user-level description of the items you want to complete on.

Therefore I am not surprised that it doesn't work out of the box, yet. Short of modifying the code yourself your best bet is probably to just file a bug report/feature request.

OTHER TIPS

Edit: This is now an Emacs package available from MELPA. It has been expanded into a full-fledged minor mode. Development happens on GitHub.

Original post:

Here is my refinement of Jacobo's answer. Credit to him for the original magic. I've added an override variable, which you can use to prevent the use of ido-completing-read in specific functions. I have also added a check that uses the original completing-read if there are no completions (This happens occasionally, for example in org-remember-apply-template from org-mode, which breaks with Jacobo's original advice).

(defvar ido-enable-replace-completing-read t
  "If t, use ido-completing-read instead of completing-read if possible.

Set it to nil using let in around-advice for functions where the
original completing-read is required.  For example, if a function
foo absolutely must use the original completing-read, define some
advice like this:

(defadvice foo (around original-completing-read-only activate)
  (let (ido-enable-replace-completing-read) ad-do-it))")

;; Replace completing-read wherever possible, unless directed otherwise
(defadvice completing-read
  (around use-ido-when-possible activate)
  (if (or (not ido-enable-replace-completing-read) ; Manual override disable ido
          (boundp 'ido-cur-list)) ; Avoid infinite loop from ido calling this
      ad-do-it
    (let ((allcomp (all-completions "" collection predicate)))
      (if allcomp
          (setq ad-return-value
                (ido-completing-read prompt
                               allcomp
                               nil require-match initial-input hist def))
        ad-do-it))))

Oh, and for using ido in M-x, use smex

Hocus pocus, abracadabra, presto!

(defadvice completing-read
  (around foo activate)
  (if (boundp 'ido-cur-list)
      ad-do-it
    (setq ad-return-value
      (ido-completing-read
       prompt
       (all-completions "" collection predicate)
       nil require-match initial-input hist def))))

That works with everything but subr's, from which execute-extended-command is the one that matters (what is binded to M-x). But we can get what we want from M-x

(global-set-key
 "\M-x"
 (lambda ()
   (interactive)
   (call-interactively
    (intern
     (ido-completing-read
      "M-x "
      (all-completions "" obarray 'commandp))))))

Ido comes with a function that should do this, so just call it in your .emacs file:

(ido-everywhere t)

Using Emacs 24.3, ido-ubiquitous didn't work for me. So tried this and it is working fine so far:

(defun my-completing-read (prompt collection &optional predicate
                  require-match initial-input
                  hist def inherit-input-method)
  (if (listp collection)
      (ido-completing-read prompt collection predicate require-match
               initial-input hist def inherit-input-method)
    (completing-read-default prompt collection predicate require-match
                 initial-input hist def inherit-input-method)))

(setq completing-read-function 'my-completing-read)

Just a thought: have you tried editing ido-completing-read to call original-completing-read instead of completing-read, defining original-completing-read to be the current completing-read and then doing your defalias or setf thing?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top