From e2040516b2949ba3f626448463f10baeb178d57c Mon Sep 17 00:00:00 2001 From: Tino Calancha 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