diff options
Diffstat (limited to 'lisp/dired.el')
-rw-r--r-- | lisp/dired.el | 113 |
1 files changed, 82 insertions, 31 deletions
diff --git a/lisp/dired.el b/lisp/dired.el index 579de723df6..e5dc8623a49 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -201,8 +201,10 @@ The target is used in the prompt for file copy, rename etc." ; These variables were deleted and the replacements are on files.el. ; We leave aliases behind for back-compatibility. -(defvaralias 'dired-free-space-program 'directory-free-space-program) -(defvaralias 'dired-free-space-args 'directory-free-space-args) +(define-obsolete-variable-alias 'dired-free-space-program + 'directory-free-space-program "27.1") +(define-obsolete-variable-alias 'dired-free-space-args + 'directory-free-space-args "27.1") ;;; Hook variables @@ -646,7 +648,7 @@ marked file, return (t FILENAME) instead of (FILENAME)." ;; save-excursion loses, again (dired-move-to-filename))) -(defun dired-get-marked-files (&optional localp arg filter distinguish-one-marked) +(defun dired-get-marked-files (&optional localp arg filter distinguish-one-marked error) "Return the marked files' names as list of strings. The list is in the same order as the buffer, that is, the car is the first marked file. @@ -663,7 +665,10 @@ Optional third argument FILTER, if non-nil, is a function to select If DISTINGUISH-ONE-MARKED is non-nil, then if we find just one marked file, return (t FILENAME) instead of (FILENAME). -Don't use that together with FILTER." +Don't use that together with FILTER. + +If ERROR is non-nil, signal an error when the list of found files is empty. +ERROR can be a string with the error message." (let ((all-of-them (save-excursion (delq nil (dired-map-over-marks @@ -673,13 +678,17 @@ Don't use that together with FILTER." (when (equal all-of-them '(t)) (setq all-of-them nil)) (if (not filter) - (if (and distinguish-one-marked (eq (car all-of-them) t)) - all-of-them - (nreverse all-of-them)) + (setq result + (if (and distinguish-one-marked (eq (car all-of-them) t)) + all-of-them + (nreverse all-of-them))) (dolist (file all-of-them) (if (funcall filter file) - (push file result))) - result))) + (push file result)))) + (when (and (null result) error) + (user-error (if (stringp error) error "No files specified"))) + result)) + ;; The dired command @@ -841,17 +850,21 @@ If DIRNAME is already in a Dired buffer, that buffer is used without refresh." (not (let ((attributes (file-attributes dirname)) (modtime (visited-file-modtime))) (or (eq modtime 0) - (not (eq (car attributes) t)) - (equal (nth 5 attributes) modtime))))) + (not (eq (file-attribute-type attributes) t)) + (equal (file-attribute-modification-time attributes) modtime))))) + +(defvar auto-revert-remote-files) (defun dired-buffer-stale-p (&optional noconfirm) "Return non-nil if current Dired buffer needs updating. -If NOCONFIRM is non-nil, then this function always returns nil -for a remote directory. This feature is used by Auto Revert mode." +If NOCONFIRM is non-nil, then this function returns nil for a +remote directory, unless `auto-revert-remote-files' is non-nil. +This feature is used by Auto Revert mode." (let ((dirname (if (consp dired-directory) (car dired-directory) dired-directory))) (and (stringp dirname) - (not (when noconfirm (file-remote-p dirname))) + (not (when noconfirm (and (not auto-revert-remote-files) + (file-remote-p dirname)))) (file-readable-p dirname) ;; Do not auto-revert when the dired buffer can be currently ;; written by the user as in `wdired-mode'. @@ -1079,7 +1092,8 @@ wildcards, erases the buffer, and builds the subdir-alist anew (dired-build-subdir-alist) (let ((attributes (file-attributes dirname))) (if (eq (car attributes) t) - (set-visited-file-modtime (nth 5 attributes)))) + (set-visited-file-modtime (file-attribute-modification-time + attributes)))) (set-buffer-modified-p nil) ;; No need to narrow since the whole buffer contains just ;; dired-readin's output, nothing else. The hook can @@ -1433,7 +1447,8 @@ ARG and NOCONFIRM, passed from `revert-buffer', are ignored." (dolist (dir hidden-subdirs) (if (dired-goto-subdir dir) (dired-hide-subdir 1)))) - (unless modflag (restore-buffer-modified-p nil))) + (unless modflag (restore-buffer-modified-p nil)) + (hack-dir-local-variables-non-file-buffer)) ;; outside of the let scope ;;; Might as well not override the user if the user changed this. ;;; (setq buffer-read-only t) @@ -1463,12 +1478,36 @@ change; the point does." (list w (dired-get-filename nil t) (line-number-at-pos (window-point w))))) - (get-buffer-window-list nil 0 t)))) + (get-buffer-window-list nil 0 t)) + ;; For each window that showed the current buffer before, scan its + ;; list of previous buffers. For each association thus found save + ;; a triple <point, name, line> where 'point' is that window's + ;; window-point marker stored in the window's list of previous + ;; buffers, 'name' is the filename at the position of 'point' and + ;; 'line' is the line number at the position of 'point'. + (let ((buffer (current-buffer)) + prevs) + (walk-windows + (lambda (window) + (let ((prev (assq buffer (window-prev-buffers window)))) + (when prev + (with-current-buffer buffer + (save-excursion + (goto-char (nth 2 prev)) + (setq prevs + (cons + (list (nth 2 prev) + (dired-get-filename nil t) + (line-number-at-pos (point))) + prevs))))))) + 'nomini t) + prevs))) (defun dired-restore-positions (positions) "Restore POSITIONS saved with `dired-save-positions'." (let* ((buf-file-pos (nth 0 positions)) - (buffer (nth 0 buf-file-pos))) + (buffer (nth 0 buf-file-pos)) + (prevs (nth 2 positions))) (unless (and (nth 1 buf-file-pos) (dired-goto-file (nth 1 buf-file-pos))) (goto-char (point-min)) @@ -1482,7 +1521,21 @@ change; the point does." (dired-goto-file (nth 1 win-file-pos))) (goto-char (point-min)) (forward-line (1- (nth 2 win-file-pos))) - (dired-move-to-filename))))))) + (dired-move-to-filename))))) + (when prevs + (with-current-buffer buffer + (save-excursion + (dolist (prev prevs) + (let ((point (nth 0 prev))) + ;; Sanity check of the point marker. + (when (and (markerp point) + (eq (marker-buffer point) buffer)) + (unless (and (nth 0 prev) + (dired-goto-file (nth 1 prev))) + (goto-char (point-min)) + (forward-line (1- (nth 2 prev)))) + (dired-move-to-filename) + (move-marker point (point) buffer))))))))) (defun dired-remember-marks (beg end) "Return alist of files and their marks, from BEG to END." @@ -1791,6 +1844,9 @@ Do so according to the former subdir alist OLD-SUBDIR-ALIST." (define-key map [menu-bar immediate create-directory] '(menu-item "Create Directory..." dired-create-directory :help "Create a directory")) + (define-key map [menu-bar immediate create-empty-file] + '(menu-item "Create Empty file..." dired-create-empty-file + :help "Create an empty file")) (define-key map [menu-bar immediate wdired-mode] '(menu-item "Edit File Names" wdired-change-to-wdired-mode :help "Put a Dired buffer in a mode in which filenames are editable" @@ -2201,7 +2257,7 @@ directory in another window." (let ((raw (dired-get-filename nil t)) file-name) (if (null raw) - (error "No file on this line")) + (user-error "No file on this line")) (setq file-name (file-name-sans-versions raw t)) (if (file-exists-p file-name) file-name @@ -2346,12 +2402,7 @@ Otherwise, an error occurs in these cases." (setq start (match-end 0)))))) ;; Hence we don't need to worry about converting `\\' back to `\'. - (setq file (read (concat "\"" file "\""))) - ;; The above `read' will return a unibyte string if FILE - ;; contains eight-bit-control/graphic characters. - (if (and enable-multibyte-characters - (not (multibyte-string-p file))) - (setq file (string-to-multibyte file))))) + (setq file (read (concat "\"" file "\""))))) (and file (files--name-absolute-system-p file) (setq already-absolute t)) (cond @@ -3033,10 +3084,10 @@ TRASH non-nil means to trash the file instead of deleting, provided ("no" ?n "skip to next") ("all" ?! "delete all remaining directories with no more questions") ("quit" ?q "exit"))) - ('"all" (setq recursive 'always dired-recursive-deletes recursive)) - ('"yes" (if (eq recursive 'top) (setq recursive 'always))) - ('"no" (setq recursive nil)) - ('"quit" (keyboard-quit)) + ("all" (setq recursive 'always dired-recursive-deletes recursive)) + ("yes" (if (eq recursive 'top) (setq recursive 'always))) + ("no" (setq recursive nil)) + ("quit" (keyboard-quit)) (_ (keyboard-quit))))) ; catch all unknown answers (setq recursive nil)) ; Empty dir or recursive is nil. (delete-directory file recursive trash)))) @@ -3095,7 +3146,7 @@ non-empty directories is allowed." (dired-recursive-deletes dired-recursive-deletes) (trashing (and trash delete-by-moving-to-trash))) ;; canonicalize file list for pop up - (setq files (nreverse (mapcar #'dired-make-relative files))) + (setq files (mapcar #'dired-make-relative files)) (if (dired-mark-pop-up " *Deletions*" 'delete files dired-deletion-confirmer (format "%s %s " |