7

I'm trying to mark a set of files (including subdirectories' files) in dired matching a regex, so I do:

C-U C-x d -alR RET e:/ RET

Followed by %m and enter my regex. No matches.

If, however, I enter the same regex on a "normal" dired (i.e. no -R switch) then the regex matches.

Am I doing something wrong? I've tried with emacs -Q and get the same result.

edit:

It seems the actual regex is significant; entering \.mp3$ works as expected, but if I try to anchor the regex using ^music marks everything under the e:/music folder.

6

I think this is a bug in Dired (and also in Dired+).

I've just fixed it in Dired+ (dired+.el). Please download the latest (or wait up to a day to pick it up in MELPA).

I checked this quickly, so it's possible that there was a good reason for the (longstanding) existing behavior, but for now at least, I think it was a bug.

Thanks for reporting it. After I've checked it out a bit more, I'll report it as an Emacs bug. Or you can do so now, if you like: M-x report-emacs-bug.


UPDATE

Actually, things are more interesting (i.e., more complicated). I'm busy at the moment, but will update this in a short while.

Suffice it to say that there are advantages to different ways to define the "file names" that are matched. If you grab the current (updated this morning) version of dired+.el then it will do as you expected: match file names with no subdirs as prefix.

But it can also be useful to match against the subdirs plus the file names. That way, for example, you can match the same file name in multiple subdirs -- or not, au choix.

I will likely change %m (in Dired+) so that a certain kind of prefix arg gives you different, alternative matching behaviors. (Right now, a prefix arg unmarks instead of marks. I might change it so that the numeric sign governs whether to unmark and what kind of matching to do.)

If you want to experiment yourself, just grab the definition of dired-mark-files-regexp, together with the definition of macro dired-mark-if, from dired+.el, and change the value of the first arg to dired-get-filename (LOCALP). There are several matching possibilities, governed by that argument value.


UPDATE 2

OK, I've updated Dired+ (dired+.el) now to provide more flexibility in this regard.

You can now mark/unmark matching file names that are considered in different ways:

  • Relative (no directory part, which is what you were incorrectly assuming you were matching).

    For this, you use a negative prefix arg (e.g. M--) to mark and a zero prefix arg (e.g. M-0) to unmark.

  • Relative to the default-directory of the Dired buffer. This means the file name is constructed the name relative to default-directory. For an entry in an inserted subdir listing, this means prefix the relative file name (no directory part) with the subdir name relative to default-directory.

    For this, you use a positive arg (e.g. M-+) to mark and a double plain prefix arg (C-u C-u) to unmark.

    This is what you were actually matching, which explains why you saw what you saw. With this behavior you would have needed to provide a regexp that matched the name relative to the default-directory of the buffer. Your use of ^ in the regexp was trying to match the beginning of this name, not the nondirectory name. This is same behavior as vanilla Emacs.

  • Absolute (full name, including all directory parts).

    For this, you use no prefix arg to mark and a plain prefix arg (C-u) to unmark. This is thus the default behavior now for Dired+. I think it is probably a better default behavior than what is used by vanilla Emacs (names relative to default-directory).

1
  • That's brilliant - thanks very much for the work you have put in, it's much appreciated
    – Dave F
    May 25 '16 at 9:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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