bug#81295: 32.0.50; dired-auto-toggle-b-switch problem with subdirectory
Stephen Berman via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <[email protected]> Thu, 30 Jul 2026 12:07:35 +0200
| Newsgroups | gmane.emacs.bugs |
|---|---|
| Message-ID | <[email protected]> |
On Wed, 29 Jul 2026 18:06:46 +0300 Eli Zaretskii <[email protected]> wrote: >> From: Filipp Gunbin <[email protected]> >> Cc: [email protected], [email protected], [email protected] >> Date: Wed, 29 Jul 2026 17:49:31 +0300 >> >> On 29/07/2026 17:00 +0300, Eli Zaretskii wrote: >> >> >> From: Filipp Gunbin <[email protected]> >> >> Cc: Eli Zaretskii <[email protected]>, [email protected], >> >> [email protected] >> >> Date: Wed, 29 Jul 2026 16:50:52 +0300 >> >> >> >> On 29/07/2026 15:32 +0200, Stephen Berman wrote: >> >> >> >> [...] >> >> >> >> > So that's the current situation, and why I've turned to you and Sean for >> >> > a decision on how to proceed: (i) install my changes to handle file >> >> > names with newlines in Dired subdirs, including the change that "fixes" >> >> > the bug with `C-u i'; (ii) install the changes except for the one that >> >> > "fixes" the `C-u i' bug, thus leaving that unfixed for now; (iii) wait >> >> > for Filipp's alternative implementation, which will hopefully fix that >> >> > bug without circumventing validation of subdir switches. >> >> >> >> As I wrote already, I do not object to (ii), we agree on that patch. I >> >> object only to the fix of supposedly rare problem which we found in the >> >> course of discussing this bug, and (i) additionally includes that fix. >> >> We could create another bug report for that and see if anyone (me, or >> >> you, or somebody else) comes up with the patch that we all agree with. >> >> That is, (iii) is not an alternative to (ii) - we could install the >> >> patch in (ii) right now, and that will fix the problem which I created >> >> this bug about. >> > >> > Why not install (i) and _then_ wait for that one aspect to be fixed >> > separately? >> >> My concerns are that (i): >> >> - Breaks the current logic, and thus will introduce more subtle bugs. >> Given that the problem it fixes is minor, I don't see this as a good >> trade-off. >> >> - Makes the code harder to read and change later, as it adds a >> non-obvious special case, and you need to read this discussion to >> understand why it was added. I always favor cleaner code, that's why >> I'd prefer to create another bug, rather than fix it here "at all >> costs", but that's me. > > Fair enough, let's wait for Sean to chime in. While we're waiting, I'd like to propose the attached patch an alternative to (ii) which is acceptable to me: it omits the fix the Filipp objects to but issues a warning when the user enters `C-u i' and triggers the bug. This way I don't feel like we're disengenuously exposing users to a known bug that has a fix, though one currently too controversial to be installed. While testing this I discovered that the code for displaying a warning when `dired-auto-toggle-b-switch' is nil does not account for the case where the subdir containing a file whose name contains a newline is more deeply embedded than one subdir level in the Dired buffer, and the attached patch fixes this; this fix should be included in the installed changeset regardless of the decision on the `C-u i' case. Steve Berman
(unnamed)
(text/x-patch, 4.4 KB)
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 50287a67129..e773bb6f2a1 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -3356,7 +3356,24 @@ dired-insert-subdir
(modflag (buffer-modified-p))
(old-switches switches)
switches-have-R mark-alist case-fold-search buffer-read-only)
- (and (not switches) cons (setq switches (cdr cons)))
+ (and (not switches)
+ ;; FIXME: This line fixes a bug when entering `C-u i' with
+ ;; `dired-auto-toggle-b-switch' non-nil, but the fix is
+ ;; controversial so currently not used; see bug#81295.
+ ;; (not (dired-switches-escape-p dired-actual-switches))
+ cons (setq switches (cdr cons)))
+ ;; FIXME: Since the bug results is a bad Dired display, we warn the
+ ;; user; remove this warning when an acceptable fix is installed.
+ (when (and dired-auto-toggle-b-switch dired-switches-alist
+ (directory-files (caar dired-switches-alist) nil "\n")
+ (dired-switches-escape-p dired-actual-switches)
+ (not (dired-switches-escape-p (cdar dired-switches-alist))))
+ (display-warning 'dired
+ "
+You have encountered a known Emacs bug
+for which there is currently no acceptable solution;
+see <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=81295#56>
+and the related messages for details."))
(dired-insert-subdir-validate dirname switches)
;; case-fold-search is nil now, so we can test for capital `R':
(if (setq switches-have-R (and switches (string-match-p "R" switches)))
@@ -3382,6 +3399,16 @@ dired-insert-subdir
(if cur-cons
(setcdr cur-cons switches)
(push (cons cur-dir switches) dired-switches-alist)))))))
+ ;; Since we insert subdirs without calling `dired-internal-noselect'
+ ;; we also have to test here whether the subdir contains a file name
+ ;; with a newline, and if so, pop up a warning. FIXME: Is there a
+ ;; cleaner way to do this? See bug#81295.
+ (unless (or dired-auto-toggle-b-switch
+ (dired-switches-escape-p dired-listing-switches)
+ (dired-switches-escape-p dired-actual-switches))
+ (when (and (dired--filename-with-newline-p)
+ (dired--ls-accept-b-switch-p))
+ (dired--display-filename-with-newline-warning (current-buffer))))
(dired-initial-position dirname)
(save-excursion (dired-mark-remembered mark-alist))
(restore-buffer-modified-p modflag)))
diff --git a/lisp/dired.el b/lisp/dired.el
index 53ec6779061..a4bfd81b5b9 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -1487,7 +1487,9 @@ dired-internal-noselect
;; and `ls' can take the `b' switch. We do this here in order to
;; get the warning not only when interactively invoking `dired' on a
;; directory, but also e.g. when passing the directory name as a
- ;; command line argument when starting Emacs from the shell.
+ ;; command line argument when starting Emacs from the shell (but
+ ;; inserting subdirs does not call `dired-internal-noselect' so we
+ ;; also have to run this test in `dired-insert-subdir').
(unless (or dired-auto-toggle-b-switch
(dired-switches-escape-p dired-listing-switches)
(dired-switches-escape-p dired-actual-switches))
@@ -4060,11 +4062,18 @@ dired-buffer-more-recently-used-p
(not (memq buffer1 (memq buffer2 (buffer-list))))))
(defun dired--filename-with-newline-p ()
- "Check whether a file name in this directory has a newline.
-Return non-nil if at least one file name in this directory contains a
-newline character (regardless of whether Dired displays the character as
-a literal newline or as \"\\n\")."
- (directory-files default-directory nil "\n"))
+ "Check whether a file name in this Dired buffer has a newline.
+Return non-nil if at least one file name in this Dired buffer (including
+any Dired subdirectories in the buffer) contains a newline character
+(regardless of whether Dired displays the character as a literal newline
+or as \"\\n\")."
+ (if (length> dired-subdir-alist 1)
+ (let (res)
+ (catch 'found
+ (dolist (subdir dired-subdir-alist res)
+ (setq res (directory-files (car subdir) nil "\n"))
+ (and res (throw 'found res)))))
+ (directory-files default-directory nil "\n")))
(defun dired--ls-accept-b-switch-p ()
"Return non-nil if the `ls' used by Dired accepts the `b' switch."