Subject: bug#20739: 25.0.50; Dired switches have no effect when explicit list of files provided

From: Drew Adams <[email-masked]>
Date: Sat, 6 Jun 2015 14:57:05 -0700 (PDT)

> > The behavior is limited, I'm guessing, wrt any parts of `ls' that
> > depend on the whole list of files and subdirs.  It seems that
> > parts of the `ls' behavior that depend only on the info about a
> > given file are retained.
> 
> Yes.
> 
> > First, the doc should specify what I said above (if it is in fact
> > the case): `ls' behavior that depends on the entire list is not
> > available for this use case - the only switches that affect the
> > display are those that depend only on the info for an individual
> > file or dir; other switches are ignored.
> 
> I've found no switches that are ignored as result of this
> implementation, except those that control the order of the files in
> the listing, so that's what I stated in the doc string.  I think
> this makes the actual behavior clear enough.

It is not about the order.  `r' works, for example - it reverses
the order.

And anyway I don't think that sort-order switches are the only
ones that are ignored/irrelevant when DIRNAME is a cons.

It's not about switches that control the order.  It's about switches
that deal with directory (or directories) themselves, their entire
contents, as opposed to switches that deal only with an individual
entry to be listed or that (like `r') deal only with the set of
entries without needing any knowledge of the directory.

On MS Windows `ls-lisp.el' is used, and it says that it supports
all of these switches: A a B C c F G g h i n R r S s t U u v X

I think that besides `t' and the other sort switches (besides `r'),
at least `A', `a', `B', and `C' have no effect.

BTW, I see a bug for `B':

(dired-other-window '("foo" "toto.el" "foo.el") "-B")

The problem is at the beginning of `ls-lisp-insert-directory, AFAICT.
There we see this code on the first line:

(if (or wildcard-regexp full-directory-p)

But that is incorrect, because when switch `B' is used
we do this (ugly hack) in `ls-lisp--insert-directory':

(if (memq ?B switches) (setq wildcard-regexp "[^~]\\'"))

and this, similarly:

(setq wildcard-regexp (if (memq ?B switches) "[^~]\\'")
      file            (file-relative-name orig-file))

IOW, we use a pseudo wildcard-regexp.

And that doesn't work with this call:
(directory-files-and-attributes
  dir nil wildcard-regexp t (if (memq ?n switches) 'integer 'string))

Debugger entered--Lisp error: (file-error "Opening directory"
 "No such file or directory" "d:/the/path/to/foo.el/foo.el/")
  directory-files-and-attributes("foo.el/" nil "[^~]\\'" t string)
  ls-lisp-insert-directory("foo.el" (66) nil "[^~]\\'" nil)
  ls-lisp--insert-directory(...

If I change the (if (or wildcard-regexp full-directory-p) to this
then it seems to fix the problem of raising an error:

 (if (or (and wildcard-regexp
              (not (string= "[^~]\\'" wildcard-regexp)))
         full-directory-p)

But that is not a complete fix.  It does not solve the
problem that `B' does not work for a cons DIRNAME.  

I'm not sure what the right fix is for that, since it's not
clear to me where switch `-B' is handled.  A guess is that
for a whole directory (not for a cons DIRNAME or for a non-dir
filename) it is handled by `directory-files-and-attributes'.
And I'm guessing that that function should still (after a fix)
be called only for the non-cons DIRNAME case.

In that case, I'm guessing that `ls-lisp-insert-directory'
should test for the pseudo wildcards-regexp "[^~]\\'" and
should then DTRT to list the entry showing the block size.
Maybe you can take a look at what that code should be.

Of course, we can just implement the fix I described above,
to prevent an error being raised, and document that `-B' is
not supported for cons DIRNAME.  It would be better to make
it DTRT, however.  This switch needs only to consider a
single file or dir name entry, so it should be possible to
support it.

[BTW, `g' and `n' are listed as supported, but the ls-lisp doc
says that `l' is always assumed (cannot be overridden), so I
don't think `g' or `n' is really supported (`g' is supposed to
be like `l' but does now show owner; `n' is supposed to show
numeric user and group ids).  At least I don't see `g' and `n'
having any effect.  Perhaps this is an ls-lisp.el bug?]

IOW, the switches that correspond to your "Yes" agreement,
above, have no effect when DIRNAME is a cons.

> > Second, it's not just about the doc string.  If no improvement
> > in the behavior is to be expected (I would prefer that it be
> > improved to respect the switches generally, to the extent that is
> > possible), then I think a minimum bug fix, beyond the doc (see
> > above), would be to change the mode-line lighter.  At a bare
> > minimum, the misleading lighter indications "by name|date" need
> > to be removed.
> >
> > Whe DIRNAME is a cons, the lighter should not show anything like
> > "by name" or "by date".  Instead, it should either have just
> > "Dired" or (better) include some indication that the listing is
> > from an explicit list and not necessarily a directory listing.
> > In the latter case, it could also show the (relevant) switches.
> 
> The 's' toggle's implementation is problematic to begin with, IMO,
> so it's small wonder that it doesn't work right in this case.

It is not about the `s' toggle.  It is about switches.  There are
multiple switches that are currently not supported for cons DIRNAME,
including but not limited to most of the switches that handle sort
order.