6

I have this setup:

(setq ido-everywhere t)
(ido-mode 1)

Well, of course there is more, but I believe that this is relevant portion.

Some time ago I wanted to have IDO for dired-do-copy and dired-do-rename and someone on IRC #emacs channel told me to add this to my config:

(put 'dired-do-copy   'ido nil) ; use ido there
(put 'dired-do-rename 'ido nil) ; ^

…it worked!

Now I would like to do the opposite: I need to completely disable IDO for dired-create-directory, because it doesn't make any sense there (but ido-everywhere activates it there).

Of course I have some other stuff like ido-ubiquitous, and ido-hacks, but I don't know if I should try to mess with these packages to do what I want to do.

Q: how to disable IDO for dired-create-directory?


Attention of future readers: @Drew's answer doesn't work, although it has been upvoted by people who didn't care to try it (including me). There are better (and more general) ways to do it, see below.

2
  • An aside: you can enter the directory name and hit C-j (bound to ido-select-text) instead of enter to effectively turn ido "off" for that particular selection.
    – Dan
    Commented Jul 6, 2015 at 18:43
  • @Dan, yes I know that, but how do you handle directory names that contain spaces? I cannot tolerate the fact that I need to press C-f when I could avoid it altogether. This is such a minor problem, but I got really curious about its solution. Commented Jul 6, 2015 at 18:49

4 Answers 4

3
+25
(defadvice dired-create-directory (around inhibit-ido activate)
  "Turn off Ido mode for the duration, then turn it on."
  (unwind-protect
       (progn (ido-everywhere -1) ad-do-it)
    (ido-everywhere 1)))

If you aren't sure you always want ido-everywhere mode turned on at the end, then you can do this instead - it keeps it on or off, as it was before using dired-create-directory:

(defadvice dired-create-directory (around inhibit-ido activate)
  "Inhibit Ido for the duration."
  (let ((orig-ido-everywhere  ido-everywhere))
    (unwind-protect
        (progn (ido-everywhere -1) ad-do-it)
      (when orig-ido-everywhere (ido-everywhere 1)))))
4
  • While this works, it's not something I couldn't write myself. I still believe that some of ido extensions provide some way to specify where to use ido. If (put 'dired-do-copy 'ido nil) works, I think there should be way to do the opposite without wrapping the function in advice. Anyway, thanks for your answer. Commented Jul 7, 2015 at 11:36
  • 1
    I don't think there's going to be a nicer way than using advice, because dired-create-directory just uses read-file-name-function which is what the ido-everywhere mode sets. You could make the advice a bit simpler by just let-binding read-file-name-function I guess.
    – npostavs
    Commented Jul 7, 2015 at 13:10
  • 1
    Does it have to be something you couldn't write yourself? ;-) I think it answers your question, but if you want to modify your question to include more info about what you do not want, please do. Something specific will of course be more helpful than just "I want something that I couldn't write myself." ;-)
    – Drew
    Commented Jul 7, 2015 at 20:35
  • But wait, it doesn't even work. If you're writing around advice for interactive function, it should be interactive too. (I didn't try it before) As written, it doesn't replace interactive spec of old function. Commented Jul 8, 2015 at 9:24
2

OK, if we have to resort to advising, here is how I would do it:

(defun mk-anti-ido-advice (func &rest args)
  "Temporarily disable IDO and call function FUNC with arguments ARGS."
  (interactive)
  (let ((read-file-name-function #'read-file-name-default))
    (if (called-interactively-p 'any)
        (call-interactively func)
      (apply func args))))

(defun mk-disable-ido (command)
  "Disable IDO when command COMMAND is called."
  (advice-add command :around #'mk-anti-ido-advice))

…and then we can just:

(mk-disable-ido 'dired-create-directory)

Thanks to @npostavs comment about let-binding of read-file-name-function.

3
  • 1
    since you're only interested in updating the interactive spec, you can use a function whose interactive spec is a function : (advice-add 'dired-create-directory :before (lambda (&rest _) "Do not use fancy completion when reading the file-name" (interactive (lambda (spec) (let ((read-file-name-function #'read-file-name-default)) (advice-eval-interactive-spec spec))))))
    – YoungFrog
    Commented Jul 8, 2015 at 9:54
  • @YoungFrog, well, that's an option, although I'm pretty happy with my current implementation. Commented Jul 8, 2015 at 13:18
  • I can attest to what Mark is pointing out, this solution actually works! Commented Jan 22, 2019 at 12:50
2

For files (and directories, not buffers) C-f makes it fall back to non-ido behavior.

C-f runs the command ido-magic-forward-char (found in ido-completion-map), which is an interactive compiled Lisp function in ‘ido.el’.

It is bound to C-f.

(ido-magic-forward-char ARG)

Move forward in user input or perform magic action.
If no user input is present, or at end of input, perform magic actions:
C-x C-b ... C-f switch to ‘ido-find-file’.
C-x C-f ... C-f fallback to non-Ido ‘find-file’.
C-x C-d ... C-f fallback to non-Ido brief ‘dired’.
C-x d ... C-f fallback to non-Ido ‘dired’.

You also might want to check out Introduction to Ido Mode.

1

I don't know if this was possible 5 years ago, anyway, you can do

(add-to-list 'ido-read-file-name-non-ido 'dired-create-directory)

By itself this only works for commands that don't use Ido completion unless ido-everywhere is enabled. I think commands that use Ido even when ido-everywhere is turned off do so because Ido remaps their key bindings to the ido- version of the original command. In that case you have to disable Ido completion for the original command by adding it to the ido-read-file-name-non-ido list and undo Ido's remapping. For example, disabling Ido for C-x w requires

(ido-mode) ; The unmapping must be done after Ido is initialized.
(add-to-list 'ido-read-file-name-non-ido 'write-file)
(define-key (cdr ido-minor-mode-map-entry) [remap write-file] nil)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.