emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [ELPA] New package: dired-duplicates


From: Philip Kaludercic
Subject: Re: [ELPA] New package: dired-duplicates
Date: Tue, 31 Oct 2023 12:21:51 +0000

Harald Judt <h.judt@gmx.at> writes:

> Hi,
>
> I have developed the following package and assigned copyright for it
> to the FSF and would now like to publish it to GNU ELPA (it has
> previously been published to MELPA):
>
> URL: https://codeberg.org/hjudt/dired-duplicates
>
> Description:
> This package helps to find duplicate files on local and remote filesystems.
> It is similar to the fdupes command-line utility but written in Emacs Lisp
> and should also work on every remote filesystem that TRAMP supports and
> where executable commands can be called remotely.  The only external
> requirement is a checksum program like md5 or sha256sum that generates a
> hash value from the contents of a file used for comparison, because Emacs
> cannot do that in a performance-efficient way.
>
> dired-duplicates works by first searching files of the same size, then
> invoking the calculation of the checksum for these files, and presents the
> grouped results in a Dired buffer that the user can work with similarly to
> a regular Dired buffer.
> ----
>
> Could someone help me with the next steps?

Sure, I can take care of adding the package to the archive, you'll only
have to bump the "Version" header when you want the package to be
released (and in the future as well, the commit that touches the
"Version" header triggers a new release).

In the meantime, here is some quick and superficial feedback on the code:

diff --git a/dired-duplicates.el b/dired-duplicates.el
index d62af02..4af37a3 100644
--- a/dired-duplicates.el
+++ b/dired-duplicates.el
@@ -54,7 +54,6 @@
 (defcustom dired-duplicates-separate-results
   t
   "Boolean value indicating whether to separate results with new-lines."
-  :group 'dired-duplicates
   :tag "Separate results"
   :type 'boolean)
 
@@ -64,7 +63,6 @@
 
 The checksums will be used for comparison of files of the same
 size."
-  :group 'dired-duplicates
   :tag "Checksum executable"
   :type 'string)
 
@@ -73,10 +71,9 @@ size."
   "The comparison function used for sorting grouped results.
 
 The sorting can be in ascending (<) or descending (>) order."
-  :group 'dired-duplicates
   :tag "Ascending or descending file size sort order"
-  :type '(choice (const :tag "Ascending" :value <)
-                 (const :tag "Descending" :value >)))
+  :type '(choice (const :tag "Ascending" <)
+                 (const :tag "Descending" >)))
 
 (defcustom dired-duplicates-file-filter-functions
   nil
@@ -84,14 +81,12 @@ The sorting can be in ascending (<) or descending (>) 
order."
 
 A filter function must accept as its single argument the file and
 return boolean t if the file matches a criteria, otherwise nil."
-  :group 'dired-duplicates
   :tag "File filter functions"
   :type 'hook)
 
 (defcustom dired-duplicates-search-directories-recursively
   t
   "Search directories recursively."
-  :group 'dired-duplicates
   :tag "Search directories recursively"
   :type 'boolean)
 
@@ -103,21 +98,22 @@ return boolean t if the file matches a criteria, otherwise 
nil."
 
 The executable used is defined by `dired-duplicates-checksum-exec'."
   (let* ((default-directory (file-name-directory (expand-file-name file)))
-         (exec (executable-find dired-duplicates-checksum-exec t)))
+         (exec (executable-find dired-duplicates-checksum-exec t))
+        (file (expand-file-name (file-local-name file))))
     (unless exec
-      (user-error "Checksum program %s not found in exec-path" exec))
-    (car (split-string
-          (shell-command-to-string
-           (concat exec " \"" (expand-file-name (file-local-name file)) "\""))
-          nil
-          t))))
+      (user-error "Checksum program %s not found in `exec-path'" exec))
+    (with-temp-buffer
+      (unless (zerop (call-process exec nil t nil file))
+       (error "Failed to start checksum program %s" exec))
+      (goto-char (point-min))
+      (if (looking-at "\\`[[:alnum:]]+")
+         (match-string 0)
+       (error "Unexpected output from checksum program %s" exec)))))
 
 (defun dired-duplicates--apply-file-filter-functions (files)
   "Apply file filter functions to FILES, returning the resulting list."
-  (if (and dired-duplicates-file-filter-functions files)
-      (dolist (filter-func dired-duplicates-file-filter-functions files)
-        (setf files (cl-delete-if-not filter-func files)))
-    files))
+  (dolist (filter-func dired-duplicates-file-filter-functions files)
+    (setf files (cl-delete-if-not filter-func files))))
 
 (defun dired-duplicates--find-and-filter-files (directories)
   "Search below DIRECTORIES for duplicate files.
@@ -140,14 +136,14 @@ duplicate files as values."
                     (append (gethash size same-size-table) (list f)))
            finally
            (cl-loop for same-size-files being the hash-values in 
same-size-table
-                    if (> (length same-size-files) 1) do
+                    if (> (length same-size-files) 1) do ;see length>
                     (cl-loop for f in same-size-files
                              for checksum = (dired-duplicates-checksum-file f)
                              do (setf (gethash checksum checksum-table)
                                       (append (gethash checksum 
checksum-table) (list f)))))
            (cl-loop for same-files being the hash-value in checksum-table 
using (hash-key checksum)
                     do
-                    (if (> (length same-files) 1)
+                    (if (cdr same-files) ;(> (length same-files) 1) in O(1)
                         (setf (gethash checksum checksum-table)
                               (cons (file-attribute-size (file-attributes (car 
same-files)))
                                     (sort same-files #'string<)))
@@ -180,7 +176,6 @@ Currently, this simply adds a new-line after each results 
group."
                for len in lengths
                do
                (forward-line len)
-               ;; (forward-line len)
                (let ((inhibit-read-only t))
                  (beginning-of-line)
                  (unless (= (point) (point-max))
@@ -225,7 +220,7 @@ This is the same as `dired-do-flagged-delete', but calls
 
 (defvar dired-duplicates-map
   (let ((map (make-sparse-keymap)))
-    ;; workaround for Emacs bug #57565
+    ;; workaround for Emacs bug#57565
     (when (< emacs-major-version 29)
       (define-key map (kbd "x") 'dired-duplicates--do-flagged-delete)
       (define-key map (kbd "D") 'dired-duplicates--do-delete))
@@ -248,7 +243,7 @@ The results will be shown in a Dired buffer."
                                                default-directory)))
   (unless directories
     (user-error "Specify one or more directories to search in"))
-  (let* ((directories (if (listp directories) directories (list directories)))
+  (let* ((directories (if (listp directories) directories (list directories))) 
;see `ensure-list'
          (truncated-dirs (truncate-string-to-width (string-join directories ", 
") 40 0 nil t)))
     (message "Finding duplicate files in %s..." truncated-dirs)
     (if-let ((default-directory "/")
@@ -257,7 +252,7 @@ The results will be shown in a Dired buffer."
           (message "Finding duplicate files in %s completed." truncated-dirs)
           (dired (cons "/" (flatten-list results)))
           (set-keymap-parent dired-duplicates-map (current-local-map))
-          (setf (current-local-map) dired-duplicates-map)
+         (use-local-map dired-duplicates-map)
           (setq-local dired-duplicates-directories directories)
           (setq-local revert-buffer-function 'dired-duplicates-dired-revert)
           (dired-duplicates--post-process-dired-buffer results))
> Regards,
> Harald

-- 
Philip Kaludercic

reply via email to

[Prev in Thread] Current Thread [Next in Thread]