aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Berman2018-07-29 01:14:41 +0200
committerStephen Berman2018-07-29 01:14:41 +0200
commit8a563d9762670e9eec9420ba2dc12075c1dd0a8c (patch)
treeca1153beee6fbec6c33fb24d02c600bb4d77d9d1
parentdb80851a1f10d73f0b2c12299c3d77716bb8425a (diff)
downloademacs-8a563d9762670e9eec9420ba2dc12075c1dd0a8c.tar.gz
emacs-8a563d9762670e9eec9420ba2dc12075c1dd0a8c.zip
Fix bugs in wdired.el involving dired-filename property
After every change in wdired-mode, put the dired-filename text property on the file name. This ensures that changing some but not all characters in the name succeeds with non-nil wdired-use-interactive-rename (bug#32173) and it also ensures that changed names can be found (e.g. by dired-isearch-filenames) while still in wdired-mode. * lisp/wdired.el (wdired--restore-dired-filename-prop): New function. (wdired-change-to-wdired-mode): Add it to after-change-functions. (wdired-change-to-dired-mode): Remove it from after-change-functions. (wdired-finish-edit): Move invocation of wdired-change-to-dired-mode below invocation of wdired-do-renames, so that the latter runs wdired--restore-dired-filename-prop, but above the invocation of revert-buffer to avoid using wdired-revert, which changes back to wdired-mode. (wdired-search-and-rename): Wrap renaming in unwind-protect and if user types C-g when prompted to change the file name, make sure we return to dired-mode.
-rw-r--r--lisp/wdired.el48
1 files changed, 38 insertions, 10 deletions
diff --git a/lisp/wdired.el b/lisp/wdired.el
index bb60e777769..1d0106775d6 100644
--- a/lisp/wdired.el
+++ b/lisp/wdired.el
@@ -255,6 +255,7 @@ See `wdired-mode'."
255 (setq buffer-read-only nil) 255 (setq buffer-read-only nil)
256 (dired-unadvertise default-directory) 256 (dired-unadvertise default-directory)
257 (add-hook 'kill-buffer-hook 'wdired-check-kill-buffer nil t) 257 (add-hook 'kill-buffer-hook 'wdired-check-kill-buffer nil t)
258 (add-hook 'after-change-functions 'wdired--restore-dired-filename-prop nil t)
258 (setq major-mode 'wdired-mode) 259 (setq major-mode 'wdired-mode)
259 (setq mode-name "Editable Dired") 260 (setq mode-name "Editable Dired")
260 (setq revert-buffer-function 'wdired-revert) 261 (setq revert-buffer-function 'wdired-revert)
@@ -363,6 +364,7 @@ non-nil means return old filename."
363 (setq mode-name "Dired") 364 (setq mode-name "Dired")
364 (dired-advertise) 365 (dired-advertise)
365 (remove-hook 'kill-buffer-hook 'wdired-check-kill-buffer t) 366 (remove-hook 'kill-buffer-hook 'wdired-check-kill-buffer t)
367 (remove-hook 'after-change-functions 'wdired--restore-dired-filename-prop t)
366 (set (make-local-variable 'revert-buffer-function) 'dired-revert)) 368 (set (make-local-variable 'revert-buffer-function) 'dired-revert))
367 369
368 370
@@ -381,7 +383,6 @@ non-nil means return old filename."
381(defun wdired-finish-edit () 383(defun wdired-finish-edit ()
382 "Actually rename files based on your editing in the Dired buffer." 384 "Actually rename files based on your editing in the Dired buffer."
383 (interactive) 385 (interactive)
384 (wdired-change-to-dired-mode)
385 (let ((changes nil) 386 (let ((changes nil)
386 (errors 0) 387 (errors 0)
387 files-deleted 388 files-deleted
@@ -423,6 +424,11 @@ non-nil means return old filename."
423 (forward-line -1))) 424 (forward-line -1)))
424 (when files-renamed 425 (when files-renamed
425 (setq errors (+ errors (wdired-do-renames files-renamed)))) 426 (setq errors (+ errors (wdired-do-renames files-renamed))))
427 ;; We have to be in wdired-mode when wdired-do-renames is executed
428 ;; so that wdired--restore-dired-filename-prop runs, but we have
429 ;; to change back to dired-mode before reverting the buffer to
430 ;; avoid using wdired-revert, which changes back to wdired-mode.
431 (wdired-change-to-dired-mode)
426 (if changes 432 (if changes
427 (progn 433 (progn
428 ;; If we are displaying a single file (rather than the 434 ;; If we are displaying a single file (rather than the
@@ -543,19 +549,25 @@ and proceed depending on the answer."
543 (goto-char (point-max)) 549 (goto-char (point-max))
544 (forward-line -1) 550 (forward-line -1)
545 (let ((done nil) 551 (let ((done nil)
552 (failed t)
546 curr-filename) 553 curr-filename)
547 (while (and (not done) (not (bobp))) 554 (while (and (not done) (not (bobp)))
548 (setq curr-filename (wdired-get-filename nil t)) 555 (setq curr-filename (wdired-get-filename nil t))
549 (if (equal curr-filename filename-ori) 556 (if (equal curr-filename filename-ori)
550 (progn 557 (unwind-protect
551 (setq done t) 558 (progn
552 (let ((inhibit-read-only t)) 559 (setq done t)
553 (dired-move-to-filename) 560 (let ((inhibit-read-only t))
554 (search-forward (wdired-get-filename t) nil t) 561 (dired-move-to-filename)
555 (replace-match (file-name-nondirectory filename-ori) t t)) 562 (search-forward (wdired-get-filename t) nil t)
556 (dired-do-create-files-regexp 563 (replace-match (file-name-nondirectory filename-ori) t t))
557 (function dired-rename-file) 564 (dired-do-create-files-regexp
558 "Move" 1 ".*" filename-new nil t)) 565 (function dired-rename-file)
566 "Move" 1 ".*" filename-new nil t)
567 (setq failed nil))
568 ;; If user types C-g when prompted to change the file
569 ;; name, make sure we return to dired-mode.
570 (when failed (wdired-change-to-dired-mode)))
559 (forward-line -1)))))) 571 (forward-line -1))))))
560 572
561;; marks a list of files for deletion 573;; marks a list of files for deletion
@@ -586,6 +598,22 @@ Optional arguments are ignored."
586 (not (y-or-n-p "Buffer changed. Discard changes and kill buffer? "))) 598 (not (y-or-n-p "Buffer changed. Discard changes and kill buffer? ")))
587 (error "Error"))) 599 (error "Error")))
588 600
601;; Added to after-change-functions in wdired-change-to-wdired-mode to
602;; ensure that, on editing a file name, new characters get the
603;; dired-filename text property, which allows functions that look for
604;; this property (e.g. dired-isearch-filenames) to work in wdired-mode
605;; and also avoids an error with non-nil wdired-use-interactive-rename
606;; (bug#32173).
607(defun wdired--restore-dired-filename-prop (beg end _len)
608 (save-match-data
609 (save-excursion
610 (beginning-of-line)
611 (when (re-search-forward directory-listing-before-filename-regexp
612 (line-end-position) t)
613 (setq beg (point)
614 end (line-end-position))
615 (put-text-property beg end 'dired-filename t)))))
616
589(defun wdired-next-line (arg) 617(defun wdired-next-line (arg)
590 "Move down lines then position at filename or the current column. 618 "Move down lines then position at filename or the current column.
591See `wdired-use-dired-vertical-movement'. Optional prefix ARG 619See `wdired-use-dired-vertical-movement'. Optional prefix ARG