X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/0acdf642cfbffe8bd800dd641a6c3132a9f718c6..cb3f945fa83c3559eccd040d377f41596b1efe5e:/lisp/dired.el diff --git a/lisp/dired.el b/lisp/dired.el index 761e579941..cc5f0bbca1 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -1,6 +1,7 @@ ;;; dired.el --- directory-browsing commands -;; Copyright (C) 1985, 86, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. +;; Copyright (C) 1985, 86, 92, 93, 94, 95, 96, 1997, 2000, 2001 +;; Free Software Foundation, Inc. ;; Author: Sebastian Kremer ;; Maintainer: FSF @@ -334,66 +335,65 @@ Subexpression 2 must end right before the \\n or \\r.") (and (> count 0) count)))) (defmacro dired-map-over-marks (body arg &optional show-progress) -;; "Macro: Perform BODY with point somewhere on each marked line -;;and return a list of BODY's results. -;;If no marked file could be found, execute BODY on the current line. -;; If ARG is an integer, use the next ARG (or previous -ARG, if ARG<0) -;; files instead of the marked files. -;; In that case point is dragged along. This is so that commands on -;; the next ARG (instead of the marked) files can be chained easily. -;; If ARG is otherwise non-nil, use current file instead. -;;If optional third arg SHOW-PROGRESS evaluates to non-nil, -;; redisplay the dired buffer after each file is processed. -;;No guarantee is made about the position on the marked line. -;; BODY must ensure this itself if it depends on this. -;;Search starts at the beginning of the buffer, thus the car of the list -;; corresponds to the line nearest to the buffer's bottom. This -;; is also true for (positive and negative) integer values of ARG. -;;BODY should not be too long as it is expanded four times." -;; -;;Warning: BODY must not add new lines before point - this may cause an -;;endless loop. -;;This warning should not apply any longer, sk 2-Sep-1991 14:10. - (` (prog1 - (let (buffer-read-only case-fold-search found results) - (if (, arg) - (if (integerp (, arg)) - (progn;; no save-excursion, want to move point. - (dired-repeat-over-lines - (, arg) - (function (lambda () - (if (, show-progress) (sit-for 0)) - (setq results (cons (, body) results))))) - (if (< (, arg) 0) - (nreverse results) - results)) - ;; non-nil, non-integer ARG means use current file: - (list (, body))) - (let ((regexp (dired-marker-regexp)) next-position) - (save-excursion - (goto-char (point-min)) - ;; remember position of next marked file before BODY - ;; can insert lines before the just found file, - ;; confusing us by finding the same marked file again - ;; and again and... + "Eval BODY with point on each marked line. Return a list of BODY's results. +If no marked file could be found, execute BODY on the current line. + If ARG is an integer, use the next ARG (or previous -ARG, if ARG<0) + files instead of the marked files. + In that case point is dragged along. This is so that commands on + the next ARG (instead of the marked) files can be chained easily. + If ARG is otherwise non-nil, use current file instead. +If optional third arg SHOW-PROGRESS evaluates to non-nil, + redisplay the dired buffer after each file is processed. +No guarantee is made about the position on the marked line. + BODY must ensure this itself if it depends on this. +Search starts at the beginning of the buffer, thus the car of the list + corresponds to the line nearest to the buffer's bottom. This + is also true for (positive and negative) integer values of ARG. +BODY should not be too long as it is expanded four times." + ;; + ;;Warning: BODY must not add new lines before point - this may cause an + ;;endless loop. + ;;This warning should not apply any longer, sk 2-Sep-1991 14:10. + `(prog1 + (let (buffer-read-only case-fold-search found results) + (if ,arg + (if (integerp ,arg) + (progn ;; no save-excursion, want to move point. + (dired-repeat-over-lines + ,arg + (function (lambda () + (if ,show-progress (sit-for 0)) + (setq results (cons ,body results))))) + (if (< ,arg 0) + (nreverse results) + results)) + ;; non-nil, non-integer ARG means use current file: + (list ,body)) + (let ((regexp (dired-marker-regexp)) next-position) + (save-excursion + (goto-char (point-min)) + ;; remember position of next marked file before BODY + ;; can insert lines before the just found file, + ;; confusing us by finding the same marked file again + ;; and again and... + (setq next-position (and (re-search-forward regexp nil t) + (point-marker)) + found (not (null next-position))) + (while next-position + (goto-char next-position) + (if ,show-progress (sit-for 0)) + (setq results (cons ,body results)) + ;; move after last match + (goto-char next-position) + (forward-line 1) + (set-marker next-position nil) (setq next-position (and (re-search-forward regexp nil t) - (point-marker)) - found (not (null next-position))) - (while next-position - (goto-char next-position) - (if (, show-progress) (sit-for 0)) - (setq results (cons (, body) results)) - ;; move after last match - (goto-char next-position) - (forward-line 1) - (set-marker next-position nil) - (setq next-position (and (re-search-forward regexp nil t) - (point-marker))))) - (if found - results - (list (, body)))))) - ;; save-excursion loses, again - (dired-move-to-filename)))) + (point-marker))))) + (if found + results + (list ,body))))) + ;; save-excursion loses, again + (dired-move-to-filename))) (defun dired-get-marked-files (&optional localp arg) "Return the marked files' names as list of strings. @@ -561,6 +561,12 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh." (set-buffer old-buf) buffer)) +(defvar dired-buffers nil + ;; Enlarged by dired-advertise + ;; Queried by function dired-buffers-for-dir. When this detects a + ;; killed buffer, it is removed from this list. + "Alist of expanded directories and their associated dired buffers.") + (defun dired-find-buffer-nocreate (dirname &optional mode) ;; This differs from dired-buffers-for-dir in that it does not consider ;; subdirs of default-directory and searches for the first match only. @@ -595,7 +601,8 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh." ;; Also, we can run this hook which may want to modify the switches ;; based on default-directory, e.g. with ange-ftp to a SysV host ;; where ls won't understand -Al switches. - (let (dirname) + (let (dirname + (indent-tabs-mode nil)) (if (consp dir-or-list) (setq dirname (car dir-or-list)) (setq dirname dir-or-list)) @@ -680,19 +687,34 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh." (goto-char (point-min)) (when (re-search-forward "total [0-9]+$" nil t) (insert " free ") - (let ((beg (point))) - (call-process dired-free-space-program nil t nil - dired-free-space-args - (expand-file-name dir-or-list)) - (goto-char beg) - (forward-line 1) - (skip-chars-forward "^ \t") - (forward-word 2) - (skip-chars-forward " \t") - (delete-region beg (point)) - (forward-word 1) - (delete-region (point) - (progn (forward-line 1) (point)))))))) + ;; Non-Posix systems don't always have dired-free-space-program, + ;; but might have an equivalent system call. + (if (fboundp 'file-system-info) + (let ((beg (point)) + (fsinfo (file-system-info dir-or-list))) + (if fsinfo + (insert + (format "%.0f" (/ (nth 2 fsinfo) 1024))) + ;; file-system-info failed; delete " free ". + (delete-region (- beg 7) beg))) + (let ((beg (point))) + (condition-case nil + (if (zerop (call-process dired-free-space-program nil t nil + dired-free-space-args + (expand-file-name dir-or-list))) + (progn + (goto-char beg) + (forward-line 1) + (skip-chars-forward "^ \t") + (forward-word 2) + (skip-chars-forward " \t") + (delete-region beg (point)) + (forward-word 1) + (delete-region (point) + (progn (forward-line 1) (point)))) + ;; The dired-free-space-program failed; delete its output + (delete-region (- beg 7) (point))) + (error (delete-region (- beg 7) (point)))))))))) ;; Quote certain characters, unless ls quoted them for us. (if (not (string-match "b" dired-actual-switches)) (save-excursion @@ -714,11 +736,13 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh." (while (< (point) end) (condition-case nil (if (dired-move-to-filename) - (put-text-property (point) - (save-excursion - (dired-move-to-end-of-filename) - (point)) - 'mouse-face 'highlight)) + (add-text-properties + (point) + (save-excursion + (dired-move-to-end-of-filename) + (point)) + '(mouse-face highlight + help-echo "mouse-2: visit this file in other window"))) (error nil)) (forward-line 1)))) @@ -864,7 +888,7 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh." (define-key map "M" 'dired-do-chmod) (define-key map "O" 'dired-do-chown) (define-key map "P" 'dired-do-print) - (define-key map "Q" 'dired-do-query-replace) + (define-key map "Q" 'dired-do-query-replace-regexp) (define-key map "R" 'dired-do-rename) (define-key map "S" 'dired-do-symlink) (define-key map "X" 'dired-do-shell-command) @@ -914,9 +938,11 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh." (define-key map "*\C-p" 'dired-prev-marked-file) (define-key map "*t" 'dired-do-toggle) ;; Lower keys for commands not operating on all the marked files + (define-key map "a" 'dired-find-alternate-file) (define-key map "d" 'dired-flag-file-deletion) (define-key map "e" 'dired-find-file) (define-key map "f" 'dired-find-file) + (define-key map "w" 'dired-show-file-type) (define-key map "\C-m" 'dired-advertised-find-file) (define-key map "g" 'revert-buffer) (define-key map "h" 'describe-mode) @@ -955,146 +981,214 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh." ;; Make menu bar items. + ;; No need to fo this, now that top-level items are fewer. + ;;;; ;; Get rid of the Edit menu bar item to save space. - (define-key map [menu-bar edit] 'undefined) + ;(define-key map [menu-bar edit] 'undefined) (define-key map [menu-bar subdir] (cons "Subdir" (make-sparse-keymap "Subdir"))) (define-key map [menu-bar subdir hide-all] - '("Hide All" . dired-hide-all)) + '(menu-item "Hide All" dired-hide-all + :help "Hide all subdirectories, leave only header lines")) (define-key map [menu-bar subdir hide-subdir] - '("Hide Subdir" . dired-hide-subdir)) + '(menu-item "Hide/UnHide Subdir" dired-hide-subdir + :help "Hide or unhide current directory listing")) (define-key map [menu-bar subdir tree-down] - '("Tree Down" . dired-tree-down)) + '(menu-item "Tree Down" dired-tree-down + :help "Go to first subdirectory header down the tree")) (define-key map [menu-bar subdir tree-up] - '("Tree Up" . dired-tree-up)) + '(menu-item "Tree Up" dired-tree-up + :help "Go to first subdirectory header up the tree")) (define-key map [menu-bar subdir up] - '("Up Directory" . dired-up-directory)) + '(menu-item "Up Directory" dired-up-directory + :help "Edit the parent directory")) (define-key map [menu-bar subdir prev-subdir] - '("Prev Subdir" . dired-prev-subdir)) + '(menu-item "Prev Subdir" dired-prev-subdir + :help "Go to previous subdirectory header line")) (define-key map [menu-bar subdir next-subdir] - '("Next Subdir" . dired-next-subdir)) + '(menu-item "Next Subdir" dired-next-subdir + :help "Go to next subdirectory header line")) (define-key map [menu-bar subdir prev-dirline] - '("Prev Dirline" . dired-prev-dirline)) + '(menu-item "Prev Dirline" dired-prev-dirline + :help "Move to next directory-file line")) (define-key map [menu-bar subdir next-dirline] - '("Next Dirline" . dired-next-dirline)) + '(menu-item "Next Dirline" dired-next-dirline + :help "Move to previous directory-file line")) (define-key map [menu-bar subdir insert] - '("Insert This Subdir" . dired-maybe-insert-subdir)) + '(menu-item "Insert This Subdir" dired-maybe-insert-subdir + :help "Insert contents of subdirectory")) (define-key map [menu-bar immediate] (cons "Immediate" (make-sparse-keymap "Immediate"))) (define-key map [menu-bar immediate revert-buffer] - '("Update Buffer" . revert-buffer)) + '(menu-item "Refresh" revert-buffer + :help "Update contents of shown directories")) (define-key map [menu-bar immediate dashes] '("--")) (define-key map [menu-bar immediate backup-diff] - '("Compare with Backup" . dired-backup-diff)) + '(menu-item "Compare with Backup" dired-backup-diff + :help "Diff file at cursor with its latest backup")) (define-key map [menu-bar immediate diff] - '("Diff" . dired-diff)) + '(menu-item "Diff..." dired-diff + :help "Compare file at cursor with another file")) (define-key map [menu-bar immediate view] - '("View This File" . dired-view-file)) + '(menu-item "View This File" dired-view-file + :help "Examine file at cursor in read-only mode")) (define-key map [menu-bar immediate display] - '("Display in Other Window" . dired-display-file)) + '(menu-item "Display in Other Window" dired-display-file + :help "Display file at cursor in other window")) (define-key map [menu-bar immediate find-file-other-window] - '("Find in Other Window" . dired-find-file-other-window)) + '(menu-item "Find in Other Window" dired-find-file-other-window + :help "Edit file at cursor in other window")) (define-key map [menu-bar immediate find-file] - '("Find This File" . dired-find-file)) + '(menu-item "Find This File" dired-find-file + :help "Edit file at cursor")) (define-key map [menu-bar immediate create-directory] - '("Create Directory..." . dired-create-directory)) + '(menu-item "Create Directory..." dired-create-directory)) (define-key map [menu-bar regexp] (cons "Regexp" (make-sparse-keymap "Regexp"))) (define-key map [menu-bar regexp downcase] - '("Downcase" . dired-downcase)) + '(menu-item "Downcase" dired-downcase + ;; When running on plain MS-DOS, there's only one + ;; letter-case for file names. + :enable (or (not (fboundp 'msdos-long-file-names)) + (msdos-long-file-names)) + :help "Rename marked files to lower-case name")) (define-key map [menu-bar regexp upcase] - '("Upcase" . dired-upcase)) + '(menu-item "Upcase" dired-upcase + :enable (or (not (fboundp 'msdos-long-file-names)) + (msdos-long-file-names)) + :help "Rename marked files to upper-case name")) (define-key map [menu-bar regexp hardlink] - '("Hardlink..." . dired-do-hardlink-regexp)) + '(menu-item "Hardlink..." dired-do-hardlink-regexp + :help "Make hard links for files matching regexp")) (define-key map [menu-bar regexp symlink] - '("Symlink..." . dired-do-symlink-regexp)) + '(menu-item "Symlink..." dired-do-symlink-regexp + :visible (fboundp 'make-symbolic-link) + :help "Make symbolic links for files matching regexp")) (define-key map [menu-bar regexp rename] - '("Rename..." . dired-do-rename-regexp)) + '(menu-item "Rename..." dired-do-rename-regexp + :help "Rename marked files matching regexp")) (define-key map [menu-bar regexp copy] - '("Copy..." . dired-do-copy-regexp)) + '(menu-item "Copy..." dired-do-copy-regexp + :help "Copy marked files matching regexp")) (define-key map [menu-bar regexp flag] - '("Flag..." . dired-flag-files-regexp)) + '(menu-item "Flag..." dired-flag-files-regexp + :help "Flag files matching regexp for deletion")) (define-key map [menu-bar regexp mark] - '("Mark..." . dired-mark-files-regexp)) + '(menu-item "Mark..." dired-mark-files-regexp + :help "Mark files matching regexp for future operations")) (define-key map [menu-bar regexp mark-cont] - '("Mark Containing..." . dired-mark-files-containing-regexp)) + '(menu-item "Mark Containing..." dired-mark-files-containing-regexp + :help "Mark files whose contents matches regexp")) (define-key map [menu-bar mark] (cons "Mark" (make-sparse-keymap "Mark"))) (define-key map [menu-bar mark prev] - '("Previous Marked" . dired-prev-marked-file)) + '(menu-item "Previous Marked" dired-prev-marked-file + :help "Move to previous marked file")) (define-key map [menu-bar mark next] - '("Next Marked" . dired-next-marked-file)) + '(menu-item "Next Marked" dired-next-marked-file + :help "Move to next marked file")) (define-key map [menu-bar mark marks] - '("Change Marks..." . dired-change-marks)) + '(menu-item "Change Marks..." dired-change-marks + :help "Replace marker with another character")) (define-key map [menu-bar mark unmark-all] - '("Unmark All" . dired-unmark-all-marks)) + '(menu-item "Unmark All" dired-unmark-all-marks)) (define-key map [menu-bar mark symlinks] - '("Mark Symlinks" . dired-mark-symlinks)) + '(menu-item "Mark Symlinks" dired-mark-symlinks + :visible (fboundp 'make-symbolic-link) + :help "Mark all symbolic links")) (define-key map [menu-bar mark directories] - '("Mark Directories" . dired-mark-directories)) + '(menu-item "Mark Directories" dired-mark-directories + :help "Mark all directories except `.' and `..'")) (define-key map [menu-bar mark directory] - '("Mark Old Backups" . dired-clean-directory)) + '(menu-item "Mark Old Backups" dired-clean-directory + :help "Flag old numbered backups for deletion")) (define-key map [menu-bar mark executables] - '("Mark Executables" . dired-mark-executables)) + '(menu-item "Mark Executables" dired-mark-executables + :help "Mark all executable files")) (define-key map [menu-bar mark garbage-files] - '("Flag Garbage Files" . dired-flag-garbage-files)) + '(menu-item "Flag Garbage Files" dired-flag-garbage-files + :help "Flag unneeded files for deletion")) (define-key map [menu-bar mark backup-files] - '("Flag Backup Files" . dired-flag-backup-files)) + '(menu-item "Flag Backup Files" dired-flag-backup-files + :help "Flag all backup files for deletion")) (define-key map [menu-bar mark auto-save-files] - '("Flag Auto-save Files" . dired-flag-auto-save-files)) + '(menu-item "Flag Auto-save Files" dired-flag-auto-save-files + :help "Flag auto-save files for deletion")) (define-key map [menu-bar mark deletion] - '("Flag" . dired-flag-file-deletion)) + '(menu-item "Flag" dired-flag-file-deletion + :help "Flag current line's file for deletion")) (define-key map [menu-bar mark unmark] - '("Unmark" . dired-unmark)) + '(menu-item "Unmark" dired-unmark + :help "Unmark or unflag current line's file")) (define-key map [menu-bar mark mark] - '("Mark" . dired-mark)) + '(menu-item "Mark" dired-mark + :help "Mark current line's file for future operations")) (define-key map [menu-bar mark toggle-marks] - '("Toggle Marks" . dired-do-toggle)) + '(menu-item "Toggle Marks" dired-do-toggle + :help "Mark unmarked files, unmark marked ones")) (define-key map [menu-bar operate] (cons "Operate" (make-sparse-keymap "Operate"))) (define-key map [menu-bar operate query-replace] - '("Query Replace in Files..." . dired-do-query-replace)) + '(menu-item "Query Replace in Files..." dired-do-query-replace-regexp + :help "Replace regexp in marked files")) (define-key map [menu-bar operate search] - '("Search Files..." . dired-do-search)) + '(menu-item "Search Files..." dired-do-search + :help "Search marked files for regexp")) (define-key map [menu-bar operate chown] - '("Change Owner..." . dired-do-chown)) + '(menu-item "Change Owner..." dired-do-chown + :visible (not (memq system-type '(ms-dos windows-nt))) + :help "Change the owner of marked files")) (define-key map [menu-bar operate chgrp] - '("Change Group..." . dired-do-chgrp)) + '(menu-item "Change Group..." dired-do-chgrp + :visible (not (memq system-type '(ms-dos windows-nt))) + :help "Change the group of marked files")) (define-key map [menu-bar operate chmod] - '("Change Mode..." . dired-do-chmod)) + '(menu-item "Change Mode..." dired-do-chmod + :help "Change mode (attributes) of marked files")) (define-key map [menu-bar operate load] - '("Load" . dired-do-load)) + '(menu-item "Load" dired-do-load + :help "Load marked Emacs Lisp files")) (define-key map [menu-bar operate compile] - '("Byte-compile" . dired-do-byte-compile)) + '(menu-item "Byte-compile" dired-do-byte-compile + :help "Byte-compile marked Emacs Lisp files")) (define-key map [menu-bar operate compress] - '("Compress" . dired-do-compress)) + '(menu-item "Compress" dired-do-compress + :help "Compress/uncompress marked files")) (define-key map [menu-bar operate print] - '("Print" . dired-do-print)) + '(menu-item "Print..." dired-do-print + :help "Ask for print command and print marked files")) (define-key map [menu-bar operate hardlink] - '("Hardlink to..." . dired-do-hardlink)) + '(menu-item "Hardlink to..." dired-do-hardlink + :help "Make hard links for current or marked files")) (define-key map [menu-bar operate symlink] - '("Symlink to..." . dired-do-symlink)) + '(menu-item "Symlink to..." dired-do-symlink + :visible (fboundp 'make-symbolic-link) + :help "Make symbolic links for current or marked files")) (define-key map [menu-bar operate command] - '("Shell Command..." . dired-do-shell-command)) + '(menu-item "Shell Command..." dired-do-shell-command + :help "Run a shell command on each of marked files")) (define-key map [menu-bar operate delete] - '("Delete" . dired-do-delete)) + '(menu-item "Delete" dired-do-delete + :help "Delete current file or all marked files")) (define-key map [menu-bar operate rename] - '("Rename to..." . dired-do-rename)) + '(menu-item "Rename to..." dired-do-rename + :help "Rename current file or move marked files")) (define-key map [menu-bar operate copy] - '("Copy to..." . dired-do-copy)) + '(menu-item "Copy to..." dired-do-copy + :help "Copy current file or all marked files")) (setq dired-mode-map map))) @@ -1272,6 +1366,12 @@ Creates a buffer if necessary." (error "File is a symlink to a nonexistent target") (error "File no longer exists; type `g' to update Dired buffer"))))) +(defun dired-find-alternate-file () + "In dired, visit this file or directory instead of the dired buffer." + (interactive) + (set-buffer-modified-p nil) + (find-alternate-file (dired-get-filename))) + (defun dired-mouse-find-file-other-window (event) "In dired, visit the file or directory name you click on." (interactive "e") @@ -1312,7 +1412,8 @@ otherwise, display it in another buffer." "In dired, return name of file mentioned on this line. Value returned normally includes the directory name. Optional arg LOCALP with value `no-dir' means don't include directory - name in result. A value of t means construct name relative to + name in result. A value of `verbatim' means to return the name exactly as + it occurs in the buffer, and a value of t means construct name relative to `default-directory', which still may contain slashes if in a subdirectory. Optional arg NO-ERROR-IF-NOT-FILEP means return nil if no filename on this line, otherwise an error occurs." @@ -1338,12 +1439,17 @@ Optional arg NO-ERROR-IF-NOT-FILEP means return nil if no filename on file) "\""))))) (and file (file-name-absolute-p file) + ;; A relative file name can start with ~. + ;; Don't treat it as absolute in this context. + (not (eq (aref file 0) ?~)) (setq already-absolute t)) (and file buffer-file-coding-system (not file-name-coding-system) (not default-file-name-coding-system) (setq file (encode-coding-string file buffer-file-coding-system))) (cond + ((eq localp 'verbatim) + file) ((and (eq localp 'no-dir) already-absolute) (file-name-nondirectory file)) ((or already-absolute (eq localp 'no-dir)) @@ -1402,7 +1508,7 @@ DIR must be a directory name, not a file name." ;; weiand: changed: month ends potentially with . or , or ., ;;old (month (concat l l "+ *")) (month (concat l l "+[.]?,? *")) - ;; Recognize any non-ASCII character. + ;; Recognize any non-ASCII character. ;; The purpose is to match a Kanji character. (k "[^\0-\177]") ;; (k "[^\x00-\x7f\x80-\xff]") @@ -1412,19 +1518,30 @@ DIR must be a directory name, not a file name." ;;old (dd "[ 0-3][0-9]") (dd "[ 0-3][0-9][.]?") (HH:MM "[ 0-2][0-9]:[0-5][0-9]") + (seconds "[0-6][0-9]\\([.,][0-9]+\\)?") + (zone "[-+][0-2][0-9][0-5][0-9]") + (iso-mm-dd "[01][0-9]-[0-3][0-9]") + (iso-time (concat HH:MM "\\(:" seconds "\\( ?" zone "\\)?\\)?")) + (iso (concat "\\(\\(" yyyy "-\\)?" iso-mm-dd "[ T]" iso-time + "\\|" yyyy "-" iso-mm-dd " ?\\)")) (western (concat "\\(" month s dd "\\|" dd s month "\\)" ;; weiand: changed: year potentially unaligned ;;old s "\\(" HH:MM "\\|" s yyyy "\\|" yyyy s "\\)")) - s "\\(" HH:MM "\\|" s "?" yyyy "\\|" yyyy s -"\\)")) - (japanese (concat mm k s dd k s "\\(" s HH:MM "\\|" yyyy k "\\)"))) + s "\\(" HH:MM + "\\|" yyyy s s "?" + "\\|" s "?" yyyy + "\\)")) + (japanese + (concat mm k s dd k "?" s "+" "\\(" HH:MM "\\|" yyyy k "?" "\\)"))) ;; The "[0-9]" below requires the previous column to end in a digit. ;; This avoids recognizing `1 may 1997' as a date in the line: ;; -r--r--r-- 1 may 1997 1168 Oct 19 16:49 README + ;; The "[kMGTPEZY]?" below supports "ls -alh" output. ;; The ".*" below finds the last match if there are multiple matches. ;; This avoids recognizing `jservice 10 1024' as a date in the line: ;; drwxr-xr-x 3 jservice 10 1024 Jul 2 1997 esg-host - (concat ".*[0-9]" s "\\(" western "\\|" japanese "\\)" s)) + (concat ".*[0-9][kMGTPEZY]?" + s "\\(" western "\\|" japanese "\\|" iso "\\)" s)) "Regular expression to match up to the file name in a directory listing. The default value is designed to recognize dates and times regardless of the language.") @@ -1512,12 +1629,6 @@ regardless of the language.") ;; Keeping Dired buffers in sync with the filesystem and with each other -(defvar dired-buffers nil - ;; Enlarged by dired-advertise - ;; Queried by function dired-buffers-for-dir. When this detects a - ;; killed buffer, it is removed from this list. - "Alist of expanded directories and their associated dired buffers.") - (defun dired-buffers-for-dir (dir &optional file) ;; Return a list of buffers that dired DIR (top level or in-situ subdir). ;; If FILE is non-nil, include only those whose wildcard pattern (if any) @@ -1683,7 +1794,13 @@ Returns the new value of the alist." (save-excursion (let ((count 0) (buffer-read-only nil) - new-dir-name) + new-dir-name + (R-ftp-base-dir-regex + ;; Used to expand subdirectory names correctly in recursive + ;; ange-ftp listings. + (and (string-match "R" dired-actual-switches) + (string-match "\\`/.*:\\(/.*\\)" default-directory) + (concat "\\`" (match-string 1 default-directory))))) (goto-char (point-min)) (setq dired-subdir-alist nil) (while (and (re-search-forward dired-subdir-regexp nil t) @@ -1697,7 +1814,15 @@ Returns the new value of the alist." (save-excursion (goto-char (match-beginning 1)) (setq new-dir-name - (expand-file-name (buffer-substring (point) (match-end 1)))) + (buffer-substring-no-properties (point) (match-end 1)) + new-dir-name + (save-match-data + (if (and R-ftp-base-dir-regex + (not (string= new-dir-name default-directory)) + (string-match R-ftp-base-dir-regex new-dir-name)) + (concat default-directory + (substring new-dir-name (match-end 0))) + (expand-file-name new-dir-name)))) (delete-region (point) (match-end 1)) (insert new-dir-name)) (setq count (1+ count)) @@ -2025,25 +2150,25 @@ Command symbols are `byte-compile', `chgrp', `chmod', `chown', `compress', `uncompress'.") (defun dired-mark-pop-up (bufname op-symbol files function &rest args) - ;;"Args BUFNAME OP-SYMBOL FILES FUNCTION &rest ARGS. - ;;Return FUNCTION's result on ARGS after popping up a window (in a buffer - ;;named BUFNAME, nil gives \" *Marked Files*\") showing the marked - ;;files. Uses function `dired-pop-to-buffer' to do that. - ;; FUNCTION should not manipulate files. - ;; It should only read input (an argument or confirmation). - ;;The window is not shown if there is just one file or - ;; OP-SYMBOL is a member of the list in `dired-no-confirm'. - ;;FILES is the list of marked files." + "Args BUFNAME OP-SYMBOL FILES FUNCTION &rest ARGS. +Return FUNCTION's result on ARGS after popping up a window (in a buffer +named BUFNAME, nil gives \" *Marked Files*\") showing the marked +files. Uses function `dired-pop-to-buffer' to do that. + FUNCTION should not manipulate files. + It should only read input (an argument or confirmation). +The window is not shown if there is just one file or + OP-SYMBOL is a member of the list in `dired-no-confirm'. +FILES is the list of marked files." (or bufname (setq bufname " *Marked Files*")) (if (or (eq dired-no-confirm t) (memq op-symbol dired-no-confirm) (= (length files) 1)) (apply function args) - (save-excursion - (set-buffer (get-buffer-create bufname)) + (with-current-buffer (get-buffer-create bufname) (erase-buffer) (dired-format-columns-of-files files) - (remove-text-properties (point-min) (point-max) '(mouse-face))) + (remove-text-properties (point-min) (point-max) + '(mouse-face nil help-echo nil))) (save-window-excursion (dired-pop-to-buffer bufname) (apply function args)))) @@ -2105,7 +2230,7 @@ Command symbols are `byte-compile', `chgrp', `chmod', `chown', `compress', ;; Point must be at beginning of line ;; Should be equivalent to (save-excursion (not (dired-move-to-filename))) ;; but is about 1.5..2.0 times as fast. (Actually that's not worth it) - (or (looking-at "^$\\|^. *$\\|^. total\\|^. wildcard") + (or (looking-at "^$\\|^. *$\\|^. total\\|^. wildcard\\|^. used\\|^. find") (and (looking-at dired-subdir-regexp) (save-excursion (not (dired-move-to-filename)))))) @@ -2535,6 +2660,7 @@ With a prefix argument you can edit the current listing switches instead." (dired-sort-set-modeline) (revert-buffer)) +;; Some user code loads dired especially for this. (defun dired-replace-in-string (regexp newtext string) ;; Replace REGEXP with NEWTEXT everywhere in STRING and return result. ;; NEWTEXT is taken literally---no \\DIGIT escapes will be recognized. @@ -2551,9 +2677,45 @@ With a prefix argument you can edit the current listing switches instead." ;; `dired-sort-by-date-regexp' or `dired-sort-by-name-regexp' set the ;; minor mode accordingly, others appear literally in the mode line. ;; With optional second arg NO-REVERT, don't refresh the listing afterwards. + (dired-sort-R-check switches) (setq dired-actual-switches switches) (if (eq major-mode 'dired-mode) (dired-sort-set-modeline)) (or no-revert (revert-buffer))) + +(make-variable-buffer-local + (defvar dired-subdir-alist-pre-R nil + "Value of `dired-subdir-alist' before -R switch added.")) + +(defun dired-sort-R-check (switches) + "Additional processing of -R in ls option string SWITCHES. +Saves `dired-subdir-alist' when R is set and restores saved value +minus any directories explicitly deleted when R is cleared. +To be called first in body of `dired-sort-other', etc." + (cond + ((and (string-match "R" switches) + (not (string-match "R" dired-actual-switches))) + ;; Adding -R to ls switches -- save `dired-subdir-alist': + (setq dired-subdir-alist-pre-R dired-subdir-alist)) + ((and (string-match "R" dired-actual-switches) + (not (string-match "R" switches))) + ;; Deleting -R from ls switches -- revert to pre-R subdirs + ;; that are still present: + (setq dired-subdir-alist + (if dired-subdir-alist-pre-R + (let (subdirs) + (while dired-subdir-alist-pre-R + (if (assoc (caar dired-subdir-alist-pre-R) + dired-subdir-alist) + ;; subdir still present... + (setq subdirs + (cons (car dired-subdir-alist-pre-R) + subdirs))) + (setq dired-subdir-alist-pre-R + (cdr dired-subdir-alist-pre-R))) + (reverse subdirs)) + ;; No pre-R subdir alist, so revert to main directory + ;; listing: + (list (car (reverse dired-subdir-alist)))))))) ;; To make this file smaller, the less common commands ;; go in a separate file. But autoload them here @@ -2561,7 +2723,8 @@ With a prefix argument you can edit the current listing switches instead." (autoload 'dired-diff "dired-aux" "Compare file at point with file FILE using `diff'. -FILE defaults to the file at the mark. +FILE defaults to the file at the mark. (That's the mark set by +\\[set-mark-command], not by Dired's \\[dired-mark] command.) The prompted-for file is the first file given to `diff'." t) @@ -2763,6 +2926,12 @@ 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." t) + +(autoload 'dired-show-file-type "dired-aux" + "Print the type of FILE, according to the `file' command. +If FILE is a symbolic link and the optional argument DEREF-SYMLINKS is +true then the type of the file linked to by FILE is printed instead." + t) (if (eq system-type 'vax-vms) (load "dired-vms"))