@@ -296,6 +296,34 @@ new Dired buffers."
296296 :version " 26.1"
297297 :group 'dired )
298298
299+ (defcustom dired-mark-region 'exclusive
300+ " Defines what commands that mark files do with the active region.
301+
302+ When nil, marking commands don't operate on all files in the
303+ active region. They process their prefix arguments as usual.
304+
305+ When the value of this option is non-nil, then all Dired commands
306+ that mark or unmark files will operate on all files in the region
307+ if the region is active in Transient Mark mode.
308+
309+ When `exclusive' , don't mark the file if the end of the region is
310+ before the file name displayed on the Dired line, so the file name
311+ is visually outside the region. This behavior is consistent with
312+ marking files without the region using the key `m' that advances
313+ point to the next line after marking the file. Thus the number
314+ of keys used to mark files is the same as the number of keys
315+ used to select the region, e.g. `M-2 m' marks 2 files, and
316+ `C-SPC M-2 n m' marks 2 files, and `M-2 S-down m' marks 2 files.
317+
318+ When `inclusive' , include the file into marking if the end of the region
319+ is anywhere on its Dired line, except the beginning of the line."
320+ :type '(choice
321+ (const :tag " Don't mark files in active region" nil )
322+ (const :tag " Exclude file name outside of region" exclusive)
323+ (const :tag " Include the file at region end line" inclusive))
324+ :group 'dired
325+ :version " 28.1" )
326+
299327; ; Internal variables
300328
301329(defvar dired-marker-char ?* ; the answer is 42
@@ -612,35 +640,60 @@ Subexpression 2 must end right before the \\n.")
612640PREDICATE is evaluated on each line, with point at beginning of line.
613641MSG is a noun phrase for the type of files being marked.
614642It should end with a noun that can be pluralized by adding `s' .
643+
644+ In Transient Mark mode, if the mark is active, operate on the contents
645+ of the region if `dired-mark-region' is non-nil. Otherwise, operate
646+ on the whole buffer.
647+
615648Return value is the number of files marked, or nil if none were marked."
616- `(let ((inhibit-read-only t ) count)
649+ `(let ((inhibit-read-only t ) count
650+ (beg (if (and dired-mark-region (use-region-p ))
651+ (save-excursion
652+ (goto-char (region-beginning ))
653+ (line-beginning-position ))
654+ (point-min )))
655+ (end (if (and dired-mark-region (use-region-p ))
656+ (save-excursion
657+ (goto-char (region-end ))
658+ (if (if (eq dired-mark-region 'inclusive )
659+ (not (bolp ))
660+ (get-text-property (1- (point )) 'dired-filename ))
661+ (line-end-position )
662+ (line-beginning-position )))
663+ (point-max ))))
617664 (save-excursion
618665 (setq count 0 )
619666 (when , msg
620- (message " %s %s s%s ..."
667+ (message " %s %s s%s%s ..."
621668 (cond ((eq dired-marker-char ?\s ) " Unmarking" )
622669 ((eq dired-del-marker dired-marker-char)
623670 " Flagging" )
624671 (t " Marking" ))
625672 , msg
626673 (if (eq dired-del-marker dired-marker-char)
627674 " for deletion"
628- " " )))
629- (goto-char (point-min ))
630- (while (not (eobp ))
675+ " " )
676+ (if (and dired-mark-region (use-region-p ))
677+ " in region"
678+ " " )))
679+ (goto-char beg)
680+ (while (< (point ) end)
631681 (when , predicate
632682 (unless (= (following-char ) dired-marker-char)
633683 (delete-char 1 )
634684 (insert dired-marker-char)
635685 (setq count (1+ count))))
636686 (forward-line 1 ))
637- (when , msg (message " %s %s%s %s%s "
687+ (when , msg (message " %s %s%s %s%s%s "
638688 count
639689 , msg
640690 (dired-plural-s count)
641691 (if (eq dired-marker-char ?\s ) " un" " " )
642692 (if (eq dired-marker-char dired-del-marker)
643- " flagged" " marked" ))))
693+ " flagged" " marked" )
694+ (if (and dired-mark-region (use-region-p ))
695+ " in region"
696+ " " ))))
644697 (and (> count 0 ) count)))
645698
646699(defmacro dired-map-over-marks (body arg &optional show-progress
@@ -3580,7 +3633,8 @@ no ARGth marked file is found before this line."
35803633
35813634(defun dired-mark (arg &optional interactive )
35823635 " Mark the file at point in the Dired buffer.
3583- If the region is active, mark all files in the region.
3636+ If the region is active in Transient Mark mode, mark all files
3637+ in the region if `dired-mark-region' is non-nil.
35843638Otherwise, with a prefix arg, mark files on the next ARG lines.
35853639
35863640If on a subdir headerline, mark all its files except `.' and `..' .
@@ -3591,13 +3645,18 @@ this subdir."
35913645 (interactive (list current-prefix-arg t ))
35923646 (cond
35933647 ; ; Mark files in the active region.
3594- ((and interactive (use-region-p ))
3648+ ((and dired-mark-region interactive (use-region-p ))
35953649 (save-excursion
35963650 (let ((beg (region-beginning ))
35973651 (end (region-end )))
35983652 (dired-mark-files-in-region
35993653 (progn (goto-char beg) (line-beginning-position ))
3600- (progn (goto-char end) (line-beginning-position ))))))
3654+ (progn (goto-char end)
3655+ (if (if (eq dired-mark-region 'inclusive )
3656+ (not (bolp ))
3657+ (get-text-property (1- (point )) 'dired-filename ))
3658+ (line-end-position )
3659+ (line-beginning-position )))))))
36013660 ; ; Mark subdir files from the subdir headerline.
36023661 ((dired-get-subdir )
36033662 (save-excursion (dired-mark-subdir-files )))
@@ -3678,6 +3737,9 @@ As always, hidden subdirs are not affected."
36783737A prefix argument means to unmark them instead.
36793738`.' and `..' are never marked.
36803739
3740+ If the region is active in Transient Mark mode, mark files
3741+ only in the active region if `dired-mark-region' is non-nil.
3742+
36813743REGEXP is an Emacs regexp, not a shell wildcard. Thus, use `\\.o$' for
36823744object files--just `.o' will mark more than you might think."
36833745 (interactive
@@ -3729,6 +3791,9 @@ object files--just `.o' will mark more than you might think."
37293791A prefix argument means to unmark them instead.
37303792`.' and `..' are never marked.
37313793
3794+ If the region is active in Transient Mark mode, mark files
3795+ only in the active region if `dired-mark-region' is non-nil.
3796+
37323797Note that if a file is visited in an Emacs buffer, and
37333798`dired-always-read-filesystem' is nil, this command will
37343799look in the buffer without revisiting the file, so the results might
@@ -3773,14 +3838,18 @@ The match is against the non-directory part of the filename. Use `^'
37733838
37743839(defun dired-mark-symlinks (unflag-p )
37753840 " Mark all symbolic links.
3776- With prefix argument, unmark or unflag all those files."
3841+ With prefix argument, unmark or unflag all those files.
3842+ If the region is active in Transient Mark mode, mark files
3843+ only in the active region if `dired-mark-region' is non-nil."
37773844 (interactive " P" )
37783845 (let ((dired-marker-char (if unflag-p ?\s dired-marker-char)))
37793846 (dired-mark-if (looking-at-p dired-re-sym) " symbolic link" )))
37803847
37813848(defun dired-mark-directories (unflag-p )
37823849 " Mark all directory file lines except `.' and `..' .
3783- With prefix argument, unmark or unflag all those files."
3850+ With prefix argument, unmark or unflag all those files.
3851+ If the region is active in Transient Mark mode, mark files
3852+ only in the active region if `dired-mark-region' is non-nil."
37843853 (interactive " P" )
37853854 (let ((dired-marker-char (if unflag-p ?\s dired-marker-char)))
37863855 (dired-mark-if (and (looking-at-p dired-re-dir)
@@ -3789,7 +3858,9 @@ With prefix argument, unmark or unflag all those files."
37893858
37903859(defun dired-mark-executables (unflag-p )
37913860 " Mark all executable files.
3792- With prefix argument, unmark or unflag all those files."
3861+ With prefix argument, unmark or unflag all those files.
3862+ If the region is active in Transient Mark mode, mark files
3863+ only in the active region if `dired-mark-region' is non-nil."
37933864 (interactive " P" )
37943865 (let ((dired-marker-char (if unflag-p ?\s dired-marker-char)))
37953866 (dired-mark-if (looking-at-p dired-re-exe) " executable file" )))
@@ -3799,7 +3870,9 @@ With prefix argument, unmark or unflag all those files."
37993870
38003871(defun dired-flag-auto-save-files (&optional unflag-p )
38013872 " Flag for deletion files whose names suggest they are auto save files.
3802- A prefix argument says to unmark or unflag those files instead."
3873+ A prefix argument says to unmark or unflag those files instead.
3874+ If the region is active in Transient Mark mode, flag files
3875+ only in the active region if `dired-mark-region' is non-nil."
38033876 (interactive " P" )
38043877 (let ((dired-marker-char (if unflag-p ?\s dired-del-marker)))
38053878 (dired-mark-if
@@ -3839,7 +3912,9 @@ A prefix argument says to unmark or unflag those files instead."
38393912
38403913(defun dired-flag-backup-files (&optional unflag-p )
38413914 " Flag all backup files (names ending with `~' ) for deletion.
3842- With prefix argument, unmark or unflag these files."
3915+ With prefix argument, unmark or unflag these files.
3916+ If the region is active in Transient Mark mode, flag files
3917+ only in the active region if `dired-mark-region' is non-nil."
38433918 (interactive " P" )
38443919 (let ((dired-marker-char (if unflag-p ?\s dired-del-marker)))
38453920 (dired-mark-if
0 commit comments