diff options
| author | Stefan Monnier | 2008-06-14 17:00:01 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2008-06-14 17:00:01 +0000 |
| commit | f6d346c940bfd988b49881ef78bf59afcd2cdeb9 (patch) | |
| tree | c96d9a5cf92cc0f683f45925269f7968c9297c01 | |
| parent | 508021c76d19608339c44aca2dbd48856dbde313 (diff) | |
| download | emacs-f6d346c940bfd988b49881ef78bf59afcd2cdeb9.tar.gz emacs-f6d346c940bfd988b49881ef78bf59afcd2cdeb9.zip | |
(wdired-do-renames): New function.
(wdired-finish-edit): Use it to.
(wdired-preprocess-files): Don't hardcode (point-min) == 1.
| -rw-r--r-- | lisp/ChangeLog | 6 | ||||
| -rw-r--r-- | lisp/wdired.el | 112 |
2 files changed, 85 insertions, 33 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index f686fb60322..cbf4e51cfad 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,11 @@ | |||
| 1 | 2008-06-14 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2008-06-14 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 2 | ||
| 3 | * wdired.el (wdired-do-renames): New function. | ||
| 4 | (wdired-finish-edit): Use it to. | ||
| 5 | (wdired-preprocess-files): Don't hardcode (point-min) == 1. | ||
| 6 | |||
| 7 | 2008-06-14 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 8 | |||
| 3 | * info.el (Info-insert-breadcrumbs): Don't break in apropos and toc. | 9 | * info.el (Info-insert-breadcrumbs): Don't break in apropos and toc. |
| 4 | 10 | ||
| 5 | 2008-06-14 Martin Rudalics <rudalics@gmx.at> | 11 | 2008-06-14 Martin Rudalics <rudalics@gmx.at> |
diff --git a/lisp/wdired.el b/lisp/wdired.el index 91db7aeb2e9..fe14bce1785 100644 --- a/lisp/wdired.el +++ b/lisp/wdired.el | |||
| @@ -271,7 +271,7 @@ or \\[wdired-abort-changes] to abort changes"))) | |||
| 271 | ;; Protect the buffer so only the filenames can be changed, and put | 271 | ;; Protect the buffer so only the filenames can be changed, and put |
| 272 | ;; properties so filenames (old and new) can be easily found. | 272 | ;; properties so filenames (old and new) can be easily found. |
| 273 | (defun wdired-preprocess-files () | 273 | (defun wdired-preprocess-files () |
| 274 | (put-text-property 1 2 'front-sticky t) | 274 | (put-text-property (point-min) (1+ (point-min))'front-sticky t) |
| 275 | (save-excursion | 275 | (save-excursion |
| 276 | (goto-char (point-min)) | 276 | (goto-char (point-min)) |
| 277 | (let ((b-protection (point)) | 277 | (let ((b-protection (point)) |
| @@ -368,9 +368,9 @@ non-nil means return old filename." | |||
| 368 | "Actually rename files based on your editing in the Dired buffer." | 368 | "Actually rename files based on your editing in the Dired buffer." |
| 369 | (interactive) | 369 | (interactive) |
| 370 | (wdired-change-to-dired-mode) | 370 | (wdired-change-to-dired-mode) |
| 371 | (let ((overwrite (or (not wdired-confirm-overwrite) 1)) | 371 | (let ((changes nil) |
| 372 | (changes nil) | ||
| 373 | (files-deleted nil) | 372 | (files-deleted nil) |
| 373 | (file-renames ()) | ||
| 374 | (errors 0) | 374 | (errors 0) |
| 375 | file-ori file-new tmp-value) | 375 | file-ori file-new tmp-value) |
| 376 | (save-excursion | 376 | (save-excursion |
| @@ -388,29 +388,16 @@ non-nil means return old filename." | |||
| 388 | (while (not (bobp)) | 388 | (while (not (bobp)) |
| 389 | (setq file-ori (wdired-get-filename nil t)) | 389 | (setq file-ori (wdired-get-filename nil t)) |
| 390 | (when file-ori | 390 | (when file-ori |
| 391 | (setq file-new (wdired-get-filename))) | 391 | (setq file-new (wdired-get-filename)) |
| 392 | (when (and file-ori (not (equal file-new file-ori))) | 392 | (unless (equal file-new file-ori) |
| 393 | (setq changes t) | 393 | (setq changes t) |
| 394 | (if (not file-new) ;empty filename! | 394 | (if (not file-new) ;empty filename! |
| 395 | (setq files-deleted (cons file-ori files-deleted)) | 395 | (push file-ori files-deleted) |
| 396 | (setq file-new (substitute-in-file-name file-new)) | 396 | (push (cons file-ori (substitute-in-file-name file-new)) |
| 397 | (if wdired-use-interactive-rename | 397 | file-renames)))) |
| 398 | (wdired-search-and-rename file-ori file-new) | ||
| 399 | ;; If dired-rename-file autoloads dired-aux while | ||
| 400 | ;; dired-backup-overwrite is locally bound, | ||
| 401 | ;; dired-backup-overwrite won't be initialized. | ||
| 402 | ;; So we must ensure dired-aux is loaded. | ||
| 403 | (require 'dired-aux) | ||
| 404 | (condition-case err | ||
| 405 | (let ((dired-backup-overwrite nil)) | ||
| 406 | (dired-rename-file file-ori file-new | ||
| 407 | overwrite)) | ||
| 408 | (error | ||
| 409 | (setq errors (1+ errors)) | ||
| 410 | (dired-log (concat "Rename `" file-ori "' to `" | ||
| 411 | file-new "' failed:\n%s\n") | ||
| 412 | err)))))) | ||
| 413 | (forward-line -1))) | 398 | (forward-line -1))) |
| 399 | (when file-renames | ||
| 400 | (setq errors (+ errors (wdired-do-renames file-renames)))) | ||
| 414 | (if changes | 401 | (if changes |
| 415 | (revert-buffer) ;The "revert" is necessary to re-sort the buffer | 402 | (revert-buffer) ;The "revert" is necessary to re-sort the buffer |
| 416 | (let ((inhibit-read-only t)) | 403 | (let ((inhibit-read-only t)) |
| @@ -426,6 +413,67 @@ non-nil means return old filename." | |||
| 426 | (set-buffer-modified-p nil) | 413 | (set-buffer-modified-p nil) |
| 427 | (setq buffer-undo-list nil)) | 414 | (setq buffer-undo-list nil)) |
| 428 | 415 | ||
| 416 | (defun wdired-do-renames (renames) | ||
| 417 | "Perform RENAMES in parallel." | ||
| 418 | (let ((residue ()) | ||
| 419 | (progress nil) | ||
| 420 | (errors 0) | ||
| 421 | (overwrite (or (not wdired-confirm-overwrite) 1))) | ||
| 422 | (while (or renames | ||
| 423 | ;; We've done one round through the renames, we have found | ||
| 424 | ;; some residue, but we also made some progress, so maybe | ||
| 425 | ;; some of the residue were resolved: try again. | ||
| 426 | (prog1 (setq renames residue) | ||
| 427 | (setq progress nil) | ||
| 428 | (setq residue nil))) | ||
| 429 | (let* ((rename (pop renames)) | ||
| 430 | (file-new (cdr rename))) | ||
| 431 | (cond | ||
| 432 | ((rassoc file-new renames) | ||
| 433 | (error "Trying to rename 2 files to the same name")) | ||
| 434 | ((assoc file-new renames) | ||
| 435 | ;; Renaming to a file name that already exists but will itself be | ||
| 436 | ;; renamed as well. Let's wait until that one gets renamed. | ||
| 437 | (push rename residue)) | ||
| 438 | ((and (assoc file-new residue) | ||
| 439 | ;; Make sure the file really exists: if it doesn't it's | ||
| 440 | ;; not really a conflict. It might be a temp-file generated | ||
| 441 | ;; specifically to break a circular renaming. | ||
| 442 | (file-exists-p file-new)) | ||
| 443 | ;; Renaming to a file name that already exists, needed to be renamed, | ||
| 444 | ;; but whose renaming could not be performed right away. | ||
| 445 | (if (or progress renames) | ||
| 446 | ;; There's still a chance the conflict will be resolved. | ||
| 447 | (push rename residue) | ||
| 448 | ;; We have not made any progress and we've reached the end of | ||
| 449 | ;; the renames, so we really have a circular conflict, and we | ||
| 450 | ;; have to forcefully break the cycle. | ||
| 451 | (message "Circular renaming: using temporary file name") | ||
| 452 | (let ((tmp (make-temp-name file-new))) | ||
| 453 | (push (cons (car rename) tmp) renames) | ||
| 454 | (push (cons tmp file-new) residue)))) | ||
| 455 | (t | ||
| 456 | (setq progress t) | ||
| 457 | (let ((file-ori (car rename))) | ||
| 458 | (if wdired-use-interactive-rename | ||
| 459 | (wdired-search-and-rename file-ori file-new) | ||
| 460 | ;; If dired-rename-file autoloads dired-aux while | ||
| 461 | ;; dired-backup-overwrite is locally bound, | ||
| 462 | ;; dired-backup-overwrite won't be initialized. | ||
| 463 | ;; So we must ensure dired-aux is loaded. | ||
| 464 | (require 'dired-aux) | ||
| 465 | (condition-case err | ||
| 466 | (let ((dired-backup-overwrite nil)) | ||
| 467 | (dired-rename-file file-ori file-new | ||
| 468 | overwrite)) | ||
| 469 | (error | ||
| 470 | (setq errors (1+ errors)) | ||
| 471 | (dired-log (concat "Rename `" file-ori "' to `" | ||
| 472 | file-new "' failed:\n%s\n") | ||
| 473 | err))))))))) | ||
| 474 | errors)) | ||
| 475 | |||
| 476 | |||
| 429 | (defun wdired-exit () | 477 | (defun wdired-exit () |
| 430 | "Exit wdired and return to dired mode. | 478 | "Exit wdired and return to dired mode. |
| 431 | Just return to dired mode if there are no changes. Otherwise, | 479 | Just return to dired mode if there are no changes. Otherwise, |
| @@ -449,24 +497,22 @@ and proceed depending on the answer." | |||
| 449 | (save-excursion | 497 | (save-excursion |
| 450 | (goto-char (point-max)) | 498 | (goto-char (point-max)) |
| 451 | (forward-line -1) | 499 | (forward-line -1) |
| 452 | (let ((exit-while nil) | 500 | (let ((done nil) |
| 453 | curr-filename) | 501 | curr-filename) |
| 454 | (while (not exit-while) | 502 | (while (and (not done) (not (bobp))) |
| 455 | (setq curr-filename (wdired-get-filename)) | 503 | (setq curr-filename (wdired-get-filename nil t)) |
| 456 | (if (and curr-filename | 504 | (if (equal curr-filename filename-ori) |
| 457 | (equal (substitute-in-file-name curr-filename) filename-new)) | ||
| 458 | (progn | 505 | (progn |
| 459 | (setq exit-while t) | 506 | (setq exit-while t) |
| 460 | (let ((inhibit-read-only t)) | 507 | (let ((inhibit-read-only t)) |
| 461 | (dired-move-to-filename) | 508 | (dired-move-to-filename) |
| 462 | (search-forward (wdired-get-filename t) nil t) | 509 | (search-forward (wdired-get-filename t) nil t) |
| 463 | (replace-match (file-name-nondirectory filename-ori) t t)) | 510 | (replace-match (file-name-nondirectory filename-ori) t t)) |
| 511 | (setq done) | ||
| 464 | (dired-do-create-files-regexp | 512 | (dired-do-create-files-regexp |
| 465 | (function dired-rename-file) | 513 | (function dired-rename-file) |
| 466 | "Move" 1 ".*" filename-new nil t)) | 514 | "Move" 1 ".*" filename-new nil t)) |
| 467 | (forward-line -1) | 515 | (forward-line -1)))))) |
| 468 | (beginning-of-line) | ||
| 469 | (setq exit-while (bobp))))))) | ||
| 470 | 516 | ||
| 471 | ;; marks a list of files for deletion | 517 | ;; marks a list of files for deletion |
| 472 | (defun wdired-flag-for-deletion (filenames-ori) | 518 | (defun wdired-flag-for-deletion (filenames-ori) |