bug-gnu-emacs
[Top][All Lists]
Advanced

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

bug#22829: Acknowledgement (25.1.50; Display number of marked files)


From: Tino Calancha
Subject: bug#22829: Acknowledgement (25.1.50; Display number of marked files)
Date: Tue, 8 Mar 2016 19:20:15 +0900 (JST)
User-agent: Alpine 2.20 (LRH 67 2015-01-07)



Thank you!  I have a feeling that code could be optimized more before
installing to dired.  I'll check it to estimate how well it works.
Please, test the latest `my-dired-count-sizes-opt3' (at the end of the comments):
*) Added the tramp handlers to make this work on remote directories.
*) `du' receives all the directories at once.

One quick comment: in defcustom my-dired-used-space-program
you could find if an executable exists like:

(defcustom my-dired-used-space-program (and (executable-find "du") du")
Thank you.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Following code requires the patch on Bug#22893

(defcustom my-dired-used-space-program
  (purecopy (let ((opts (if (string-prefix-p "gnu" (symbol-name system-type))
                                                        "-sb"
                                                  "-sk"))) ; -k overestimate used 
space for files w/ size < 1024
                          (cond ((executable-find "du") (list "du" opts))
                                        ((file-executable-p "/usr/sbin/du") (list 
"/usr/sbin/du" opts))
                                        ((file-executable-p "/etc/du") (list 
"/etc/du" opts))
                                        (t (list "du" opts)))))
  "Program and its options to get recursively the total size of a directory.
We assume the output has the format of `du'.

A value of nil disables this feature."
  :type '(list (string :tag "Program")
                           (repeat :tag "Options"
                                           :inline t
                                           (stting :format "%v")))
  :group 'dired)

(defun my-dired-count-sizes-opt3 (&optional mark ask include-dirs)
  "Count sizes of files marked by MARK mark.
When ASK non-nil user is prompted for MARK. Otherwise `dired-marker-char'
is used.
Optional arg INCLUDE-DIRS, if non-nil, run `my-dired-used-space-program'
on the markd directories. Otherwise the size of the directories is
not included."
  ;; TODO: add this info to mode-line and file count too, e.g.: F32 S64k
  ;; and make minor mode
  ;; see `dired-change-marks'
  (interactive
   (let* ((cursor-in-echo-area t)
          (default current-prefix-arg)
          (mark (or (and default (progn (message "Count files marked with mark: 
")
                                                   (read-char)))
                    dired-marker-char))
          (dirs (and default (car my-dired-used-space-program) (y-or-n-p "Include 
directories? "))))
     (list mark t dirs)))
  (unless mark (setq mark dired-marker-char))
  ;; If `my-dired-used-space-program' not available signal an error.
  (when (and include-dirs
             (not (equal 0 (condition-case nil
                               (process-file (car my-dired-used-space-program) 
nil nil nil null-device)
                             (error nil)))))
    (error "Program `my-dired-used-space-program' not found"))
  (require 'cl-lib) ; for cl-remove-if and cl-nset-difference
  (if (eq mark ?\r)
      (progn
        (message "Mark cannot be \\r")
        (sit-for 1)
        (ding))
    (let* ((files          (dired-get-marked-files nil nil nil t mark))
                   (num-files      (or (and (not (cdr files)) 0)
                                                           (and (equal t (car 
files)) (pop files) 1)
                                                           (length files)))
           (non-dirs       (cl-remove-if (lambda(x) (eq (car (file-attributes 
x)) t)) files))
           (total-size     (apply '+ (mapcar (lambda(x) (elt x 7))
                                             (mapcar 'file-attributes 
non-dirs))))
           (dirs           (cl-nset-difference files non-dirs :test 'equal))
           (num-dirs       (length dirs))
           (num-non-dirs   (- num-files num-dirs))
                   (handler        (and dirs (find-file-name-handler (car dirs) 
'call-process)))
           total-size-str)
      (when (and include-dirs (not (= num-dirs 0)))
        (let ((size 0)
                          (scale-factor (if (string= (cadr my-dired-used-space-program) 
"-sk")
                                                                1024.0
                                                          1.0)))
          (with-temp-buffer
                        (if handler
                                (apply handler 'process-file (car 
my-dired-used-space-program)
                                           nil t nil
                                           (cadr my-dired-used-space-program)
                                           (mapcar 'file-name-nondirectory 
dirs))
                          (apply 'process-file (car my-dired-used-space-program)
                                         nil t nil
                                         (cadr my-dired-used-space-program) 
dirs))
            (goto-char 1)
            (while (search-forward-regexp "^[0-9]+" nil t)
              (setq size (+ size (string-to-number (match-string 0))))))
          (setq total-size (+ total-size (* scale-factor size)))))

      (setq total-size-str (if my-dired-human-readable
                               (file-size-human-readable total-size)
                             (my-dired-use-comma-separator total-size)))
      (if (= num-files 0)
          (message "No marked files with mark '%s'" (char-to-string mark))
        (message "Marked %d %s (%d non-dirs/%d dirs) with '%s' and total size 
%s%s%s"
                 num-files
                 (or (and (= num-files 1) "file") "files")
                 num-non-dirs
                 num-dirs
                 (char-to-string mark)
                 total-size-str
                 (or (and my-dired-human-readable "") " bytes")
                 (or (and (not include-dirs) " (dirs size excluded)") ""))))))

(define-key dired-mode-map (kbd "*N") 'my-dired-count-sizes-opt3)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;





reply via email to

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