summaryrefslogtreecommitdiff
path: root/lisp/wdired.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/wdired.el')
-rw-r--r--lisp/wdired.el87
1 files changed, 57 insertions, 30 deletions
diff --git a/lisp/wdired.el b/lisp/wdired.el
index cf73b7bf249..d2a298bd25b 100644
--- a/lisp/wdired.el
+++ b/lisp/wdired.el
@@ -255,6 +255,7 @@ See `wdired-mode'."
(setq buffer-read-only nil)
(dired-unadvertise default-directory)
(add-hook 'kill-buffer-hook 'wdired-check-kill-buffer nil t)
+ (add-hook 'after-change-functions 'wdired--restore-dired-filename-prop nil t)
(setq major-mode 'wdired-mode)
(setq mode-name "Editable Dired")
(setq revert-buffer-function 'wdired-revert)
@@ -363,6 +364,7 @@ non-nil means return old filename."
(setq mode-name "Dired")
(dired-advertise)
(remove-hook 'kill-buffer-hook 'wdired-check-kill-buffer t)
+ (remove-hook 'after-change-functions 'wdired--restore-dired-filename-prop t)
(set (make-local-variable 'revert-buffer-function) 'dired-revert))
@@ -381,7 +383,6 @@ non-nil means return old filename."
(defun wdired-finish-edit ()
"Actually rename files based on your editing in the Dired buffer."
(interactive)
- (wdired-change-to-dired-mode)
(let ((changes nil)
(errors 0)
files-deleted
@@ -423,6 +424,11 @@ non-nil means return old filename."
(forward-line -1)))
(when files-renamed
(setq errors (+ errors (wdired-do-renames files-renamed))))
+ ;; We have to be in wdired-mode when wdired-do-renames is executed
+ ;; so that wdired--restore-dired-filename-prop runs, but we have
+ ;; to change back to dired-mode before reverting the buffer to
+ ;; avoid using wdired-revert, which changes back to wdired-mode.
+ (wdired-change-to-dired-mode)
(if changes
(progn
;; If we are displaying a single file (rather than the
@@ -543,39 +549,25 @@ and proceed depending on the answer."
(goto-char (point-max))
(forward-line -1)
(let ((done nil)
- (failed t)
+ (failed t)
curr-filename)
(while (and (not done) (not (bobp)))
(setq curr-filename (wdired-get-filename nil t))
(if (equal curr-filename filename-ori)
- (unwind-protect
- (progn
- (setq done t)
- (let ((inhibit-read-only t))
- ;; Remove dired-filename text property in order to
- ;; find filename-new when it only partially
- ;; replaces filename-ori (bug#32173); the text
- ;; property is added again when renaming succeeds.
- (remove-text-properties
- (line-beginning-position) (line-end-position)
- '(dired-filename nil))
- (dired-move-to-filename)
- (search-forward (wdired-get-filename t) nil t)
- (replace-match (file-name-nondirectory filename-ori) t t))
- (dired-do-create-files-regexp
- (function dired-rename-file)
- "Move" 1 ".*" filename-new nil t)
- (setq failed nil))
- ;; If user quits before renaming succeeds, restore the
- ;; dired-filename text property.
- (when failed
- (beginning-of-line)
- (let ((beg (re-search-forward
- directory-listing-before-filename-regexp
- (line-end-position) t))
- (end (dired-move-to-end-of-filename))
- (inhibit-read-only t))
- (add-text-properties beg end '(dired-filename t)))))
+ (unwind-protect
+ (progn
+ (setq done t)
+ (let ((inhibit-read-only t))
+ (dired-move-to-filename)
+ (search-forward (wdired-get-filename t) nil t)
+ (replace-match (file-name-nondirectory filename-ori) t t))
+ (dired-do-create-files-regexp
+ (function dired-rename-file)
+ "Move" 1 ".*" filename-new nil t)
+ (setq failed nil))
+ ;; If user types C-g when prompted to change the file
+ ;; name, make sure we return to dired-mode.
+ (when failed (wdired-change-to-dired-mode)))
(forward-line -1))))))
;; marks a list of files for deletion
@@ -606,6 +598,41 @@ Optional arguments are ignored."
(not (y-or-n-p "Buffer changed. Discard changes and kill buffer? ")))
(error "Error")))
+;; Added to after-change-functions in wdired-change-to-wdired-mode to
+;; ensure that, on editing a file name, new characters get the
+;; dired-filename text property, which allows functions that look for
+;; this property (e.g. dired-isearch-filenames) to work in wdired-mode
+;; and also avoids an error with non-nil wdired-use-interactive-rename
+;; (bug#32173).
+(defun wdired--restore-dired-filename-prop (beg end _len)
+ (save-match-data
+ (save-excursion
+ (let ((lep (line-end-position)))
+ (beginning-of-line)
+ (when (re-search-forward
+ directory-listing-before-filename-regexp lep t)
+ (setq beg (point)
+ end (if (or
+ ;; If the file is a symlink, put the
+ ;; dired-filename property only on the link
+ ;; name. (Using (file-symlink-p
+ ;; (dired-get-filename)) fails in
+ ;; wdired-mode, bug#32673.)
+ (and (re-search-backward
+ dired-permission-flags-regexp nil t)
+ (looking-at "l")
+ (search-forward " -> " lep t))
+ ;; When dired-listing-switches includes "F"
+ ;; or "classify", don't treat appended
+ ;; indicator characters as part of the file
+ ;; name (bug#34915).
+ (and (dired-check-switches dired-actual-switches
+ "F" "classify")
+ (re-search-forward "[*/@|=>]$" lep t)))
+ (goto-char (match-beginning 0))
+ lep))
+ (put-text-property beg end 'dired-filename t))))))
+
(defun wdired-next-line (arg)
"Move down lines then position at filename or the current column.
See `wdired-use-dired-vertical-movement'. Optional prefix ARG