Subject: bug#64606: 29.0.91; Error when editing partial matched files with dired editable mode

From: Eli Zaretskii <[email-masked]>
Date: Sun, 16 Jul 2023 10:10:06 +0300

> From: Aditya Yadav <[email-masked]>
> Date: Fri, 14 Jul 2023 02:49:23 +0530
> 
> Let say in the current dir it is the following structure
> .
> ├── star1
> │   └── letter1
> ├── star2
> │   └── letter2
> └── star3
>     └── letter3
> 
> When i open dired with the command partial match `./s/l`
> 
>   -rw-rw-r-- 1 aditya-yadav 6 2023-07-13 22:32 star1/letter1
>   -rw-rw-r-- 1 aditya-yadav 6 2023-07-13 22:32 star2/letter2
>   -rw-rw-r-- 1 aditya-yadav 6 2023-07-13 22:32 star3/letter3
> 
> When i try to rename a file with dired editable mode and when i write the changes
> Dired errors out and closes the buffer although the rename of the file is successful
> 
> Aside from the partial match you can go to that directory with the above structure and run
> (dired '("." "star1/letter1" "star2/letter2" "star3/letter3"))
> from eshell to get the same result
> 
> Debug on error output:-
> 
> Debugger entered--Lisp error: (file-missing "Reading directory" "No such file or directory"
> "star1/letter1")
>   #<subr insert-directory>("star1/letter1" "--dired -AGFhlv --group-directories-first --time-s..." nil nil)
>   ls-lisp--insert-directory(#<subr insert-directory> "star1/letter1" "--dired -AGFhlv -
> -group-directories-first --time-s..." nil nil)
>   apply(ls-lisp--insert-directory #<subr insert-directory> ("star1/letter1" "--dired -AGFhlv -
> -group-directories-first --time-s..." nil nil))
>   insert-directory("star1/letter1" "--dired -AGFhlv --group-directories-first --time-s..." nil nil)
>   dired-insert-directory("/home/aditya-yadav/Personal/Demo/" "-AGFhlv --group-directories-first -
> -time-style=lon..." ("star1/letter1" "star2/letter2" "star3/letter3") nil t)
>   dired-readin-insert()
>   #<subr F616e6f6e796d6f75732d6c616d626461_anonymous_lambda_47>()
>   combine-change-calls-1(1 227 #<subr
> F616e6f6e796d6f75732d6c616d626461_anonymous_lambda_47>)
>   dired-readin()
>   dired-revert(nil nil)
>   revert-buffer()
>   wdired-finish-edit()
>   funcall-interactively(wdired-finish-edit)
>   evil-ex-call-command(nil #("w" 0 1 (ex-index 1)) nil)
>   evil-ex-execute(#("w" 0 1 (ex-index 1)))
>   evil-ex(nil)
>   funcall-interactively(evil-ex nil)
>   command-execute(evil-ex)

Thanks.  Does the patch below give good results?

diff --git a/lisp/wdired.el b/lisp/wdired.el
index 5c745cc..7b9c75d 100644
--- a/lisp/wdired.el
+++ b/lisp/wdired.el
@@ -556,8 +556,24 @@ wdired-finish-edit
                         ;; been modified with their new name keeping
                         ;; the ones that are unmodified at the same place.
                         (cl-loop for f in (cdr dired-directory)
-                                 collect (or (assoc-default f files-renamed)
-                                             f))))))
+                                 collect
+                                 (or (assoc-default f files-renamed)
+                                     ;; F could be relative or
+                                     ;; abbreviated, whereas
+                                     ;; files-renamed always consists
+                                     ;; of absolute file names.
+                                     (let ((relative
+                                            (not (file-name-absolute-p f)))
+                                           (match
+                                            (assoc-default (expand-file-name f)
+                                                           files-renamed)))
+                                       (cond
+                                        ;; If it was relative, convert
+                                        ;; the new name back to relative.
+                                        ((and match relative)
+                                         (file-relative-name match))
+                                        (t match)))
+                                     f))))))
 	  ;; Re-sort the buffer.
 	  (revert-buffer)
 	  (let ((inhibit-read-only t))