Subject: Re: bug#22893: 25.1.50; dired-get-marked-files get all marked

From: Tino Calancha <[email-masked]>
Date: Tue, 8 Mar 2016 14:18:58 +0900 (JST)

> Looks good, I think.  Can you include a NEWS entry for this and resubmit
> the patch?
Attached the patch including the NEWS entry.

From e2040516b2949ba3f626448463f10baeb178d57c Mon Sep 17 00:00:00 2001
From: Tino Calancha <[email-masked]>
Date: Tue, 8 Mar 2016 13:32:49 +0900
Subject: [PATCH 1/2] Dired operate on all kind of mark characters

* lisp/dired.el (dired-map-over-marks): Added optional arg 'all-marks'.
(dired-marker-regexp): Idem.
(dired-get-marked-files): Added two optional args, 'marker-char'
and 'all-marks' (Bug#22893).
If MARKER-CHAR non-nil, return files marked with MARKER-CHAR.
If ALL-MARKS, non-nil, return files marked with any
mark character.

Callers are not affected.
---
 lisp/dired.el | 127 +++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 72 insertions(+), 55 deletions(-)

diff --git a/lisp/dired.el b/lisp/dired.el
index 6c7445c..bf81649 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -553,7 +553,7 @@ dired-mark-if
     (and (> count 0) count)))
 
 (defmacro dired-map-over-marks (body arg &optional show-progress
-				     distinguish-one-marked)
+                     distinguish-one-marked all-marks)
   "Eval BODY with point on each marked line.  Return a list of BODY's results.
 If no marked file could be found, execute BODY on the current
 line.  ARG, if non-nil, specifies the files to use instead of the
@@ -579,55 +579,60 @@ dired-map-over-marks
 BODY should not be too long as it is expanded four times.
 
 If DISTINGUISH-ONE-MARKED is non-nil, then if we find just one
-marked file, return (t FILENAME) instead of (FILENAME)."
+marked file, return (t FILENAME) instead of (FILENAME).
+
+If ALL-MARKS is non-nil, accept all mark characters.  Otherwise use
+just `dired-marker-char'."
   ;;
   ;;Warning: BODY must not add new lines before point - this may cause an
   ;;endless loop.
   ;;This warning should not apply any longer, sk  2-Sep-1991 14:10.
   `(prog1
        (let ((inhibit-read-only t) case-fold-search found results)
-	 (if ,arg
-	     (if (integerp ,arg)
-		 (progn	;; no save-excursion, want to move point.
-		   (dired-repeat-over-lines
-		    ,arg
-		    (function (lambda ()
-				(if ,show-progress (sit-for 0))
-				(setq results (cons ,body results)))))
-		   (if (< ,arg 0)
-		       (nreverse results)
-		     results))
-	       ;; non-nil, non-integer ARG means use current file:
-	       (list ,body))
-	   (let ((regexp (dired-marker-regexp)) next-position)
-	     (save-excursion
-	       (goto-char (point-min))
-	       ;; remember position of next marked file before BODY
-	       ;; can insert lines before the just found file,
-	       ;; confusing us by finding the same marked file again
-	       ;; and again and...
-	       (setq next-position (and (re-search-forward regexp nil t)
-					(point-marker))
-		     found (not (null next-position)))
-	       (while next-position
-		 (goto-char next-position)
-		 (if ,show-progress (sit-for 0))
-		 (setq results (cons ,body results))
-		 ;; move after last match
-		 (goto-char next-position)
-		 (forward-line 1)
-		 (set-marker next-position nil)
-		 (setq next-position (and (re-search-forward regexp nil t)
-					  (point-marker)))))
-	     (if (and ,distinguish-one-marked (= (length results) 1))
-		 (setq results (cons t results)))
-	     (if found
-		 results
-	       (list ,body)))))
+     (if ,arg
+         (if (integerp ,arg)
+         (progn ;; no save-excursion, want to move point.
+           (dired-repeat-over-lines
+            ,arg
+            (function (lambda ()
+                (if ,show-progress (sit-for 0))
+                (setq results (cons ,body results)))))
+           (if (< ,arg 0)
+               (nreverse results)
+             results))
+           ;; non-nil, non-integer ARG means use current file:
+           (list ,body))
+       (let ((regexp (dired-marker-regexp ,all-marks)) next-position)
+         (save-excursion
+           (goto-char (point-min))
+           ;; remember position of next marked file before BODY
+           ;; can insert lines before the just found file,
+           ;; confusing us by finding the same marked file again
+           ;; and again and...
+           (setq next-position (and (re-search-forward regexp nil t)
+                    (point-marker))
+             found (not (null next-position)))
+           (while next-position
+         (goto-char next-position)
+         (if ,show-progress (sit-for 0))
+         (setq results (cons ,body results))
+         ;; move after last match
+         (goto-char next-position)
+         (forward-line 1)
+         (set-marker next-position nil)
+         (setq next-position (and (re-search-forward regexp nil t)
+                      (point-marker)))))
+         (if (and ,distinguish-one-marked (= (length results) 1))
+         (setq results (cons t results)))
+         (if found
+         results
+           (list ,body)))))
      ;; save-excursion loses, again
      (dired-move-to-filename)))
 
-(defun dired-get-marked-files (&optional localp arg filter distinguish-one-marked)
+(defun dired-get-marked-files (&optional localp arg filter
+                                         distinguish-one-marked
+                                         marker-char all-marks)
   "Return the marked files' names as list of strings.
 The list is in the same order as the buffer, that is, the car is the
   first marked file.
@@ -644,22 +649,29 @@ dired-get-marked-files
 
 If DISTINGUISH-ONE-MARKED is non-nil, then if we find just one marked file,
 return (t FILENAME) instead of (FILENAME).
-Don't use that together with FILTER."
-  (let ((all-of-them
-	 (save-excursion
-	   (delq nil (dired-map-over-marks
-		      (dired-get-filename localp 'no-error-if-not-filep)
-		      arg nil distinguish-one-marked))))
-	result)
+Don't use that together with FILTER.
+
+Optional arg MARKER-CHAR, if non-nil, then it is the mark
+character to search.  Otherwise use `dired-marker-char'.
+
+Optional arg ALL-MARKS, if non-nil, then accept all mark characters.
+Otherwise use just MARKER-CHAR."
+  (let* ((dired-marker-char (or marker-char dired-marker-char))
+         (all-of-them
+          (save-excursion
+            (delq nil (dired-map-over-marks
+                       (dired-get-filename localp 'no-error-if-not-filep)
+                       arg nil distinguish-one-marked all-marks))))
+         result)
     (when (equal all-of-them '(t))
       (setq all-of-them nil))
     (if (not filter)
-	(if (and distinguish-one-marked (eq (car all-of-them) t))
-	    all-of-them
-	  (nreverse all-of-them))
+    (if (and distinguish-one-marked (eq (car all-of-them) t))
+        all-of-them
+      (nreverse all-of-them))
       (dolist (file all-of-them)
-	(if (funcall filter file)
-	    (push file result)))
+    (if (funcall filter file)
+        (push file result)))
       result)))
 
 ;; The dired command
@@ -3031,8 +3043,13 @@ dired-clean-up-after-deletion
 
 ;; Confirmation
 
-(defun dired-marker-regexp ()
-  (concat "^" (regexp-quote (char-to-string dired-marker-char))))
+(defun dired-marker-regexp (&optional all-marks)
+  "Return a regexp matching `dired-marker-char' at the beginning of line.
+If optional argument ALL-MARKS evaluates to non-nil, the regexp
+matches any mark character."
+  (if all-marks
+      "^[^\t ]"
+    (concat "^" (regexp-quote (char-to-string dired-marker-char)))))
 
 (defun dired-plural-s (count)
   (if (= 1 count) "" "s"))
-- 
2.7.0

From f0f31787a679b468e222740954af49c66626b13c Mon Sep 17 00:00:00 2001
From: Tino Calancha <[email-masked]>
Date: Tue, 8 Mar 2016 14:04:13 +0900
Subject: [PATCH 2/2] ; Add NEWS entry for last commit

---
 ChangeLog.2 |  8 ++++++++
 etc/NEWS    | 11 +++++++++++
 2 files changed, 19 insertions(+)

diff --git a/ChangeLog.2 b/ChangeLog.2
index 6edc654..1ce9bee 100644
--- a/ChangeLog.2
+++ b/ChangeLog.2
@@ -1,3 +1,11 @@
+2016-03-08  Tino Calancha  <[email-masked]>
+
+	Dired operate on all kind of mark characters (Bug#22893).
+	* lisp/dired.el (dired-map-over-marks): Added optional arg 'all-marks'.
+	(dired-marker-regexp): Idem.
+	(dired-get-marked-files): Added two optional args, 'marker-char'
+	and 'all-marks'.
+
 2016-02-15  Glenn Morris  <[email-masked]>
 
 	* lisp/dired-aux.el: Require cl-lib.  (Bug#22613)
diff --git a/etc/NEWS b/etc/NEWS
index cf09350..e385fab 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1471,6 +1471,17 @@ previous commands, `dired-do-search' and
 keys; rebind `A' and `Q' to invoke them if you want the old behavior
 back.  We intend to obsolete the old commands in a future release.
 
+---
+*** Dired operate on all kind of mark characters
+`dired-map-over-marks': New optional arg `all-marks'. When non-nil,
+operate over all marks, not just `dired-marker-char'.
+`dired-marker-regexp': Added optional arg `all-marks'.
+`dired-get-marked-files': Added optional args `marker-char' and `all-marks'.
+If MARKER-CHAR non-nil, then return files marked with such character.
+Otherwise return files marked with `dired-marker-char'.
+If ALL-MARKS non-nil, return all marked files. Otherwise return just those
+files marked with MARKER-CHAR.
+
 ** Tabulated List Mode
 
 +++
-- 
2.7.0