5

I frequently use dired-mode and I recently started using ido:

(ido-mode 1); enable ido-mode
(setq ido-enable-flex-matching t); flexibly match names via fuzzy matching
(setq ido-everywhere t); use ido-mode everywhere, in buffers and for finding files
(setq ido-use-filename-at-point 'guess); for find-file-at-point
(setq ido-use-url-at-point t); look for URLs at point
(setq ffap-require-prefix t); get find-file-at-point with C-u C-x C-f 

When I copy a file (with C) in a dired buffer, I still have to use the "standard way" of giving the new location where the file is copied to. That means, I have to use standard TAB-completion but there is no ido-completion. The same applies for R for moving files etc. I am thus wondering if it is possible to get ido also acting on C or R in dired buffers?

Marius Hofert
  • 6,546
  • 10
  • 48
  • 102

2 Answers2

6

Looks like I had the same problem you are experiencing. Some investigating shows that we need to override the variable read-file-name-function which, by default, calls read-file-name-function-default. But, looking at the source code for ido-everywhere (which is a minor mode), it does this for us.

Solution:

Rather than doing (setq ido-everywhere t), replace that with:

(ido-everywhere t)

This fixes it for me, causing ido-read-file-name to be called in dired buffers when you use C or similar.

Another Option:

You might also consider this beefed up version of ido-everywhere:

https://github.com/DarwinAwardWinner/ido-ubiquitous

;;; Commentary:

;; You may have seen the `ido-everywhere' variable in ido.el and got
;; excited that you could use ido completion for everything. Then you
;; were probably disappointed when you realized that it only applied
;; to *file names* and nothing else. Well, ido-ubiquitous is here to
;; fulfill the original promise and let you use ido completion for
;; (almost) any command that uses `completing-read' to offer you a
;; choice of several alternatives.
assem
  • 2,077
  • 1
  • 19
  • 24
  • Interestingly, `C` for copying works, but `R` for renaming and move does not work this way :-( – Marius Hofert Jul 16 '12 at 15:49
  • Using `debug-on-entry` I found a difference in the behavior of `R` and `C`. `R` uses `dired-mark-read-file-name`, whereas, 'C' does not. – Nicolas Dudebout Jul 16 '12 at 17:53
  • And from the documentation `C` is a closure whereas `R` is a function. – Nicolas Dudebout Jul 16 '12 at 18:01
  • It would be great if there was a solution to that so that it works in `R` in dired-mode as well. – Marius Hofert Jul 16 '12 at 21:52
  • The problem is the `'ido` property in the symbol for `'dired-do-rename` has been specifically set to `'ignore`. As a result, inside of `ido-read-file-name` the `(and ...)` clause that falls into completing-read fails, and it jumps into the fallback, ultimately to `read-file-name-default` – assem Jul 17 '12 at 02:26
  • 1
    Surely they had a very good reason for this, but I will say that doing `(put 'dired-do-rename 'ido 'find-file)` gives an ido-completing read and had no adverse consequences for me to rename a basic file and directory. I don't recommend this though - instead I would submit a bug report/feature request. – assem Jul 17 '12 at 02:29
  • I can already see what is not working properly anymore. If you use `(put...)` you get ido mode on hiting `R` in a dired buffer. However, if you want to move the file (keep the same name) you could just hit return after navigating to the correct folder where you want to move the file to. But with `(put...)`, you can't hit return anymore, the file will not be moved. Instead, you have to give it a name (could be the same, but it's definitely tedious to type) – Marius Hofert Jul 17 '12 at 21:13
  • Unfortunately, `C` also does not work. Once you copy a file to a different folder foo, ido-mode always suggests a subfolder of foo (if there exists one) where to copy the file to, but you can't select foo to copy the file to. – Marius Hofert Jul 18 '12 at 08:04
  • @MariusHofert, I find that workaround works great. Ido offers the C-f shortcut to manually edit the input. I also use the setting " (setq ido-show-dot-for-dired t) ;; put . as the first item", perhaps this is why it seems to work for me. – sp3ctum May 08 '13 at 11:49
  • Hey, I think I can answer a few of the questions in this thread. First, ido-ubiquitous (my package) is only designed for basic uses of `completing-read`, i.e. not reading files or directories, so it won't help with anything here. Second, I ido intentionally disables itself in `dired-do-rename` not because it cannot work there, but because ido is optimized for completing an existing file name, and the point of a rename is (usually) to create a new file, not overwrite an existing one, so ido isn't really optimized for the use case of renaming. So feel free to use ido fore dired renaming. – Ryan C. Thompson Mar 24 '14 at 16:37
  • Also, for copying into a directory, remember that in ido, C-j will select whatever is currently entered regardless of the completions being offered, so select the directory you want to copy into and then just ignore the completions of the files in that directory and press C-j. – Ryan C. Thompson Mar 24 '14 at 16:48
3

I found that (put 'dired-do-rename 'ido 'find-file) for the R key works fine, if you need to stop at a path you simply press C-j instead of completing a file name.

Silex
  • 1,707
  • 17
  • 24
  • Unfortunately, this does not change anything for me. – Marius Hofert Jan 08 '13 at 09:52
  • Can you explain what you're trying to do and how it doens't work? also, why the downvote? – Silex Jan 19 '13 at 12:35
  • That post was not very precise, indeed. I only later found (see below) out about the effects/changes of this "solution". The downvote was probably because of the side-effects. This is not a clean solution to the problem, it affects many other "good" behavior and therefore shouldn't be used with care. I should have rather just said it instead of using the downvote button. Sorry for this. – Marius Hofert Jan 19 '13 at 16:41
  • Works fine for me. See my comment on assem's solution. – sp3ctum May 08 '13 at 11:52
  • I use the [`ido-ubiquitous`](https://github.com/DarwinAwardWinner/ido-ubiquitous) package, but this solution is the only thing that works for me. FYI, if you want to enable this solution for all `dired-do-` functions, put this in your init file(s): `(eval-after-load 'dired '(progn (mapatoms (lambda (symbol) (if (s-starts-with? "dired-do-" (symbol-name symbol)) (put symbol 'ido 'find-file))))))`. Note that this solution requires [`s.el`](https://github.com/magnars/s.el/), but you really should install that library anyway. – GDP2 Nov 25 '16 at 06:02
  • Correction for my last comment: `s.el` is not needed there; use `string-prefix-p` instead. Also, doing this solution on all `dired-do-` functions is actually a bad idea as some of those functions are not meant to be with Ido. This solution is better as it only targets functions that make sense with Ido: `(eval-after-load dired '(progn (dolist (action '(dired-do-compress dired-do-compress-to dired-do-copy dired-do-hardlink dired-do-relsymlink dired-do-rename dired-do-symlink dired-do-touch epa-dired-do-decrypt epa-dired-do-encrypt do-sign epa-dired-do-verify)) (put action 'ido 'find-file))))` – GDP2 Apr 27 '17 at 15:50