Function: dired-map-over-marks

dired-map-over-marks is a macro defined in dired.el.gz.

Signature

(dired-map-over-marks BODY ARG &optional SHOW-PROGRESS DISTINGUISH-ONE-MARKED)

Documentation

Eval BODY with point on each marked line. Return a list of BODY's results.

If no marked file could be found and ARG is nil, execute BODY on the current line. If ARG is non-nil, it specifies the files to use instead of the marked files.

  If ARG is an integer, use the next ARG (or previous -ARG, if ARG<0)
  files. In that case, point is dragged along. This is so that
  commands on the next ARG (instead of the marked) files can be
  chained easily.
  If ARG is the symbol marked, use only marked files; if none are
  marked, don't eval BODY and return nil.
  For any other non-nil value of ARG, use the current file.

If optional third arg SHOW-PROGRESS evaluates to non-nil, redisplay the Dired buffer after each file is processed.

No guarantee is made about the position on the marked line. BODY must ensure this itself if it depends on this.

Search starts at the beginning of the buffer, thus the car of the returned list corresponds to the line nearest to the buffer's bottom. This is also true for (positive and negative) integer values of ARG.

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 BODY-RESULT) instead of (BODY-RESULT), where BODY-RESULT is the result of evaluating BODY with point on the single marked file's line.

Source Code

;; Defined in /usr/src/emacs/lisp/dired.el.gz
(defmacro dired-map-over-marks (body arg &optional show-progress
				     distinguish-one-marked)
  "Eval BODY with point on each marked line.  Return a list of BODY's results.
If no marked file could be found and ARG is nil, execute BODY on the current
line.  If ARG is non-nil, it specifies the files to use instead of the
marked files.

  If ARG is an integer, use the next ARG (or previous -ARG, if ARG<0)
  files.  In that case, point is dragged along.  This is so that
  commands on the next ARG (instead of the marked) files can be
  chained easily.
  If ARG is the symbol `marked', use only marked files; if none are
  marked, don't eval BODY and return nil.
  For any other non-nil value of ARG, use the current file.

If optional third arg SHOW-PROGRESS evaluates to non-nil,
redisplay the Dired buffer after each file is processed.

No guarantee is made about the position on the marked line.
BODY must ensure this itself if it depends on this.

Search starts at the beginning of the buffer, thus the car of the
returned list corresponds to the line nearest to the buffer's bottom.
This is also true for (positive and negative) integer values of
ARG.

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 BODY-RESULT) instead of (BODY-RESULT),
where BODY-RESULT is the result of evaluating BODY with point
on the single marked file's line."
  ;;
  ;;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
       (inhibit-auto-revert
         (let ((inhibit-read-only t)
               case-fold-search found results)
	   (if (and ,arg (not (eq ,arg 'marked)))
	       (if (integerp ,arg)
		   (progn	;; no save-excursion, want to move point.
		     (dired-repeat-over-lines
		      ,arg
		      (lambda ()
                        (if ,show-progress (sit-for 0))
                        (setq results (cons ,body results))))
		     (when (< ,arg 0)
		       (setq results (nreverse results)))
		     results)
                 ;; non-nil, non-integer, non-marked 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
                 (unless (eq ,arg 'marked)
                   (list ,body)))))))
     ;; save-excursion loses, again
     (dired-move-to-filename)))