Skip to content

Commit 3b7cb5f

Browse files
committed
* lisp/dired.el (dired-mark-region): New defcustom (bug#39902)
* lisp/dired.el (dired-mark-if): Use dired-mark-region. (dired-mark): Use dired-mark-region. Fix docstring. (dired-mark-files-regexp, dired-mark-files-containing-regexp) (dired-mark-symlinks, dired-mark-directories) (dired-mark-executables, dired-flag-auto-save-files) (dired-flag-backup-files): Mention dired-mark-region in docstring. * lisp/dired-aux.el (dired-compare-directories): * lisp/dired-x.el (dired-mark-unmarked-files, dired-mark-sexp): Mention dired-mark-region in docstring.
1 parent 813478c commit 3b7cb5f

File tree

4 files changed

+106
-18
lines changed

4 files changed

+106
-18
lines changed

etc/NEWS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ shows equivalent key bindings for all commands that have them.
101101

102102
** Dired
103103

104+
*** New option 'dired-mark-region' affects all Dired commands that mark files.
105+
When non-nil and the region is active in Transient Mark mode,
106+
then Dired commands operate only on files in the active region.
107+
The values 'exclusive' and 'inclusive' of this option define
108+
the details of marking the last file at the end of the region.
109+
104110
*** State changing VC operations are supported in dired-mode on files
105111
(but still not on directories).
106112

lisp/dired-aux.el

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,10 @@ Examples of PREDICATE:
205205
(not (and (= (file-attribute-user-id fa1) - mark files with different UID
206206
(file-attribute-user-id fa2))
207207
(= (file-attribute-group-id fa1) - and GID.
208-
(file-attribute-group-id fa2))))"
208+
(file-attribute-group-id fa2))))
209+
210+
If the region is active in Transient Mark mode, mark files
211+
only in the active region if `dired-mark-region' is non-nil."
209212
(interactive
210213
(list
211214
(let* ((target-dir (dired-dwim-target-directory))

lisp/dired-x.el

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,9 @@ interactively, prompt for REGEXP.
623623
With prefix argument, unflag all those files.
624624
Optional fourth argument LOCALP is as in `dired-get-filename'.
625625
Optional fifth argument CASE-FOLD-P specifies the value of
626-
`case-fold-search' used for matching REGEXP."
626+
`case-fold-search' used for matching REGEXP.
627+
If the region is active in Transient Mark mode, operate only on
628+
files in the active region if `dired-mark-region' is non-nil."
627629
(interactive
628630
(list (read-regexp
629631
"Mark unmarked files matching regexp (default all): "
@@ -1386,7 +1388,9 @@ present for some values of `ls-lisp-emulation'.
13861388
13871389
This function operates only on the buffer content and does not
13881390
refer at all to the underlying file system. Contrast this with
1389-
`find-dired', which might be preferable for the task at hand."
1391+
`find-dired', which might be preferable for the task at hand.
1392+
If the region is active in Transient Mark mode, mark files
1393+
only in the active region if `dired-mark-region' is non-nil."
13901394
;; Using sym="" instead of nil avoids the trap of
13911395
;; (string-match "foo" sym) into which a user would soon fall.
13921396
;; Give `equal' instead of `=' in the example, as this works on

lisp/dired.el

Lines changed: 90 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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.")
612640
PREDICATE is evaluated on each line, with point at beginning of line.
613641
MSG is a noun phrase for the type of files being marked.
614642
It 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+
615648
Return 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 %ss%s..."
667+
(message "%s %ss%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.
35843638
Otherwise, with a prefix arg, mark files on the next ARG lines.
35853639
35863640
If 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."
36783737
A 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+
36813743
REGEXP is an Emacs regexp, not a shell wildcard. Thus, use `\\.o$' for
36823744
object 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."
37293791
A 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+
37323797
Note that if a file is visited in an Emacs buffer, and
37333798
`dired-always-read-filesystem' is nil, this command will
37343799
look 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

Comments
 (0)