aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2008-06-14 17:00:01 +0000
committerStefan Monnier2008-06-14 17:00:01 +0000
commitf6d346c940bfd988b49881ef78bf59afcd2cdeb9 (patch)
treec96d9a5cf92cc0f683f45925269f7968c9297c01
parent508021c76d19608339c44aca2dbd48856dbde313 (diff)
downloademacs-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/ChangeLog6
-rw-r--r--lisp/wdired.el112
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 @@
12008-06-14 Stefan Monnier <monnier@iro.umontreal.ca> 12008-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
72008-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
52008-06-14 Martin Rudalics <rudalics@gmx.at> 112008-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.
431Just return to dired mode if there are no changes. Otherwise, 479Just 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)