master 5a58e371698: Handle file names with newlines in Dired subdirs (bug#81295)
Stephen Berman via Mailing list for Emacs changes <[email protected]> Thu, 30 Jul 2026 17:06:01 -0400 (EDT)
| Newsgroups | gmane.emacs.diffs |
|---|---|
| Message-ID | <[email protected]> |
branch: master commit 5a58e371698c2d2c29dc8ca9616b3bfbe5fceaf3 Author: Stephen Berman <[email protected]> Commit: Stephen Berman <[email protected]> Handle file names with newlines in Dired subdirs (bug#81295) * lisp/dired.el (dired-internal-noselect): Add to the comment about displaying a warning about literal newlines a reference to needing the same test with subdirs. (dired--filename-with-newline-p): If the Dired buffer has subdirs, check these for file names with newlines. * lisp/dired-aux.el (dired-insert-subdir): Test for file names with literal newlines in subdirs and if there are display a warning. Add a comment about buggy Dired display when using extra 'ls' switches on inserting a subdir, and display a temporary warning about this (to be removed when the bug is fixed). --- lisp/dired-aux.el | 31 ++++++++++++++++++++++++++++++- lisp/dired.el | 21 +++++++++++++++------ 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 50287a67129..faa0317dd32 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -3356,7 +3356,26 @@ This function takes some pains to conform to `ls -lR' output." (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 + ;; <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=81295#20> and + ;; the following messages and also bug#81522 for discussion. + ;; (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 +3401,16 @@ This function takes some pains to conform to `ls -lR' output." (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 and bug#81522. + (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 @@ The return value is the target column for the file names." ;; 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 @@ Considers buffers closer to the car of `buffer-list' to be more recent." (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."