diff options
Diffstat (limited to 'lisp/dired-aux.el')
-rw-r--r-- | lisp/dired-aux.el | 339 |
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) |