aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorStefan Monnier2019-03-17 13:35:20 -0400
committerStefan Monnier2019-03-17 13:35:20 -0400
commit5055e14dda041f4a4985d3663f19fa8ccb37cad6 (patch)
tree282e553df14bc3914a7d24fb42bd57eee31b2d2d /lisp
parent2f50a990b756a0b3477455e28abc0dbd8d33a27e (diff)
downloademacs-5055e14dda041f4a4985d3663f19fa8ccb37cad6.tar.gz
emacs-5055e14dda041f4a4985d3663f19fa8ccb37cad6.zip
Dired: Use invisibility-spec instead of selective-display
* lisp/dired.el (dired-subdir-regexp): No need to pay attention to \r. (dired-remember-hidden): Use pcase-dolist and dired--hidden-p. (dired-mode): Set invisibility-spec instead of selective-display. (dired--hidden-p, dired--hide, dired--unhide, dired--find-hidden-pos): New functions. (dired-move-to-end-of-filename): Use dired--hidden-p. (dired-next-subdir): No need to pay attention to \r. (dired-fun-in-all-buffers): Use push. * lisp/dired-aux.el (dired-unhide-subdir, dired-hide-subdir, dired-hide-all): Use the new functions and with-silent-modifications. (dired-add-entry): Use dired--hidden-p. (dired-goto-subdir): No need to pay attention to \r. (dired-hide-check): Remove. (dired-subdir-hidden-p): Use dired--hidden-p. (dired-do-find-regexp): Use file-name-as-directory.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/dired-aux.el146
-rw-r--r--lisp/dired.el122
2 files changed, 139 insertions, 129 deletions
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 4be93c32207..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'."
148 (read-string "Options for diff: " 148 (read-string "Options for diff: "
149 (if (stringp diff-switches) 149 (if (stringp diff-switches)
150 diff-switches 150 diff-switches
151 (mapconcat 'identity diff-switches " "))))))) 151 (mapconcat #'identity diff-switches " ")))))))
152 (let ((current (dired-get-filename t))) 152 (let ((current (dired-get-filename t)))
153 (when (or (equal (expand-file-name file) 153 (when (or (equal (expand-file-name file)
154 (expand-file-name current)) 154 (expand-file-name current))
@@ -173,7 +173,7 @@ With prefix arg, prompt for argument SWITCHES which is options for `diff'."
173 (list (read-string "Options for diff: " 173 (list (read-string "Options for diff: "
174 (if (stringp diff-switches) 174 (if (stringp diff-switches)
175 diff-switches 175 diff-switches
176 (mapconcat 'identity diff-switches " ")))) 176 (mapconcat #'identity diff-switches " "))))
177 nil)) 177 nil))
178 (diff-backup (dired-get-filename) switches)) 178 (diff-backup (dired-get-filename) switches))
179 179
@@ -227,12 +227,12 @@ Examples of PREDICATE:
227 (setq file-alist2 (delq (assoc "." file-alist2) file-alist2)) 227 (setq file-alist2 (delq (assoc "." file-alist2) file-alist2))
228 (setq file-alist2 (delq (assoc ".." file-alist2) file-alist2)) 228 (setq file-alist2 (delq (assoc ".." file-alist2) file-alist2))
229 (setq file-list1 (mapcar 229 (setq file-list1 (mapcar
230 'cadr 230 #'cadr
231 (dired-file-set-difference 231 (dired-file-set-difference
232 file-alist1 file-alist2 232 file-alist1 file-alist2
233 predicate)) 233 predicate))
234 file-list2 (mapcar 234 file-list2 (mapcar
235 'cadr 235 #'cadr
236 (dired-file-set-difference 236 (dired-file-set-difference
237 file-alist2 file-alist1 237 file-alist2 file-alist1
238 predicate))) 238 predicate)))
@@ -491,7 +491,7 @@ Uses the shell command coming from variables `lpr-command' and
491 lpr-switches)) 491 lpr-switches))
492 (command (dired-mark-read-string 492 (command (dired-mark-read-string
493 "Print %s with: " 493 "Print %s with: "
494 (mapconcat 'identity 494 (mapconcat #'identity
495 (cons lpr-command 495 (cons lpr-command
496 (if (stringp lpr-switches) 496 (if (stringp lpr-switches)
497 (list lpr-switches) 497 (list lpr-switches)
@@ -597,7 +597,7 @@ with a prefix argument."
597 (possibilities (file-name-all-completions 597 (possibilities (file-name-all-completions
598 base-versions 598 base-versions
599 (file-name-directory fn))) 599 (file-name-directory fn)))
600 (versions (mapcar 'backup-extract-version possibilities))) 600 (versions (mapcar #'backup-extract-version possibilities)))
601 (if versions 601 (if versions
602 (setq dired-file-version-alist 602 (setq dired-file-version-alist
603 (cons (cons fn versions) 603 (cons (cons fn versions)
@@ -822,27 +822,28 @@ can be produced by `dired-get-marked-files', for example."
822 retval)) 822 retval))
823 (lambda (x) (concat cmd-prefix command dired-mark-separator x))))) 823 (lambda (x) (concat cmd-prefix command dired-mark-separator x)))))
824 (concat 824 (concat
825 (cond (on-each 825 (cond
826 (format "%s%s" 826 (on-each
827 (mapconcat stuff-it (mapcar 'shell-quote-argument file-list) 827 (format "%s%s"
828 cmd-sep) 828 (mapconcat stuff-it (mapcar #'shell-quote-argument file-list)
829 ;; POSIX shells running a list of commands in the background 829 cmd-sep)
830 ;; (LIST = cmd_1 & [cmd_2 & ... cmd_i & ... cmd_N &]) 830 ;; POSIX shells running a list of commands in the background
831 ;; return once cmd_N ends, i.e., the shell does not 831 ;; (LIST = cmd_1 & [cmd_2 & ... cmd_i & ... cmd_N &])
832 ;; wait for cmd_i to finish before executing cmd_i+1. 832 ;; return once cmd_N ends, i.e., the shell does not
833 ;; That means, running (shell-command LIST) may not show 833 ;; wait for cmd_i to finish before executing cmd_i+1.
834 ;; the output of all the commands (Bug#23206). 834 ;; That means, running (shell-command LIST) may not show
835 ;; Add 'wait' to force those POSIX shells to wait until 835 ;; the output of all the commands (Bug#23206).
836 ;; all commands finish. 836 ;; Add 'wait' to force those POSIX shells to wait until
837 (or (and parallel-in-background (not w32-shell) 837 ;; all commands finish.
838 "&wait") 838 (or (and parallel-in-background (not w32-shell)
839 ""))) 839 "&wait")
840 (t 840 "")))
841 (let ((files (mapconcat 'shell-quote-argument 841 (t
842 file-list dired-mark-separator))) 842 (let ((files (mapconcat #'shell-quote-argument
843 (when (cdr file-list) 843 file-list dired-mark-separator)))
844 (setq files (concat dired-mark-prefix files dired-mark-postfix))) 844 (when (cdr file-list)
845 (funcall stuff-it files)))) 845 (setq files (concat dired-mark-prefix files dired-mark-postfix)))
846 (funcall stuff-it files))))
846 (or (and in-background "&") "")))) 847 (or (and in-background "&") ""))))
847 848
848;; This is an extra function so that it can be redefined by ange-ftp. 849;; This is an extra function so that it can be redefined by ange-ftp.
@@ -872,7 +873,7 @@ Else returns nil for success."
872 (set-buffer err-buffer) 873 (set-buffer err-buffer)
873 (erase-buffer) 874 (erase-buffer)
874 (setq default-directory dir ; caller's default-directory 875 (setq default-directory dir ; caller's default-directory
875 err (not (eq 0 (apply 'process-file program nil t nil arguments)))) 876 err (not (eq 0 (apply #'process-file program nil t nil arguments))))
876 (if err 877 (if err
877 (progn 878 (progn
878 (dired-log (concat program " " (prin1-to-string arguments) "\n")) 879 (dired-log (concat program " " (prin1-to-string arguments) "\n"))
@@ -1349,7 +1350,7 @@ See Info node `(emacs)Subdir switches' for more details."
1349 ;; Replace space by old marker without moving point. 1350 ;; Replace space by old marker without moving point.
1350 ;; Faster than goto+insdel inside a save-excursion? 1351 ;; Faster than goto+insdel inside a save-excursion?
1351 (when char 1352 (when char
1352 (subst-char-in-region opoint (1+ opoint) ?\040 char))))) 1353 (subst-char-in-region opoint (1+ opoint) ?\s char)))))
1353 (dired-move-to-filename)) 1354 (dired-move-to-filename))
1354 1355
1355;;;###autoload 1356;;;###autoload
@@ -1403,8 +1404,8 @@ files matching `dired-omit-regexp'."
1403 (catch 'not-found 1404 (catch 'not-found
1404 (if (string= directory cur-dir) 1405 (if (string= directory cur-dir)
1405 (progn 1406 (progn
1406 (skip-chars-forward "^\r\n") 1407 (end-of-line)
1407 (if (eq (following-char) ?\r) 1408 (if (dired--hidden-p)
1408 (dired-unhide-subdir)) 1409 (dired-unhide-subdir))
1409 ;; We are already where we should be, except when 1410 ;; We are already where we should be, except when
1410 ;; point is before the subdir line or its total line. 1411 ;; point is before the subdir line or its total line.
@@ -1414,7 +1415,7 @@ files matching `dired-omit-regexp'."
1414 ;; else try to find correct place to insert 1415 ;; else try to find correct place to insert
1415 (if (dired-goto-subdir directory) 1416 (if (dired-goto-subdir directory)
1416 (progn ;; unhide if necessary 1417 (progn ;; unhide if necessary
1417 (if (= (following-char) ?\r) 1418 (if (dired--hidden-p)
1418 ;; Point is at end of subdir line. 1419 ;; Point is at end of subdir line.
1419 (dired-unhide-subdir)) 1420 (dired-unhide-subdir))
1420 ;; found - skip subdir and `total' line 1421 ;; found - skip subdir and `total' line
@@ -1523,7 +1524,7 @@ files matching `dired-omit-regexp'."
1523 (point)) 1524 (point))
1524 (line-beginning-position 2))) 1525 (line-beginning-position 2)))
1525 (setq file (directory-file-name file)) 1526 (setq file (directory-file-name file))
1526 (dired-add-entry file (if (eq ?\040 marker) nil marker))))) 1527 (dired-add-entry file (if (eq ?\s marker) nil marker)))))
1527 1528
1528;;; Copy, move/rename, making hard and symbolic links 1529;;; Copy, move/rename, making hard and symbolic links
1529 1530
@@ -2562,7 +2563,7 @@ Optional third arg LIMIT (>= 1) is a limit to the length of the
2562resulting list. 2563resulting list.
2563Thus, if SEP is a regexp that only matches itself, 2564Thus, if SEP is a regexp that only matches itself,
2564 2565
2565 (mapconcat 'identity (dired-split SEP STRING) SEP) 2566 (mapconcat #'identity (dired-split SEP STRING) SEP)
2566 2567
2567is always equal to STRING." 2568is always equal to STRING."
2568 (let* ((start (string-match pat str)) 2569 (let* ((start (string-match pat str))
@@ -2610,7 +2611,7 @@ When called interactively and not on a subdir line, go to this subdir's line."
2610(defun dired-goto-subdir (dir) 2611(defun dired-goto-subdir (dir)
2611 "Go to end of header line of DIR in this dired buffer. 2612 "Go to end of header line of DIR in this dired buffer.
2612Return value of point on success, otherwise return nil. 2613Return value of point on success, otherwise return nil.
2613The next char is either \\n, or \\r if DIR is hidden." 2614The next char is \\n."
2614 (interactive 2615 (interactive
2615 (prog1 ; let push-mark display its message 2616 (prog1 ; let push-mark display its message
2616 (list (expand-file-name 2617 (list (expand-file-name
@@ -2625,8 +2626,8 @@ The next char is either \\n, or \\r if DIR is hidden."
2625 (and elt 2626 (and elt
2626 (goto-char (dired-get-subdir-min elt)) 2627 (goto-char (dired-get-subdir-min elt))
2627 ;; dired-subdir-hidden-p and dired-add-entry depend on point being 2628 ;; dired-subdir-hidden-p and dired-add-entry depend on point being
2628 ;; at either \r or \n after this function succeeds. 2629 ;; at \n after this function succeeds.
2629 (progn (skip-chars-forward "^\r\n") 2630 (progn (end-of-line)
2630 (point))))) 2631 (point)))))
2631 2632
2632;;;###autoload 2633;;;###autoload
@@ -2699,18 +2700,13 @@ Lower levels are unaffected."
2699;;; hiding 2700;;; hiding
2700 2701
2701(defun dired-unhide-subdir () 2702(defun dired-unhide-subdir ()
2702 (let (buffer-read-only) 2703 (with-silent-modifications
2703 (subst-char-in-region (dired-subdir-min) (dired-subdir-max) ?\r ?\n))) 2704 (dired--unhide (dired-subdir-min) (dired-subdir-max))))
2704
2705(defun dired-hide-check ()
2706 (or selective-display
2707 (error "selective-display must be t for subdir hiding to work!")))
2708 2705
2709(defun dired-subdir-hidden-p (dir) 2706(defun dired-subdir-hidden-p (dir)
2710 (and selective-display 2707 (save-excursion
2711 (save-excursion 2708 (dired-goto-subdir dir)
2712 (dired-goto-subdir dir) 2709 (dired--hidden-p)))
2713 (= (following-char) ?\r))))
2714 2710
2715;;;###autoload 2711;;;###autoload
2716(defun dired-hide-subdir (arg) 2712(defun dired-hide-subdir (arg)
@@ -2718,8 +2714,7 @@ Lower levels are unaffected."
2718Optional prefix arg is a repeat factor. 2714Optional prefix arg is a repeat factor.
2719Use \\[dired-hide-all] to (un)hide all directories." 2715Use \\[dired-hide-all] to (un)hide all directories."
2720 (interactive "p") 2716 (interactive "p")
2721 (dired-hide-check) 2717 (with-silent-modifications
2722 (let ((modflag (buffer-modified-p)))
2723 (while (>= (setq arg (1- arg)) 0) 2718 (while (>= (setq arg (1- arg)) 0)
2724 (let* ((cur-dir (dired-current-directory)) 2719 (let* ((cur-dir (dired-current-directory))
2725 (hidden-p (dired-subdir-hidden-p cur-dir)) 2720 (hidden-p (dired-subdir-hidden-p cur-dir))
@@ -2728,12 +2723,11 @@ Use \\[dired-hide-all] to (un)hide all directories."
2728 buffer-read-only) 2723 buffer-read-only)
2729 ;; keep header line visible, hide rest 2724 ;; keep header line visible, hide rest
2730 (goto-char (dired-get-subdir-min elt)) 2725 (goto-char (dired-get-subdir-min elt))
2731 (skip-chars-forward "^\n\r") 2726 (end-of-line)
2732 (if hidden-p 2727 (if hidden-p
2733 (subst-char-in-region (point) end-pos ?\r ?\n) 2728 (dired--unhide (point) end-pos)
2734 (subst-char-in-region (point) end-pos ?\n ?\r))) 2729 (dired--hide (point) end-pos)))
2735 (dired-next-subdir 1 t)) 2730 (dired-next-subdir 1 t))))
2736 (restore-buffer-modified-p modflag)))
2737 2731
2738;;;###autoload 2732;;;###autoload
2739(defun dired-hide-all (&optional ignored) 2733(defun dired-hide-all (&optional ignored)
@@ -2741,28 +2735,20 @@ Use \\[dired-hide-all] to (un)hide all directories."
2741If there is already something hidden, make everything visible again. 2735If there is already something hidden, make everything visible again.
2742Use \\[dired-hide-subdir] to (un)hide a particular subdirectory." 2736Use \\[dired-hide-subdir] to (un)hide a particular subdirectory."
2743 (interactive "P") 2737 (interactive "P")
2744 (dired-hide-check) 2738 (with-silent-modifications
2745 (let ((modflag (buffer-modified-p)) 2739 (if (text-property-any (point-min) (point-max) 'invisible 'dired)
2746 buffer-read-only) 2740 (dired--unhide (point-min) (point-max))
2747 (if (save-excursion
2748 (goto-char (point-min))
2749 (search-forward "\r" nil t))
2750 ;; unhide - bombs on \r in filenames
2751 (subst-char-in-region (point-min) (point-max) ?\r ?\n)
2752 ;; hide 2741 ;; hide
2753 (let ((pos (point-max)) ; pos of end of last directory 2742 (let ((pos (point-max))) ; pos of end of last directory
2754 (alist dired-subdir-alist)) 2743 (dolist (subdir dired-subdir-alist)
2755 (while alist ; while there are dirs before pos 2744 (let ((start (dired-get-subdir-min subdir)) ; pos of prev dir
2756 (subst-char-in-region (dired-get-subdir-min (car alist)) ; pos of prev dir 2745 (end (save-excursion
2757 (save-excursion 2746 (goto-char pos) ; current dir
2758 (goto-char pos) ; current dir 2747 ;; we're somewhere on current dir's line
2759 ;; we're somewhere on current dir's line 2748 (forward-line -1)
2760 (forward-line -1) 2749 (point))))
2761 (point)) 2750 (dired--hide start end))
2762 ?\n ?\r) 2751 (setq pos (dired-get-subdir-min subdir))))))) ; prev dir gets current dir
2763 (setq pos (dired-get-subdir-min (car alist))) ; prev dir gets current dir
2764 (setq alist (cdr alist)))))
2765 (restore-buffer-modified-p modflag)))
2766 2752
2767;;;###end dired-ins.el 2753;;;###end dired-ins.el
2768 2754
@@ -2788,8 +2774,8 @@ When off, it uses the original predicate."
2788 nil nil nil 2774 nil nil nil
2789 (if dired-isearch-filenames-mode 2775 (if dired-isearch-filenames-mode
2790 (add-function :before-while (local 'isearch-filter-predicate) 2776 (add-function :before-while (local 'isearch-filter-predicate)
2791 #'dired-isearch-filter-filenames 2777 #'dired-isearch-filter-filenames
2792 '((isearch-message-prefix . "filename "))) 2778 '((isearch-message-prefix . "filename ")))
2793 (remove-function (local 'isearch-filter-predicate) 2779 (remove-function (local 'isearch-filter-predicate)
2794 #'dired-isearch-filter-filenames)) 2780 #'dired-isearch-filter-filenames))
2795 (when isearch-mode 2781 (when isearch-mode
@@ -2805,13 +2791,13 @@ Intended to be added to `isearch-mode-hook'."
2805 (get-text-property (point) 'dired-filename))) 2791 (get-text-property (point) 'dired-filename)))
2806 (define-key isearch-mode-map "\M-sff" 'dired-isearch-filenames-mode) 2792 (define-key isearch-mode-map "\M-sff" 'dired-isearch-filenames-mode)
2807 (dired-isearch-filenames-mode 1) 2793 (dired-isearch-filenames-mode 1)
2808 (add-hook 'isearch-mode-end-hook 'dired-isearch-filenames-end nil t))) 2794 (add-hook 'isearch-mode-end-hook #'dired-isearch-filenames-end nil t)))
2809 2795
2810(defun dired-isearch-filenames-end () 2796(defun dired-isearch-filenames-end ()
2811 "Clean up the Dired file name search after terminating isearch." 2797 "Clean up the Dired file name search after terminating isearch."
2812 (define-key isearch-mode-map "\M-sff" nil) 2798 (define-key isearch-mode-map "\M-sff" nil)
2813 (dired-isearch-filenames-mode -1) 2799 (dired-isearch-filenames-mode -1)
2814 (remove-hook 'isearch-mode-end-hook 'dired-isearch-filenames-end t) 2800 (remove-hook 'isearch-mode-end-hook #'dired-isearch-filenames-end t)
2815 (unless isearch-suspended 2801 (unless isearch-suspended
2816 (custom-reevaluate-setting 'dired-isearch-filenames))) 2802 (custom-reevaluate-setting 'dired-isearch-filenames)))
2817 2803
@@ -2905,7 +2891,7 @@ REGEXP should use constructs supported by your local `grep' command."
2905 (declare-function rgrep-find-ignored-directories "grep" (dir)) 2891 (declare-function rgrep-find-ignored-directories "grep" (dir))
2906 (let* ((files (dired-get-marked-files nil nil nil nil t)) 2892 (let* ((files (dired-get-marked-files nil nil nil nil t))
2907 (ignores (nconc (mapcar 2893 (ignores (nconc (mapcar
2908 (lambda (s) (concat s "/")) 2894 #'file-name-as-directory
2909 (rgrep-find-ignored-directories default-directory)) 2895 (rgrep-find-ignored-directories default-directory))
2910 grep-find-ignored-files)) 2896 grep-find-ignored-files))
2911 (xrefs (mapcan 2897 (xrefs (mapcan
diff --git a/lisp/dired.el b/lisp/dired.el
index 98f493ecc65..fc0b71238ba 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -364,12 +364,12 @@ This is an alist of the form (SUBDIR . SWITCHES).")
364(defvaralias 'dired-move-to-filename-regexp 364(defvaralias 'dired-move-to-filename-regexp
365 'directory-listing-before-filename-regexp) 365 'directory-listing-before-filename-regexp)
366 366
367(defvar dired-subdir-regexp "^. \\([^\n\r]+\\)\\(:\\)[\n\r]" 367(defvar dired-subdir-regexp "^. \\(.+\\)\\(:\\)\n"
368 "Regexp matching a maybe hidden subdirectory line in `ls -lR' output. 368 "Regexp matching a maybe hidden subdirectory line in `ls -lR' output.
369Subexpression 1 is the subdirectory proper, no trailing colon. 369Subexpression 1 is the subdirectory proper, no trailing colon.
370The match starts at the beginning of the line and ends after the end 370The match starts at the beginning of the line and ends after the end
371of the line (\\n or \\r). 371of the line.
372Subexpression 2 must end right before the \\n or \\r.") 372Subexpression 2 must end right before the \\n.")
373 373
374(defgroup dired-faces nil 374(defgroup dired-faces nil
375 "Faces used by Dired." 375 "Faces used by Dired."
@@ -548,7 +548,7 @@ Return value is the number of files marked, or nil if none were marked."
548 (setq count 0) 548 (setq count 0)
549 (when ,msg 549 (when ,msg
550 (message "%s %ss%s..." 550 (message "%s %ss%s..."
551 (cond ((eq dired-marker-char ?\040) "Unmarking") 551 (cond ((eq dired-marker-char ?\s) "Unmarking")
552 ((eq dired-del-marker dired-marker-char) 552 ((eq dired-del-marker dired-marker-char)
553 "Flagging") 553 "Flagging")
554 (t "Marking")) 554 (t "Marking"))
@@ -568,7 +568,7 @@ Return value is the number of files marked, or nil if none were marked."
568 count 568 count
569 ,msg 569 ,msg
570 (dired-plural-s count) 570 (dired-plural-s count)
571 (if (eq dired-marker-char ?\040) "un" "") 571 (if (eq dired-marker-char ?\s) "un" "")
572 (if (eq dired-marker-char dired-del-marker) 572 (if (eq dired-marker-char dired-del-marker)
573 "flagged" "marked")))) 573 "flagged" "marked"))))
574 (and (> count 0) count))) 574 (and (> count 0) count)))
@@ -1539,9 +1539,8 @@ change; the point does."
1539 1539
1540(defun dired-remember-marks (beg end) 1540(defun dired-remember-marks (beg end)
1541 "Return alist of files and their marks, from BEG to END." 1541 "Return alist of files and their marks, from BEG to END."
1542 (if selective-display ; must unhide to make this work. 1542 (if (dired--find-hidden-pos (point-min) (point-max))
1543 (let ((inhibit-read-only t)) 1543 (dired--unhide (point-min) (point-max))) ;Must unhide to make this work.
1544 (subst-char-in-region beg end ?\r ?\n)))
1545 (let (fil chr alist) 1544 (let (fil chr alist)
1546 (save-excursion 1545 (save-excursion
1547 (goto-char beg) 1546 (goto-char beg)
@@ -1568,15 +1567,12 @@ Each element of ALIST looks like (FILE . MARKERCHAR)."
1568 1567
1569(defun dired-remember-hidden () 1568(defun dired-remember-hidden ()
1570 "Return a list of names of subdirs currently hidden." 1569 "Return a list of names of subdirs currently hidden."
1571 (let ((l dired-subdir-alist) dir pos result) 1570 (let (result)
1572 (while l 1571 (pcase-dolist (`(,dir . ,pos) dired-subdir-alist)
1573 (setq dir (car (car l))
1574 pos (cdr (car l))
1575 l (cdr l))
1576 (goto-char pos) 1572 (goto-char pos)
1577 (skip-chars-forward "^\r\n") 1573 (end-of-line)
1578 (if (eq (following-char) ?\r) 1574 (if (dired--hidden-p)
1579 (setq result (cons dir result)))) 1575 (push dir result)))
1580 result)) 1576 result))
1581 1577
1582(defun dired-insert-old-subdirs (old-subdir-alist) 1578(defun dired-insert-old-subdirs (old-subdir-alist)
@@ -2135,9 +2131,9 @@ Keybindings:
2135 mode-name "Dired" 2131 mode-name "Dired"
2136 ;; case-fold-search nil 2132 ;; case-fold-search nil
2137 buffer-read-only t 2133 buffer-read-only t
2138 selective-display t ; for subdirectory hiding
2139 mode-line-buffer-identification 2134 mode-line-buffer-identification
2140 (propertized-buffer-identification "%17b")) 2135 (propertized-buffer-identification "%17b"))
2136 (add-to-invisibility-spec '(dired . t))
2141 ;; Ignore dired-hide-details-* value of invisible text property by default. 2137 ;; Ignore dired-hide-details-* value of invisible text property by default.
2142 (when (eq buffer-invisibility-spec t) 2138 (when (eq buffer-invisibility-spec t)
2143 (setq buffer-invisibility-spec (list t))) 2139 (setq buffer-invisibility-spec (list t)))
@@ -2160,8 +2156,8 @@ Keybindings:
2160 (when (featurep 'dnd) 2156 (when (featurep 'dnd)
2161 (setq-local dnd-protocol-alist 2157 (setq-local dnd-protocol-alist
2162 (append dired-dnd-protocol-alist dnd-protocol-alist))) 2158 (append dired-dnd-protocol-alist dnd-protocol-alist)))
2163 (add-hook 'file-name-at-point-functions 'dired-file-name-at-point nil t) 2159 (add-hook 'file-name-at-point-functions #'dired-file-name-at-point nil t)
2164 (add-hook 'isearch-mode-hook 'dired-isearch-filenames-setup nil t) 2160 (add-hook 'isearch-mode-hook #'dired-isearch-filenames-setup nil t)
2165 (run-mode-hooks 'dired-mode-hook)) 2161 (run-mode-hooks 'dired-mode-hook))
2166 2162
2167;; Idiosyncratic dired commands that don't deal with marks. 2163;; Idiosyncratic dired commands that don't deal with marks.
@@ -2266,7 +2262,8 @@ directory in another window."
2266 (error "File no longer exists; type `g' to update Dired buffer"))))) 2262 (error "File no longer exists; type `g' to update Dired buffer")))))
2267 2263
2268;; Force C-m keybinding rather than `f' or `e' in the mode doc: 2264;; Force C-m keybinding rather than `f' or `e' in the mode doc:
2269(define-obsolete-function-alias 'dired-advertised-find-file 'dired-find-file "23.2") 2265(define-obsolete-function-alias 'dired-advertised-find-file
2266 #'dired-find-file "23.2")
2270(defun dired-find-file () 2267(defun dired-find-file ()
2271 "In Dired, visit the file or directory named on this line." 2268 "In Dired, visit the file or directory named on this line."
2272 (interactive) 2269 (interactive)
@@ -2514,6 +2511,34 @@ See options: `dired-hide-details-hide-symlink-targets' and
2514 'remove-from-invisibility-spec) 2511 'remove-from-invisibility-spec)
2515 'dired-hide-details-link)) 2512 'dired-hide-details-link))
2516 2513
2514;;; Functions to hide/unhide text
2515
2516(defun dired--find-hidden-pos (start end)
2517 (text-property-any start end 'invisible 'dired))
2518
2519(defun dired--hidden-p (&optional pos)
2520 (eq (get-char-property (or pos (point)) 'invisible) 'dired))
2521
2522(defun dired--hide (start end)
2523 ;; The old code used selective-display which only works at
2524 ;; a line-granularity, so it used start and end positions that where
2525 ;; approximate ("anywhere on the line is fine").
2526 (save-excursion
2527 (put-text-property (progn (goto-char start) (line-end-position))
2528 (progn (goto-char end) (line-end-position))
2529 'invisible 'dired)))
2530
2531(defun dired--unhide (start end)
2532 ;; The old code used selective-display which only works at
2533 ;; a line-granularity, so it used start and end positions that where
2534 ;; approximate ("anywhere on the line is fine").
2535 ;; FIXME: This also removes other invisible properties!
2536 (save-excursion
2537 (remove-text-properties
2538 (progn (goto-char start) (line-end-position))
2539 (progn (goto-char end) (line-end-position))
2540 '(invisible))))
2541
2517;;; Functions for finding the file name in a dired buffer line. 2542;;; Functions for finding the file name in a dired buffer line.
2518 2543
2519(defvar dired-permission-flags-regexp 2544(defvar dired-permission-flags-regexp
@@ -2553,12 +2578,11 @@ Return the position of the beginning of the filename, or nil if none found."
2553 ;; This is the UNIX version. 2578 ;; This is the UNIX version.
2554 (if (get-text-property (point) 'dired-filename) 2579 (if (get-text-property (point) 'dired-filename)
2555 (goto-char (next-single-property-change (point) 'dired-filename)) 2580 (goto-char (next-single-property-change (point) 'dired-filename))
2556 (let (opoint file-type executable symlink hidden used-F eol) 2581 (let ((opoint (point))
2557 (setq used-F (dired-check-switches dired-actual-switches "F" "classify") 2582 (used-F (dired-check-switches dired-actual-switches "F" "classify"))
2558 opoint (point) 2583 (eol (line-end-position))
2559 eol (line-end-position) 2584 (hidden (dired--hidden-p))
2560 hidden (and selective-display 2585 file-type executable symlink)
2561 (save-excursion (search-forward "\r" eol t))))
2562 (if hidden 2586 (if hidden
2563 nil 2587 nil
2564 (save-excursion ;; Find out what kind of file this is: 2588 (save-excursion ;; Find out what kind of file this is:
@@ -2795,7 +2819,7 @@ You can then feed the file name(s) to other commands with \\[yank]."
2795 (if pos 2819 (if pos
2796 (progn 2820 (progn
2797 (goto-char pos) 2821 (goto-char pos)
2798 (or no-skip (skip-chars-forward "^\n\r")) 2822 (or no-skip (end-of-line))
2799 (point)) 2823 (point))
2800 (if no-error-if-not-found 2824 (if no-error-if-not-found
2801 nil ; return nil if not found 2825 nil ; return nil if not found
@@ -3187,17 +3211,17 @@ non-empty directories is allowed."
3187 (dired-move-to-filename)) 3211 (dired-move-to-filename))
3188 3212
3189(defun dired-fun-in-all-buffers (directory file fun &rest args) 3213(defun dired-fun-in-all-buffers (directory file fun &rest args)
3190 ;; In all buffers dired'ing DIRECTORY, run FUN with ARGS. 3214 "In all buffers dired'ing DIRECTORY, run FUN with ARGS.
3191 ;; If the buffer has a wildcard pattern, check that it matches FILE. 3215If the buffer has a wildcard pattern, check that it matches FILE.
3192 ;; (FILE does not include a directory component.) 3216(FILE does not include a directory component.)
3193 ;; FILE may be nil, in which case ignore it. 3217FILE may be nil, in which case ignore it.
3194 ;; Return list of buffers where FUN succeeded (i.e., returned non-nil). 3218Return list of buffers where FUN succeeded (i.e., returned non-nil)."
3195 (let (success-list) 3219 (let (success-list)
3196 (dolist (buf (dired-buffers-for-dir (expand-file-name directory) 3220 (dolist (buf (dired-buffers-for-dir (expand-file-name directory) file))
3197 file))
3198 (with-current-buffer buf 3221 (with-current-buffer buf
3199 (if (apply fun args) 3222 (if (apply fun args)
3200 (setq success-list (cons (buffer-name buf) success-list))))) 3223 (push buf success-list))))
3224 ;; FIXME: AFAICT, this return value is not used by any of the callers!
3201 success-list)) 3225 success-list))
3202 3226
3203;; Delete the entry for FILE from 3227;; Delete the entry for FILE from
@@ -3430,7 +3454,7 @@ no ARGth marked file is found before this line."
3430 (and (dired-goto-file file) 3454 (and (dired-goto-file file)
3431 (progn 3455 (progn
3432 (beginning-of-line) 3456 (beginning-of-line)
3433 (if (not (equal ?\040 (following-char))) 3457 (if (not (equal ?\s (following-char)))
3434 (following-char)))))) 3458 (following-char))))))
3435 3459
3436(defun dired-mark-files-in-region (start end) 3460(defun dired-mark-files-in-region (start end)
@@ -3488,7 +3512,7 @@ If looking at a subdir, unmark all its files except `.' and `..'.
3488If the region is active in Transient Mark mode, unmark all files 3512If the region is active in Transient Mark mode, unmark all files
3489in the active region." 3513in the active region."
3490 (interactive (list current-prefix-arg t)) 3514 (interactive (list current-prefix-arg t))
3491 (let ((dired-marker-char ?\040)) 3515 (let ((dired-marker-char ?\s))
3492 (dired-mark arg interactive))) 3516 (dired-mark arg interactive)))
3493 3517
3494(defun dired-flag-file-deletion (arg &optional interactive) 3518(defun dired-flag-file-deletion (arg &optional interactive)
@@ -3527,11 +3551,11 @@ As always, hidden subdirs are not affected."
3527 ;; use subst instead of insdel because it does not move 3551 ;; use subst instead of insdel because it does not move
3528 ;; the gap and thus should be faster and because 3552 ;; the gap and thus should be faster and because
3529 ;; other characters are left alone automatically 3553 ;; other characters are left alone automatically
3530 (apply 'subst-char-in-region 3554 (apply #'subst-char-in-region
3531 (point) (1+ (point)) 3555 (point) (1+ (point))
3532 (if (eq ?\040 (following-char)) ; SPC 3556 (if (eq ?\s (following-char))
3533 (list ?\040 dired-marker-char) 3557 (list ?\s dired-marker-char)
3534 (list dired-marker-char ?\040)))) 3558 (list dired-marker-char ?\s))))
3535 (forward-line 1))))) 3559 (forward-line 1)))))
3536 3560
3537;;; Commands to mark or flag files based on their characteristics or names. 3561;;; Commands to mark or flag files based on their characteristics or names.
@@ -3562,7 +3586,7 @@ object files--just `.o' will mark more than you might think."
3562 (dired-get-filename nil t) t)) 3586 (dired-get-filename nil t) t))
3563 "\\'")))) 3587 "\\'"))))
3564 'dired-regexp-history) 3588 'dired-regexp-history)
3565 (if current-prefix-arg ?\040))) 3589 (if current-prefix-arg ?\s)))
3566 (let ((dired-marker-char (or marker-char dired-marker-char))) 3590 (let ((dired-marker-char (or marker-char dired-marker-char)))
3567 (dired-mark-if 3591 (dired-mark-if
3568 (and (not (looking-at-p dired-re-dot)) 3592 (and (not (looking-at-p dired-re-dot))
@@ -3585,7 +3609,7 @@ since it was last visited."
3585 (list (read-regexp (concat (if current-prefix-arg "Unmark" "Mark") 3609 (list (read-regexp (concat (if current-prefix-arg "Unmark" "Mark")
3586 " files containing (regexp): ") 3610 " files containing (regexp): ")
3587 nil 'dired-regexp-history) 3611 nil 'dired-regexp-history)
3588 (if current-prefix-arg ?\040))) 3612 (if current-prefix-arg ?\s)))
3589 (let ((dired-marker-char (or marker-char dired-marker-char))) 3613 (let ((dired-marker-char (or marker-char dired-marker-char)))
3590 (dired-mark-if 3614 (dired-mark-if
3591 (and (not (looking-at-p dired-re-dot)) 3615 (and (not (looking-at-p dired-re-dot))
@@ -3622,14 +3646,14 @@ The match is against the non-directory part of the filename. Use `^'
3622 "Mark all symbolic links. 3646 "Mark all symbolic links.
3623With prefix argument, unmark or unflag all those files." 3647With prefix argument, unmark or unflag all those files."
3624 (interactive "P") 3648 (interactive "P")
3625 (let ((dired-marker-char (if unflag-p ?\040 dired-marker-char))) 3649 (let ((dired-marker-char (if unflag-p ?\s dired-marker-char)))
3626 (dired-mark-if (looking-at-p dired-re-sym) "symbolic link"))) 3650 (dired-mark-if (looking-at-p dired-re-sym) "symbolic link")))
3627 3651
3628(defun dired-mark-directories (unflag-p) 3652(defun dired-mark-directories (unflag-p)
3629 "Mark all directory file lines except `.' and `..'. 3653 "Mark all directory file lines except `.' and `..'.
3630With prefix argument, unmark or unflag all those files." 3654With prefix argument, unmark or unflag all those files."
3631 (interactive "P") 3655 (interactive "P")
3632 (let ((dired-marker-char (if unflag-p ?\040 dired-marker-char))) 3656 (let ((dired-marker-char (if unflag-p ?\s dired-marker-char)))
3633 (dired-mark-if (and (looking-at-p dired-re-dir) 3657 (dired-mark-if (and (looking-at-p dired-re-dir)
3634 (not (looking-at-p dired-re-dot))) 3658 (not (looking-at-p dired-re-dot)))
3635 "directory file"))) 3659 "directory file")))
@@ -3638,7 +3662,7 @@ With prefix argument, unmark or unflag all those files."
3638 "Mark all executable files. 3662 "Mark all executable files.
3639With prefix argument, unmark or unflag all those files." 3663With prefix argument, unmark or unflag all those files."
3640 (interactive "P") 3664 (interactive "P")
3641 (let ((dired-marker-char (if unflag-p ?\040 dired-marker-char))) 3665 (let ((dired-marker-char (if unflag-p ?\s dired-marker-char)))
3642 (dired-mark-if (looking-at-p dired-re-exe) "executable file"))) 3666 (dired-mark-if (looking-at-p dired-re-exe) "executable file")))
3643 3667
3644;; dired-x.el has a dired-mark-sexp interactive command: mark 3668;; dired-x.el has a dired-mark-sexp interactive command: mark
@@ -3648,7 +3672,7 @@ With prefix argument, unmark or unflag all those files."
3648 "Flag for deletion files whose names suggest they are auto save files. 3672 "Flag for deletion files whose names suggest they are auto save files.
3649A prefix argument says to unmark or unflag those files instead." 3673A prefix argument says to unmark or unflag those files instead."
3650 (interactive "P") 3674 (interactive "P")
3651 (let ((dired-marker-char (if unflag-p ?\040 dired-del-marker))) 3675 (let ((dired-marker-char (if unflag-p ?\s dired-del-marker)))
3652 (dired-mark-if 3676 (dired-mark-if
3653 ;; It is less than general to check for # here, 3677 ;; It is less than general to check for # here,
3654 ;; but it's the only way this runs fast enough. 3678 ;; but it's the only way this runs fast enough.
@@ -3887,7 +3911,7 @@ The idea is to set this buffer-locally in special Dired buffers.")
3887 (force-mode-line-update))) 3911 (force-mode-line-update)))
3888 3912
3889(define-obsolete-function-alias 'dired-sort-set-modeline 3913(define-obsolete-function-alias 'dired-sort-set-modeline
3890 'dired-sort-set-mode-line "24.3") 3914 #'dired-sort-set-mode-line "24.3")
3891 3915
3892(defun dired-sort-toggle-or-edit (&optional arg) 3916(defun dired-sort-toggle-or-edit (&optional arg)
3893 "Toggle sorting by date, and refresh the Dired buffer. 3917 "Toggle sorting by date, and refresh the Dired buffer.
@@ -4129,7 +4153,7 @@ Ask means pop up a menu for the user to select one of copy, move or link."
4129 (dired dired-dir) 4153 (dired dired-dir)
4130 ;; The following elements of `misc-data' are the keys 4154 ;; The following elements of `misc-data' are the keys
4131 ;; from `dired-subdir-alist'. 4155 ;; from `dired-subdir-alist'.
4132 (mapc 'dired-maybe-insert-subdir (cdr misc-data)) 4156 (mapc #'dired-maybe-insert-subdir (cdr misc-data))
4133 (current-buffer)) 4157 (current-buffer))
4134 (message "Desktop: Directory %s no longer exists." dir) 4158 (message "Desktop: Directory %s no longer exists." dir)
4135 (when desktop-missing-file-warning (sit-for 1)) 4159 (when desktop-missing-file-warning (sit-for 1))