GNU bug report logs - #22829
25.1.50; Display number of marked files

Previous Next

Package: emacs;

Reported by: Tino Calancha <f92capac <at> gmail.com>

Date: Sat, 27 Feb 2016 14:27:02 UTC

Severity: wishlist

Tags: fixed, patch

Found in version 25.1.50

Fixed in version 27.1

Done: Lars Ingebrigtsen <larsi <at> gnus.org>

Bug is archived. No further changes may be made.

Full log


Message #20 received at 22829 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Tino Calancha <f92capac <at> gmail.com>
Cc: Lars Ingebrigtsen <larsi <at> gnus.org>, 22829 <at> debbugs.gnu.org
Subject: Re: bug#22829: Acknowledgement (25.1.50;
 Display number of marked files)
Date: Wed, 02 Mar 2016 02:32:39 +0200
>> And I'm not sure I'm feeling the utility of this function, either.
>> What's the use case?
>
> For those marking files in several directories quite often, and using
> dired-change-marks to separate files in different categories: those
> people may be interested in counting number of marked files. I need
> this every day, but I agree not too many people would find it useful.

I confirm this is very useful.  I'm using the same for a long time,
but additionally also displaying a total sum of sizes on every mark
(this emulates the behavior of File Commanders on marking files by INS).

The code I'm using in ~/.emacs is very very old, and nowadays
you could implement the same with less code.

;; 2 new functions:
(defun dired-get-file-info ()
  "Get file info files for which PREDICATE returns non-nil."
  ;; code for this function is borrowed from dired-x.el::dired-mark-sexp
  (let (inode s mode nlink uid gid size time name sym)
    (save-excursion
      (if (dired-move-to-filename)
          (let (pos
                (mode-len 10)
                (dired-re-inode-size "\\s *\\([0-9]*\\)\\s *\\([0-9]*\\) ?"))
            (beginning-of-line)
            (forward-char 2)
            (if (looking-at dired-re-inode-size)
                (progn
                  (goto-char (match-end 0))
                  (setq inode (string-to-int (buffer-substring (match-beginning 1)
                                                               (match-end 1)))
                        s (string-to-int (buffer-substring (match-beginning 2)
                                                           (match-end 2)))))
              (setq inode nil
                    s nil))
            (setq mode (buffer-substring (point) (+ mode-len (point))))
            (forward-char mode-len)
            (setq nlink (read (current-buffer)))
            (setq uid (buffer-substring (+ (point) 1) (progn (forward-word 1) (point))))
            ;; works only with ls patch
            ;; patched in dired.el:dired-move-to-filename-regexp
            ;; (re-search-forward "\\([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\\)")
	    ;; try standard expression
            (re-search-forward directory-listing-before-filename-regexp)
            (goto-char (match-beginning 2))
            (forward-char -1)
            (setq size (string-to-int (replace-regexp-in-string
				       ;; handle thousand separators in sizes
				       "," ""
				       (buffer-substring (save-excursion
							   ;; (backward-word 1)
							   (skip-chars-backward "[0-9,.]")
							   (setq pos (point)))
							 (point)))))
            (goto-char pos)
            (backward-word 1)
            (setq gid (buffer-substring (save-excursion (forward-word 1) (point))
                                        (point))
                  time (buffer-substring (match-beginning 1)
                                         (1- (dired-move-to-filename)))
                  name (buffer-substring (point)
                                         (or (dired-move-to-end-of-filename t)
                                             (point)))
                  sym  (progn
                         (if (looking-at " -> ")
                             (buffer-substring (progn (forward-char 4) (point))
                                               (progn (end-of-line) (point)))
                           "")))
            (list
             (cons 'inode inode)
             (cons 's s)
             (cons 'mode mode)
             (cons 'nlink nlink)
             (cons 'uid uid)
             (cons 'gid gid)
             (cons 'size size)
             (cons 'time time)
             (cons 'name name)
             (cons 'sym sym)))
        nil))))

;; TODO: use `pint2hrstr' in Lisp
(defun dired-count-sizes (&optional mark)
  "Count sizes of files marked by MARK mark."
  ;; 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)
          (mark (progn (message "Count files marked by mark: ")
                       (read-char))))
     (list mark)))
  (if (or (eq mark ?\r))
      (ding)
    (let ((string (format "\n%c" mark))
          (buffer-read-only)
          (total-size 0)
          total-size-str
          (total-count 0))
      (save-excursion
        (goto-char (point-min))
        (while (search-forward string nil t)
          (if (if (= mark ?\ )
                  (save-match-data
                    (dired-get-filename 'no-dir t))
                t)
              (if (equal (buffer-substring-no-properties
                          (match-beginning 0) (match-end 0))
                         string)
                  (setq total-size
                        (+ total-size
                           (*;;(/
                            (cdr (assoc 'size (dired-get-file-info)))
                            1.0);;1024)
                           )
                        total-count (+ total-count 1))))))
      (setq total-size-str (replace-regexp-in-string
                            "^," ""
                            (apply 'string
                                   (reverse
                                    (string-to-list
                                     (replace-regexp-in-string
                                      "\\([0-9]\\{3\\}\\)" "\\1,"
                                      (apply 'string
                                             (reverse
                                              (string-to-list
                                               (replace-regexp-in-string
                                                "\.0$" ""
                                                (number-to-string
                                                 total-size)))))))))))
      (message "Marked %s files with %s bytes" total-count total-size-str))))

(define-key dired-mode-map [(shift f5)] 'dired-count-sizes)

(defun my-dired-mark (arg)
  "Mark ARG files and print the total size of marked files."
  (interactive "P")
  (dired-mark arg)
  (dired-count-sizes dired-marker-char))
(define-key dired-mode-map [insert] 'my-dired-mark)

(defun my-dired-unmark-backward (arg)
  "Move up lines, remove deletion flag there and print size of marked files."
  (interactive "p")
  (dired-unmark-backward arg)
  (dired-count-sizes dired-marker-char))
(define-key dired-mode-map [backspace] 'my-dired-unmark-backward)




This bug report was last modified 6 years and 24 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.