summaryrefslogtreecommitdiff
path: root/lisp/dired.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/dired.el')
-rw-r--r--lisp/dired.el113
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 "