summaryrefslogtreecommitdiff
path: root/lisp/dired-aux.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/dired-aux.el')
-rw-r--r--lisp/dired-aux.el339
1 files changed, 195 insertions, 144 deletions
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index a9443482d63..b81c0d1a4f5 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -148,7 +148,7 @@ the string of command switches used as the third argument of `diff'."
(read-string "Options for diff: "
(if (stringp diff-switches)
diff-switches
- (mapconcat 'identity diff-switches " ")))))))
+ (mapconcat #'identity diff-switches " ")))))))
(let ((current (dired-get-filename t)))
(when (or (equal (expand-file-name file)
(expand-file-name current))
@@ -173,7 +173,7 @@ With prefix arg, prompt for argument SWITCHES which is options for `diff'."
(list (read-string "Options for diff: "
(if (stringp diff-switches)
diff-switches
- (mapconcat 'identity diff-switches " "))))
+ (mapconcat #'identity diff-switches " "))))
nil))
(diff-backup (dired-get-filename) switches))
@@ -200,9 +200,12 @@ Examples of PREDICATE:
(> mtime1 mtime2) - mark newer files
(not (= size1 size2)) - mark files with different sizes
- (not (string= (nth 8 fa1) (nth 8 fa2))) - mark files with different modes
- (not (and (= (nth 2 fa1) (nth 2 fa2)) - mark files with different UID
- (= (nth 3 fa1) (nth 3 fa2)))) and GID."
+ (not (string= (file-attribute-modes fa1) - mark files with different modes
+ (file-attribute-modes fa2)))
+ (not (and (= (file-attribute-user-id fa1) - mark files with different UID
+ (file-attribute-user-id fa2))
+ (= (file-attribute-group-id fa1) - and GID.
+ (file-attribute-group-id fa2))))"
(interactive
(list
(let* ((target-dir (dired-dwim-target-directory))
@@ -224,12 +227,12 @@ Examples of PREDICATE:
(setq file-alist2 (delq (assoc "." file-alist2) file-alist2))
(setq file-alist2 (delq (assoc ".." file-alist2) file-alist2))
(setq file-list1 (mapcar
- 'cadr
+ #'cadr
(dired-file-set-difference
file-alist1 file-alist2
predicate))
file-list2 (mapcar
- 'cadr
+ #'cadr
(dired-file-set-difference
file-alist2 file-alist1
predicate)))
@@ -269,12 +272,12 @@ condition. Two file items are considered to match if they are equal
(eval predicate
`((fa1 . ,fa1)
(fa2 . ,fa2)
- (size1 . ,(nth 7 fa1))
- (size2 . ,(nth 7 fa2))
+ (size1 . ,(file-attribute-size fa1))
+ (size2 . ,(file-attribute-size fa2))
(mtime1
- . ,(float-time (nth 5 fa1)))
+ . ,(float-time (file-attribute-modification-time fa1)))
(mtime2
- . ,(float-time (nth 5 fa2)))
+ . ,(float-time (file-attribute-modification-time fa2)))
)))))
(setq list (cdr list)))
list)
@@ -301,18 +304,21 @@ List has a form of (file-name full-file-name (attribute-list))."
;; PROGRAM is the program used to change the attribute.
;; OP-SYMBOL is the type of operation (for use in `dired-mark-pop-up').
;; ARG describes which files to use, as in `dired-get-marked-files'.
- (let* ((files (dired-get-marked-files t arg))
+ (let* ((files (dired-get-marked-files t arg nil nil t))
;; The source of default file attributes is the file at point.
(default-file (dired-get-filename t t))
(default (when default-file
(cond ((eq op-symbol 'touch)
(format-time-string
"%Y%m%d%H%M.%S"
- (nth 5 (file-attributes default-file))))
+ (file-attribute-modification-time
+ (file-attributes default-file))))
((eq op-symbol 'chown)
- (nth 2 (file-attributes default-file 'string)))
+ (file-attribute-user-id
+ (file-attributes default-file 'string)))
((eq op-symbol 'chgrp)
- (nth 3 (file-attributes default-file 'string))))))
+ (file-attribute-group-id
+ (file-attributes default-file 'string))))))
(prompt (concat "Change " attribute-name " of %s to"
(if (eq op-symbol 'touch)
" (default now): "
@@ -361,11 +367,11 @@ Symbolic modes like `g+w' are allowed.
Type M-n to pull the file attributes of the file at point
into the minibuffer."
(interactive "P")
- (let* ((files (dired-get-marked-files t arg))
+ (let* ((files (dired-get-marked-files t arg nil nil t))
;; The source of default file attributes is the file at point.
(default-file (dired-get-filename t t))
(modestr (when default-file
- (nth 8 (file-attributes default-file))))
+ (file-attribute-modes (file-attributes default-file))))
(default
(and (stringp modestr)
(string-match "^.\\(...\\)\\(...\\)\\(...\\)$" modestr)
@@ -476,7 +482,7 @@ Uses the shell command coming from variables `lpr-command' and
`lpr-switches' as default."
(interactive "P")
(require 'lpr)
- (let* ((file-list (dired-get-marked-files t arg))
+ (let* ((file-list (dired-get-marked-files t arg nil nil t))
(lpr-switches
(if (and (stringp printer-name)
(string< "" printer-name))
@@ -485,7 +491,7 @@ Uses the shell command coming from variables `lpr-command' and
lpr-switches))
(command (dired-mark-read-string
"Print %s with: "
- (mapconcat 'identity
+ (mapconcat #'identity
(cons lpr-command
(if (stringp lpr-switches)
(list lpr-switches)
@@ -591,7 +597,7 @@ with a prefix argument."
(possibilities (file-name-all-completions
base-versions
(file-name-directory fn)))
- (versions (mapcar 'backup-extract-version possibilities)))
+ (versions (mapcar #'backup-extract-version possibilities)))
(if versions
(setq dired-file-version-alist
(cons (cons fn versions)
@@ -668,7 +674,7 @@ In shell syntax this means separating the individual commands with `;'.
The output appears in the buffer `*Async Shell Command*'."
(interactive
- (let ((files (dired-get-marked-files t current-prefix-arg)))
+ (let ((files (dired-get-marked-files t current-prefix-arg nil nil t)))
(list
;; Want to give feedback whether this file or marked files are used:
(dired-read-shell-command "& on %s: " current-prefix-arg files)
@@ -729,7 +735,7 @@ can be produced by `dired-get-marked-files', for example."
;;Functions dired-run-shell-command and dired-shell-stuff-it do the
;;actual work and can be redefined for customization.
(interactive
- (let ((files (dired-get-marked-files t current-prefix-arg)))
+ (let ((files (dired-get-marked-files t current-prefix-arg nil nil t)))
(list
;; Want to give feedback whether this file or marked files are used:
(dired-read-shell-command "! on %s: " current-prefix-arg files)
@@ -816,27 +822,28 @@ can be produced by `dired-get-marked-files', for example."
retval))
(lambda (x) (concat cmd-prefix command dired-mark-separator x)))))
(concat
- (cond (on-each
- (format "%s%s"
- (mapconcat stuff-it (mapcar 'shell-quote-argument file-list)
- cmd-sep)
- ;; POSIX shells running a list of commands in the background
- ;; (LIST = cmd_1 & [cmd_2 & ... cmd_i & ... cmd_N &])
- ;; return once cmd_N ends, i.e., the shell does not
- ;; wait for cmd_i to finish before executing cmd_i+1.
- ;; That means, running (shell-command LIST) may not show
- ;; the output of all the commands (Bug#23206).
- ;; Add 'wait' to force those POSIX shells to wait until
- ;; all commands finish.
- (or (and parallel-in-background (not w32-shell)
- "&wait")
- "")))
- (t
- (let ((files (mapconcat 'shell-quote-argument
- file-list dired-mark-separator)))
- (when (cdr file-list)
- (setq files (concat dired-mark-prefix files dired-mark-postfix)))
- (funcall stuff-it files))))
+ (cond
+ (on-each
+ (format "%s%s"
+ (mapconcat stuff-it (mapcar #'shell-quote-argument file-list)
+ cmd-sep)
+ ;; POSIX shells running a list of commands in the background
+ ;; (LIST = cmd_1 & [cmd_2 & ... cmd_i & ... cmd_N &])
+ ;; return once cmd_N ends, i.e., the shell does not
+ ;; wait for cmd_i to finish before executing cmd_i+1.
+ ;; That means, running (shell-command LIST) may not show
+ ;; the output of all the commands (Bug#23206).
+ ;; Add 'wait' to force those POSIX shells to wait until
+ ;; all commands finish.
+ (or (and parallel-in-background (not w32-shell)
+ "&wait")
+ "")))
+ (t
+ (let ((files (mapconcat #'shell-quote-argument
+ file-list dired-mark-separator)))
+ (when (cdr file-list)
+ (setq files (concat dired-mark-prefix files dired-mark-postfix)))
+ (funcall stuff-it files))))
(or (and in-background "&") ""))))
;; This is an extra function so that it can be redefined by ange-ftp.
@@ -866,7 +873,7 @@ Else returns nil for success."
(set-buffer err-buffer)
(erase-buffer)
(setq default-directory dir ; caller's default-directory
- err (not (eq 0 (apply 'process-file program nil t nil arguments))))
+ err (not (eq 0 (apply #'process-file program nil t nil arguments))))
(if err
(progn
(dired-log (concat program " " (prin1-to-string arguments) "\n"))
@@ -1033,7 +1040,7 @@ Prompt for the archive file name.
Choose the archiving command based on the archive file-name extension
and `dired-compress-files-alist'."
(interactive)
- (let* ((in-files (dired-get-marked-files))
+ (let* ((in-files (dired-get-marked-files nil nil nil nil t))
(out-file (expand-file-name (read-file-name "Compress to: ")))
(rule (cl-find-if
(lambda (x)
@@ -1156,7 +1163,7 @@ Return nil if no change in files."
;; Pass t for DISTINGUISH-ONE-MARKED so that a single file which
;; is marked pops up a window. That will help the user see
;; it isn't the current line file.
- (let ((files (dired-get-marked-files t arg nil t))
+ (let ((files (dired-get-marked-files t arg nil t t))
(string (if (eq op-symbol 'compress) "Compress or uncompress"
(capitalize (symbol-name op-symbol)))))
(dired-mark-pop-up nil op-symbol files #'y-or-n-p
@@ -1343,7 +1350,7 @@ See Info node `(emacs)Subdir switches' for more details."
;; Replace space by old marker without moving point.
;; Faster than goto+insdel inside a save-excursion?
(when char
- (subst-char-in-region opoint (1+ opoint) ?\040 char)))))
+ (subst-char-in-region opoint (1+ opoint) ?\s char)))))
(dired-move-to-filename))
;;;###autoload
@@ -1397,8 +1404,8 @@ files matching `dired-omit-regexp'."
(catch 'not-found
(if (string= directory cur-dir)
(progn
- (skip-chars-forward "^\r\n")
- (if (eq (following-char) ?\r)
+ (end-of-line)
+ (if (dired--hidden-p)
(dired-unhide-subdir))
;; We are already where we should be, except when
;; point is before the subdir line or its total line.
@@ -1408,7 +1415,7 @@ files matching `dired-omit-regexp'."
;; else try to find correct place to insert
(if (dired-goto-subdir directory)
(progn ;; unhide if necessary
- (if (= (following-char) ?\r)
+ (if (dired--hidden-p)
;; Point is at end of subdir line.
(dired-unhide-subdir))
;; found - skip subdir and `total' line
@@ -1517,7 +1524,7 @@ files matching `dired-omit-regexp'."
(point))
(line-beginning-position 2)))
(setq file (directory-file-name file))
- (dired-add-entry file (if (eq ?\040 marker) nil marker)))))
+ (dired-add-entry file (if (eq ?\s marker) nil marker)))))
;;; Copy, move/rename, making hard and symbolic links
@@ -1557,22 +1564,41 @@ Special value `always' suppresses confirmation."
(declare-function make-symbolic-link "fileio.c")
+(defcustom dired-create-destination-dirs nil
+ "Whether Dired should create destination dirs when copying/removing files.
+If nil, don't create them.
+If `always', create them without asking.
+If `ask', ask for user confirmation."
+ :type '(choice (const :tag "Never create non-existent dirs" nil)
+ (const :tag "Always create non-existent dirs" always)
+ (const :tag "Ask for user confirmation" ask))
+ :group 'dired
+ :version "27.1")
+
+(defun dired-maybe-create-dirs (dir)
+ "Create DIR if doesn't exist according to `dired-create-destination-dirs'."
+ (when (and dired-create-destination-dirs (not (file-exists-p dir)))
+ (if (or (eq dired-create-destination-dirs 'always)
+ (yes-or-no-p (format "Create destination dir `%s'? " dir)))
+ (dired-create-directory dir))))
+
(defun dired-copy-file-recursive (from to ok-flag &optional
preserve-time top recursive)
- (when (and (eq t (car (file-attributes from)))
+ (when (and (eq t (file-attribute-type (file-attributes from)))
(file-in-directory-p to from))
(error "Cannot copy `%s' into its subdirectory `%s'" from to))
(let ((attrs (file-attributes from)))
(if (and recursive
- (eq t (car attrs))
+ (eq t (file-attribute-type attrs))
(or (eq recursive 'always)
(yes-or-no-p (format "Recursive copies of %s? " from))))
(copy-directory from to preserve-time)
(or top (dired-handle-overwrite to))
(condition-case err
- (if (stringp (car attrs))
+ (if (stringp (file-attribute-type attrs))
;; It is a symlink
- (make-symbolic-link (car attrs) to ok-flag)
+ (make-symbolic-link (file-attribute-type attrs) to ok-flag)
+ (dired-maybe-create-dirs (file-name-directory to))
(copy-file from to ok-flag preserve-time))
(file-date-error
(push (dired-make-relative from)
@@ -1582,6 +1608,7 @@ Special value `always' suppresses confirmation."
;;;###autoload
(defun dired-rename-file (file newname ok-if-already-exists)
(dired-handle-overwrite newname)
+ (dired-maybe-create-dirs (file-name-directory newname))
(rename-file file newname ok-if-already-exists) ; error is caught in -create-files
;; Silently rename the visited file of any buffer visiting this file.
(and (get-file-buffer file)
@@ -1751,7 +1778,7 @@ ESC or `q' to not overwrite any of the remaining files,
(setq to destname))
;; If DESTNAME is a subdirectory of FROM, not a symlink,
;; and the method in use is copying, signal an error.
- (and (eq t (car (file-attributes destname)))
+ (and (eq t (file-attribute-type (file-attributes destname)))
(eq file-creator 'dired-copy-file)
(file-in-directory-p destname from)
(error "Cannot copy `%s' into its subdirectory `%s'"
@@ -1834,7 +1861,7 @@ Optional arg HOW-TO determines how to treat the target.
arguments for the function that is the first element of the list.
For any other return value, TARGET is treated as a directory."
(or op1 (setq op1 operation))
- (let* ((fn-list (dired-get-marked-files nil arg))
+ (let* ((fn-list (dired-get-marked-files nil arg nil nil t))
(rfn-list (mapcar #'dired-make-relative fn-list))
(dired-one-file ; fluid variable inside dired-create-files
(and (consp fn-list) (null (cdr fn-list)) (car fn-list)))
@@ -1852,28 +1879,31 @@ Optional arg HOW-TO determines how to treat the target.
(dired-mark-read-file-name
(concat (if dired-one-file op1 operation) " %s to: ")
target-dir op-symbol arg rfn-list default))))
- (into-dir (cond ((null how-to)
- ;; Allow users to change the letter case of
- ;; a directory on a case-insensitive
- ;; filesystem. If we don't test these
- ;; conditions up front, file-directory-p
- ;; below will return t on a case-insensitive
- ;; filesystem, and Emacs will try to move
- ;; foo -> foo/foo, which fails.
- (if (and (file-name-case-insensitive-p (car fn-list))
- (eq op-symbol 'move)
- dired-one-file
- (string= (downcase
- (expand-file-name (car fn-list)))
- (downcase
- (expand-file-name target)))
- (not (string=
- (file-name-nondirectory (car fn-list))
- (file-name-nondirectory target))))
- nil
- (file-directory-p target)))
- ((eq how-to t) nil)
- (t (funcall how-to target)))))
+ (into-dir
+ (progn
+ (unless dired-one-file (dired-maybe-create-dirs target))
+ (cond ((null how-to)
+ ;; Allow users to change the letter case of
+ ;; a directory on a case-insensitive
+ ;; filesystem. If we don't test these
+ ;; conditions up front, file-directory-p
+ ;; below will return t on a case-insensitive
+ ;; filesystem, and Emacs will try to move
+ ;; foo -> foo/foo, which fails.
+ (if (and (file-name-case-insensitive-p (car fn-list))
+ (eq op-symbol 'move)
+ dired-one-file
+ (string= (downcase
+ (expand-file-name (car fn-list)))
+ (downcase
+ (expand-file-name target)))
+ (not (string=
+ (file-name-nondirectory (car fn-list))
+ (file-name-nondirectory target))))
+ nil
+ (file-directory-p target)))
+ ((eq how-to t) nil)
+ (t (funcall how-to target))))))
(if (and (consp into-dir) (functionp (car into-dir)))
(apply (car into-dir) operation rfn-list fn-list target (cdr into-dir))
(if (not (or dired-one-file into-dir))
@@ -1972,6 +2002,19 @@ Optional arg HOW-TO determines how to treat the target.
dired-dirs)))
+
+;; We use this function in `dired-create-directory' and
+;; `dired-create-empty-file'; the return value is the new entry
+;; in the updated Dired buffer.
+(defun dired--find-topmost-parent-dir (filename)
+ "Return the topmost nonexistent parent dir of FILENAME.
+FILENAME is a full file name."
+ (let ((try filename) new)
+ (while (and try (not (file-exists-p try)) (not (equal new try)))
+ (setq new try
+ try (directory-file-name (file-name-directory try))))
+ new))
+
;;;###autoload
(defun dired-create-directory (directory)
"Create a directory called DIRECTORY.
@@ -1980,18 +2023,32 @@ If DIRECTORY already exists, signal an error."
(interactive
(list (read-file-name "Create directory: " (dired-current-directory))))
(let* ((expanded (directory-file-name (expand-file-name directory)))
- (try expanded) new)
+ new)
(if (file-exists-p expanded)
(error "Cannot create directory %s: file exists" expanded))
- ;; Find the topmost nonexistent parent dir (variable `new')
- (while (and try (not (file-exists-p try)) (not (equal new try)))
- (setq new try
- try (directory-file-name (file-name-directory try))))
+ (setq new (dired--find-topmost-parent-dir expanded))
(make-directory expanded t)
(when new
(dired-add-file new)
(dired-move-to-filename))))
+;;;###autoload
+(defun dired-create-empty-file (file)
+ "Create an empty file called FILE.
+ Add a new entry for the new file in the Dired buffer.
+ Parent directories of FILE are created as needed.
+ If FILE already exists, signal an error."
+ (interactive (list (read-file-name "Create empty file: ")))
+ (let* ((expanded (expand-file-name file))
+ new)
+ (if (file-exists-p expanded)
+ (error "Cannot create file %s: file exists" expanded))
+ (setq new (dired--find-topmost-parent-dir expanded))
+ (make-empty-file file 'parents)
+ (when new
+ (dired-add-file new)
+ (dired-move-to-filename))))
+
(defun dired-into-dir-with-symlinks (target)
(and (file-directory-p target)
(not (file-symlink-p target))))
@@ -2506,7 +2563,7 @@ Optional third arg LIMIT (>= 1) is a limit to the length of the
resulting list.
Thus, if SEP is a regexp that only matches itself,
- (mapconcat 'identity (dired-split SEP STRING) SEP)
+ (mapconcat #'identity (dired-split SEP STRING) SEP)
is always equal to STRING."
(let* ((start (string-match pat str))
@@ -2554,7 +2611,7 @@ When called interactively and not on a subdir line, go to this subdir's line."
(defun dired-goto-subdir (dir)
"Go to end of header line of DIR in this dired buffer.
Return value of point on success, otherwise return nil.
-The next char is either \\n, or \\r if DIR is hidden."
+The next char is \\n."
(interactive
(prog1 ; let push-mark display its message
(list (expand-file-name
@@ -2569,8 +2626,8 @@ The next char is either \\n, or \\r if DIR is hidden."
(and elt
(goto-char (dired-get-subdir-min elt))
;; dired-subdir-hidden-p and dired-add-entry depend on point being
- ;; at either \r or \n after this function succeeds.
- (progn (skip-chars-forward "^\r\n")
+ ;; at \n after this function succeeds.
+ (progn (end-of-line)
(point)))))
;;;###autoload
@@ -2643,18 +2700,13 @@ Lower levels are unaffected."
;;; hiding
(defun dired-unhide-subdir ()
- (let (buffer-read-only)
- (subst-char-in-region (dired-subdir-min) (dired-subdir-max) ?\r ?\n)))
-
-(defun dired-hide-check ()
- (or selective-display
- (error "selective-display must be t for subdir hiding to work!")))
+ (with-silent-modifications
+ (dired--unhide (dired-subdir-min) (dired-subdir-max))))
(defun dired-subdir-hidden-p (dir)
- (and selective-display
- (save-excursion
- (dired-goto-subdir dir)
- (= (following-char) ?\r))))
+ (save-excursion
+ (dired-goto-subdir dir)
+ (dired--hidden-p)))
;;;###autoload
(defun dired-hide-subdir (arg)
@@ -2662,8 +2714,7 @@ Lower levels are unaffected."
Optional prefix arg is a repeat factor.
Use \\[dired-hide-all] to (un)hide all directories."
(interactive "p")
- (dired-hide-check)
- (let ((modflag (buffer-modified-p)))
+ (with-silent-modifications
(while (>= (setq arg (1- arg)) 0)
(let* ((cur-dir (dired-current-directory))
(hidden-p (dired-subdir-hidden-p cur-dir))
@@ -2672,12 +2723,11 @@ Use \\[dired-hide-all] to (un)hide all directories."
buffer-read-only)
;; keep header line visible, hide rest
(goto-char (dired-get-subdir-min elt))
- (skip-chars-forward "^\n\r")
+ (end-of-line)
(if hidden-p
- (subst-char-in-region (point) end-pos ?\r ?\n)
- (subst-char-in-region (point) end-pos ?\n ?\r)))
- (dired-next-subdir 1 t))
- (restore-buffer-modified-p modflag)))
+ (dired--unhide (point) end-pos)
+ (dired--hide (point) end-pos)))
+ (dired-next-subdir 1 t))))
;;;###autoload
(defun dired-hide-all (&optional ignored)
@@ -2685,28 +2735,20 @@ Use \\[dired-hide-all] to (un)hide all directories."
If there is already something hidden, make everything visible again.
Use \\[dired-hide-subdir] to (un)hide a particular subdirectory."
(interactive "P")
- (dired-hide-check)
- (let ((modflag (buffer-modified-p))
- buffer-read-only)
- (if (save-excursion
- (goto-char (point-min))
- (search-forward "\r" nil t))
- ;; unhide - bombs on \r in filenames
- (subst-char-in-region (point-min) (point-max) ?\r ?\n)
+ (with-silent-modifications
+ (if (text-property-any (point-min) (point-max) 'invisible 'dired)
+ (dired--unhide (point-min) (point-max))
;; hide
- (let ((pos (point-max)) ; pos of end of last directory
- (alist dired-subdir-alist))
- (while alist ; while there are dirs before pos
- (subst-char-in-region (dired-get-subdir-min (car alist)) ; pos of prev dir
- (save-excursion
- (goto-char pos) ; current dir
- ;; we're somewhere on current dir's line
- (forward-line -1)
- (point))
- ?\n ?\r)
- (setq pos (dired-get-subdir-min (car alist))) ; prev dir gets current dir
- (setq alist (cdr alist)))))
- (restore-buffer-modified-p modflag)))
+ (let ((pos (point-max))) ; pos of end of last directory
+ (dolist (subdir dired-subdir-alist)
+ (let ((start (dired-get-subdir-min subdir)) ; pos of prev dir
+ (end (save-excursion
+ (goto-char pos) ; current dir
+ ;; we're somewhere on current dir's line
+ (forward-line -1)
+ (point))))
+ (dired--hide start end))
+ (setq pos (dired-get-subdir-min subdir))))))) ; prev dir gets current dir
;;;###end dired-ins.el
@@ -2732,8 +2774,8 @@ When off, it uses the original predicate."
nil nil nil
(if dired-isearch-filenames-mode
(add-function :before-while (local 'isearch-filter-predicate)
- #'dired-isearch-filter-filenames
- '((isearch-message-prefix . "filename ")))
+ #'dired-isearch-filter-filenames
+ '((isearch-message-prefix . "filename ")))
(remove-function (local 'isearch-filter-predicate)
#'dired-isearch-filter-filenames))
(when isearch-mode
@@ -2749,13 +2791,15 @@ Intended to be added to `isearch-mode-hook'."
(get-text-property (point) 'dired-filename)))
(define-key isearch-mode-map "\M-sff" 'dired-isearch-filenames-mode)
(dired-isearch-filenames-mode 1)
- (add-hook 'isearch-mode-end-hook 'dired-isearch-filenames-end nil t)))
+ (add-hook 'isearch-mode-end-hook #'dired-isearch-filenames-end nil t)))
(defun dired-isearch-filenames-end ()
"Clean up the Dired file name search after terminating isearch."
(define-key isearch-mode-map "\M-sff" nil)
(dired-isearch-filenames-mode -1)
- (remove-hook 'isearch-mode-end-hook 'dired-isearch-filenames-end t))
+ (remove-hook 'isearch-mode-end-hook #'dired-isearch-filenames-end t)
+ (unless isearch-suspended
+ (custom-reevaluate-setting 'dired-isearch-filenames)))
(defun dired-isearch-filter-filenames (beg end)
"Test whether some part of the current search match is inside a file name.
@@ -2768,15 +2812,15 @@ is part of a file name (i.e., has the text property `dired-filename')."
(defun dired-isearch-filenames ()
"Search for a string using Isearch only in file names in the Dired buffer."
(interactive)
- (let ((dired-isearch-filenames t))
- (isearch-forward nil t)))
+ (setq dired-isearch-filenames t)
+ (isearch-forward nil t))
;;;###autoload
(defun dired-isearch-filenames-regexp ()
"Search for a regexp using Isearch only in file names in the Dired buffer."
(interactive)
- (let ((dired-isearch-filenames t))
- (isearch-forward-regexp nil t)))
+ (setq dired-isearch-filenames t)
+ (isearch-forward-regexp nil t))
;; Functions for searching in tags style among marked files.
@@ -2786,14 +2830,14 @@ is part of a file name (i.e., has the text property `dired-filename')."
"Search for a string through all marked files using Isearch."
(interactive)
(multi-isearch-files
- (dired-get-marked-files nil nil 'dired-nondirectory-p)))
+ (dired-get-marked-files nil nil #'dired-nondirectory-p nil t)))
;;;###autoload
(defun dired-do-isearch-regexp ()
"Search for a regexp through all marked files using Isearch."
(interactive)
(multi-isearch-files-regexp
- (dired-get-marked-files nil nil 'dired-nondirectory-p)))
+ (dired-get-marked-files nil nil 'dired-nondirectory-p nil t)))
;;;###autoload
(defun dired-do-search (regexp)
@@ -2801,7 +2845,11 @@ is part of a file name (i.e., has the text property `dired-filename')."
Stops when a match is found.
To continue searching for next match, use command \\[tags-loop-continue]."
(interactive "sSearch marked files (regexp): ")
- (tags-search regexp '(dired-get-marked-files nil nil 'dired-nondirectory-p)))
+ (fileloop-initialize-search
+ regexp
+ (dired-get-marked-files nil nil #'dired-nondirectory-p)
+ 'default)
+ (fileloop-continue))
;;;###autoload
(defun dired-do-query-replace-regexp (from to &optional delimited)
@@ -2814,13 +2862,16 @@ with the command \\[tags-loop-continue]."
(query-replace-read-args
"Query replace regexp in marked files" t t)))
(list (nth 0 common) (nth 1 common) (nth 2 common))))
- (dolist (file (dired-get-marked-files nil nil 'dired-nondirectory-p))
+ (dolist (file (dired-get-marked-files nil nil #'dired-nondirectory-p nil t))
(let ((buffer (get-file-buffer file)))
(if (and buffer (with-current-buffer buffer
buffer-read-only))
(error "File `%s' is visited read-only" file))))
- (tags-query-replace from to delimited
- '(dired-get-marked-files nil nil 'dired-nondirectory-p)))
+ (fileloop-initialize-replace
+ from to (dired-get-marked-files nil nil #'dired-nondirectory-p)
+ (if (equal from (downcase from)) nil 'default)
+ delimited)
+ (fileloop-continue))
(declare-function xref--show-xrefs "xref")
(declare-function xref-query-replace-in-results "xref")
@@ -2837,11 +2888,11 @@ REGEXP should use constructs supported by your local `grep' command."
(interactive "sSearch marked files (regexp): ")
(require 'grep)
(defvar grep-find-ignored-files)
- (defvar grep-find-ignored-directories)
- (let* ((files (dired-get-marked-files))
+ (declare-function rgrep-find-ignored-directories "grep" (dir))
+ (let* ((files (dired-get-marked-files nil nil nil nil t))
(ignores (nconc (mapcar
- (lambda (s) (concat s "/"))
- grep-find-ignored-directories)
+ #'file-name-as-directory
+ (rgrep-find-ignored-directories default-directory))
grep-find-ignored-files))
(xrefs (mapcan
(lambda (file)