diff options
| author | Stephen Berman | 2018-07-29 01:14:41 +0200 |
|---|---|---|
| committer | Stephen Berman | 2018-07-29 01:14:41 +0200 |
| commit | 8a563d9762670e9eec9420ba2dc12075c1dd0a8c (patch) | |
| tree | ca1153beee6fbec6c33fb24d02c600bb4d77d9d1 | |
| parent | db80851a1f10d73f0b2c12299c3d77716bb8425a (diff) | |
| download | emacs-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.el | 48 |
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. |
| 591 | See `wdired-use-dired-vertical-movement'. Optional prefix ARG | 619 | See `wdired-use-dired-vertical-movement'. Optional prefix ARG |