Subject: Re: bug#8484: 24.0.50; Dired problems with marking and hidden subdirs

From: Marcin Borkowski <[email-masked]>
Date: Fri, 22 Jan 2016 21:55:21 +0100

Hello,

I'm writing to confirm that I can reproduce this under GNU Emacs
25.1.50.1.

Best,
Marcin Borkowski

On 2011-04-12, at 14:58, Stephen Berman <[email-masked]> wrote:

> 1. emacs -Q
> 2. Create a directory containing a non-empty directory,
>    e.g. "~/test/test0/test1". 
> 3. Visit "test" in Dired: `C-x d ~/test RET'
> 4. Put point on "test0" and type `i' to insert the subdirectory.
> 5. With point within the inserted subdirectory type `$' to hide it.
> 6. Type `% m RET' to mark all files except "." and "..".  This is what
>    buffer "test" now looks like:
>
>      /home/steve/test:
>      total used in directory 12 available 24083132
>      drwxr-xr-x 3 steve users 4096 2011-04-12 09:22 .
>      drwxr-xr-x 6 steve users 4096 2011-04-12 09:20 ..
>    * drwxr-xr-x 3 steve users 4096 2011-04-12 09:23 test0
>    
>    * /home/steve/test/test0:...
>
> 7. Try to operate on the marked files, e.g. `C', `R', 'D' etc.
> => Instead of the operation being executed, you get the message "Cannot
> operate on `.' or `..'".
> 8. Now type `$' on the hidden subdirectory to unhide it.  The two marked
>    lines remain marked.  Then repeat step 7.
> => Regardless of where point is, you get this error: "No file on this line"
>
> I believe these problems are due to the hidden subdirectory being a
> single line, since selective display replaces "\n" with "\r".  In the
> first case, when dired-mark-if is called in dired-mark-files-regexp,
> with point at the beginning of the hidden subdirectory, (looking-at
> dired-re-dot) is nil but dired-get-filename finds "." inside "test0",
> and this triggers the error message.  In the second case, when
> dired-move-to-filename is called in dired-map-over-marks with point on
> the subdirectory, it fails and raises the error.
>
> I see two directions to go for fixing this: (a) temporarily unhide the
> subdirectory (probably iteratively) and then mark as usual, so that the
> dired-re-dot filter succeeds; (b) prevent any marking of (and hence
> within) hidden subdirectories.  It seems that the latter is more
> consistent with current Dired behavior: if you remove the marks from
> "test" above, then unhide "test0", then type `% m RET', so that now
> "test0" and "test1" are marked, then hide "test0" again, then invoke an
> operation, e.g. `C', `R', 'D' etc. -- only "test0" gets operated on, not
> "test1".  That is, the marked file in the hidden subdirectory is
> ignored.  So marking the hidden subdirectory in step 6 above is the real
> bug, given current Dired behavior.  One way to fix this is the below
> patch to dired-get-filename: this checks whether the current line is a
> hidden subdirectory and if so, unhides it, so that it isn't just a
> single line and the line does not get marked, then after
> dired-move-to-filename fails, hides it again, shortcutting any further
> marking.
>
> In GNU Emacs 24.0.50.1 (i686-suse-linux-gnu, GTK+ Version 2.20.1)
>  of 2011-04-03 on escher
> Windowing system distributor `The X.Org Foundation', version 11.0.10800000
> configured using `configure  '--without-toolkit-scroll-bars' 'CFLAGS=-g -O2 -fno-optimize-sibling-calls''
>
> Important settings:
>   value of $LC_ALL: nil
>   value of $LC_COLLATE: nil
>   value of $LC_CTYPE: nil
>   value of $LC_MESSAGES: nil
>   value of $LC_MONETARY: nil
>   value of $LC_NUMERIC: nil
>   value of $LC_TIME: nil
>   value of $LANG: en_US.UTF-8
>   value of $XMODIFIERS: @im=local
>   locale-coding-system: utf-8-unix
>   default enable-multibyte-characters: t
>
>
> *** /data/steve/bzr/emacs/trunk/lisp/dired.el	2011-04-03 16:10:27.000000000 +0200
> --- /data/steve/bzr/emacs/quickfixes/lisp/dired.el	2011-04-12 12:48:02.000000000 +0200
> ***************
> *** 2049,2058 ****
>   Optional arg NO-ERROR-IF-NOT-FILEP means treat `.' and `..' as
>   regular filenames and return nil if no filename on this line.
>   Otherwise, an error occurs in these cases."
> !   (let (case-fold-search file p1 p2 already-absolute)
>       (save-excursion
>         (if (setq p1 (dired-move-to-filename (not no-error-if-not-filep)))
>   	  (setq p2 (dired-move-to-end-of-filename no-error-if-not-filep))))
>       ;; nil if no file on this line, but no-error-if-not-filep is t:
>       (if (setq file (and p1 p2 (buffer-substring p1 p2)))
>   	(progn
> --- 2049,2061 ----
>   Optional arg NO-ERROR-IF-NOT-FILEP means treat `.' and `..' as
>   regular filenames and return nil if no filename on this line.
>   Otherwise, an error occurs in these cases."
> !   (let ((hidden (dired-subdir-hidden-p (dired-current-directory)))
> ! 	case-fold-search file p1 p2 already-absolute)
> !     (if hidden (dired-unhide-subdir))
>       (save-excursion
>         (if (setq p1 (dired-move-to-filename (not no-error-if-not-filep)))
>   	  (setq p2 (dired-move-to-end-of-filename no-error-if-not-filep))))
> +     (if hidden (dired-hide-subdir 1))
>       ;; nil if no file on this line, but no-error-if-not-filep is t:
>       (if (setq file (and p1 p2 (buffer-substring p1 p2)))
>   	(progn