0

I am working on implementing my own feature request -- http://debbugs.gnu.org/cgi/bugreport.cgi?bug=31601 -- to give wdired the ability to handle a dired- buffer that contains an arbitrary list of absolute paths to directories and files; e.g.,

(dired (directory-files-recursively "/path/to/directory" "" 'include-directories))

However, the files and directories may not necessarily be recursive -- i.e., dired-mode can handle creating a buffer containing an arbitrary list of files and directories.

I have added draft code to wdired that places read-only text properties on the file-name-directory. That way, a user cannot edit those portions of the path while in wdired-mode.

The next step is to process the renaming of files/directories, which requires they be done in a hierarchical order. For example, a user may have renamed a directory and a file:

OLD NAME:   /path/to/directory

NEW NAME:   /path/to/the_directory

OLD NAME:   /path/to/directory/file

NEW NAME:   /path/to/directory/the_file

OLD NAME:   /path/to/different_directory

NEW NAME:   /path/to/the_different_directory

OLD NAME:   /path/to/different_directory/different_file

NEW NAME:  /path/to/different_directory/the_different_file

If we first rename the directory from /path/to/directory to /path/to/the_directory, then rename-file will be unable to rename /path/to/directory/file because the directory no longer exists; i.e., the directory was changed to the_directory.

Therefore, it makes sense to sort all of the files and directories into a hierarchical order such that the deepest file or directory is processed fist in time when renaming the files/directories. For example, if we have a set of files that are 5 directories deep, then those should be processed before processing directories or files that are less than 5 deep.

Q: How to sort a list of files/directories by hierarchical depth?

WORKING LIST:

'("/path/to/different_directory/different_file"
  "/path/to/directory/file"
  "/X/Y"
  "/a/b/c/d/e/f"
  "/1/2/3/4"
  "/A/B/C/D/e"
  "/x/y/Z"
  "/Z"
  "/path/to/different_directory"
  "/path/to/directory")

RESULT DESIRED:

'("/a/b/c/d/e/f"
  "/A/B/C/D/e"
  "/path/to/different_directory/different_file"
  "/1/2/3/4"
  "/path/to/directory/file"
  "/x/y/Z"
  "/path/to/different_directory"
  "/path/to/directory"
  "/X/Y"
  "/Z")
  • Define a function that counts directory "steps"? Anyway, I hope you're considering creating a minor mode for your feature, so that a user can, for example, turn it on and off in Wdired. It would be a shame to just modify Wdired so that it always had the behavior you suggest (e.g. read-only directory components). – Drew May 27 '18 at 20:51
  • @Drew -- thank you for taking a look at this thread. My understanding of the current behavior of wdired is to let the user mistakenly believe that he/she is modifying a component of the file-name-directory and then when the user types C-c C-c or wdired-finish-edit, the proposed edit to the file-name-directory cannot be processed: (file-error Renaming No such file or directory .... The reason for that error is because only the file-name-nondirectory can be edited without errors, and still there would be the problem described above due to processing of hierarchy/directory-steps. – lawlist May 28 '18 at 0:45
  • @Drew -- by placing read-only properties on the file-name-directory, it prevents the user from mistakenly thinking he/she has edited something successfully and it prevents the above-mentioned file-error. In general, I suggest things through the years to the Emacs team and they choose what, if anything, gets implemented. I am usually happy if it works in my own setup even if the feature never gets implemented. – lawlist May 28 '18 at 0:47
  • I see. I didn't know that one cannot modify directory components anyway. Yes, it makes sense to prevent someone from trying that and only finding out later that an error is raised. – Drew May 28 '18 at 4:24
1

Hm, I am not so sure why you decide to sort "/1/2/3/4" before "/path/to/directory/file" in your desired result.

If you can skip that specification the solution is rather simple:

(let ((paths
       '("/path/to/different_directory/different_file"
         "/path/to/directory/file"
         "/X/Y"
         "/a/b/c/d/e/f"
         "/1/2/3/4"
         "/A/B/C/D/e"
         "/x/y/Z"
         "/Z"
         "/path/to/different_directory"
         "/path/to/directory")))
  (cl-stable-sort paths
       (lambda (path1 path2)
         (> (cl-count ?/ path1)
            (cl-count ?/ path2)))))
  • Thank you very much. I manually placed "/1/2/3/4" before "/path/to/directory/file" in the proposed desired result for no reason other than each has four (4) components. Your answer does the job nicely. – lawlist May 28 '18 at 0:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.