From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Tino Calancha Newsgroups: gmane.emacs.bugs Subject: bug#32899: 27.0.50; wdired-do-renames: Speed up for long Emacs sessions Date: Tue, 2 Oct 2018 02:22:51 +0900 Message-ID: NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" X-Trace: blaine.gmane.org 1538415404 28682 195.159.176.226 (1 Oct 2018 17:36:44 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Mon, 1 Oct 2018 17:36:44 +0000 (UTC) To: 32899@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Mon Oct 01 19:36:39 2018 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1g727Z-0007LR-WF for geb-bug-gnu-emacs@m.gmane.org; Mon, 01 Oct 2018 19:36:38 +0200 Original-Received: from localhost ([::1]:39932 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g729g-0000B8-GK for geb-bug-gnu-emacs@m.gmane.org; Mon, 01 Oct 2018 13:38:48 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:59385) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g71vP-0005zS-Hz for bug-gnu-emacs@gnu.org; Mon, 01 Oct 2018 13:24:05 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g71vO-0001a0-8d for bug-gnu-emacs@gnu.org; Mon, 01 Oct 2018 13:24:03 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:57459) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1g71vO-0001Zr-3S for bug-gnu-emacs@gnu.org; Mon, 01 Oct 2018 13:24:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1g71vN-0001zP-V1 for bug-gnu-emacs@gnu.org; Mon, 01 Oct 2018 13:24:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Tino Calancha Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 01 Oct 2018 17:24:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 32899 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.15384145847583 (code B ref -1); Mon, 01 Oct 2018 17:24:01 +0000 Original-Received: (at submit) by debbugs.gnu.org; 1 Oct 2018 17:23:04 +0000 Original-Received: from localhost ([127.0.0.1]:33484 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1g71uR-0001yF-Ve for submit@debbugs.gnu.org; Mon, 01 Oct 2018 13:23:04 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:49583) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1g71uQ-0001xW-02 for submit@debbugs.gnu.org; Mon, 01 Oct 2018 13:23:02 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g71uJ-00014Y-QB for submit@debbugs.gnu.org; Mon, 01 Oct 2018 13:22:56 -0400 Original-Received: from lists.gnu.org ([2001:4830:134:3::11]:36224) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1g71uJ-00014Q-LO for submit@debbugs.gnu.org; Mon, 01 Oct 2018 13:22:55 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:59187) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g71uI-00053Y-AQ for bug-gnu-emacs@gnu.org; Mon, 01 Oct 2018 13:22:55 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g71uH-00013H-87 for bug-gnu-emacs@gnu.org; Mon, 01 Oct 2018 13:22:54 -0400 Original-Received: from mail-ot1-x32e.google.com ([2607:f8b0:4864:20::32e]:38631) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1g71uH-00012y-1N for bug-gnu-emacs@gnu.org; Mon, 01 Oct 2018 13:22:53 -0400 Original-Received: by mail-ot1-x32e.google.com with SMTP id h15-v6so13908948otj.5 for ; Mon, 01 Oct 2018 10:22:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=bERpS1HyrVt/XrwLQ8udHT7EW4aIAkRF9TDfRRcJ1QA=; b=q83/wct1+Fv/ZC3KjkEM7S3jbDaAzCN88a3PT/AvBFiLQtperD47AwGfFVvVLLw7pT 0cGl4u7oEsXJQFQKCex+cLi1wEJL3YfGGiBFx//GX5SS/nBn5Wd8z0qWAq3B30QH/nIX bNY3BLjeQh53roV/YCNN1qvFWMpdbShQRDaCfbopECr66rYzRrW6qEkpQ3DR5FUjtvL4 eYZm3hjryLCvTWGFGPZ1MO4dzBa3+i8GKdUN5jpLRNGV4QaTAa81Y0G0N7xMbULG2rJY F0i4o9lcYvtslNUzV3gp1PhT9/CXQaRLpMoNlIw97UcBqa4nmSyZBVULKj9xBelvgAmq Wpmw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=bERpS1HyrVt/XrwLQ8udHT7EW4aIAkRF9TDfRRcJ1QA=; b=htUyeRr0j7IrsdqFYq8G8cdllqVZPjFjQZ7ss32RAiXN4+fhLuDyHGbpdN/DZMJMW3 SG8vwC2RJvjObqtOfpbdLWhyBKSViAPj0qx8epjfXUBHzcU8NOpggQlEEkgmDnbhLk3b Od6W5TZ6MJidfA3UaYAw6BbdWk9zVEeV+OjHpeug/Fh0NAoN3ultPZcu6oYNdNdUN2dK UqW3+XBjdjXDkftbNgsJfkG1SUiVxr+jDe6HWsLEB6tbadgGV+VFtakWL2txcBEEAwMP h9Cmz/H9loqvRzrSVQBw/uet+cR0ZsvwZ/fR+M5tjvaRv+8PjG3hIMNQZInavOnpG8Ob QFrg== X-Gm-Message-State: ABuFfoiQIOfbvbdTAFHkY8QmARjNuAmoJR6LrbtKLX41tyqTiw1Ped8U jLc+pl+zQ/rTMt6SH+VQ5rhDafg/ZWq1MVE9Bzz7tkoh X-Google-Smtp-Source: ACcGV61n1fWPm+aXpy+N8bzFgfTgtCypsnH1EN5u6o7qDuQ8i0jaCZHPzu5vhQ0DVd648CjlxEj82ECJ7X2mDovUmzs= X-Received: by 2002:a9d:7698:: with SMTP id j24-v6mr6672862otl.167.1538414572025; Mon, 01 Oct 2018 10:22:52 -0700 (PDT) Original-Received: by 2002:a4a:8a45:0:0:0:0:0 with HTTP; Mon, 1 Oct 2018 10:22:51 -0700 (PDT) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:150884 Archived-At: Severity: wishlist In a long lived Emacs session with many buffers, we can get a significant improvement with `wdired-do-renames' if we drop an unnecessary step, i.e., if `dired-rename-file' calls `dired-rename-subdir' iif FILE is a directory. I observe gains as high as a factor 15. --8<-----------------------------cut here---------------start------------->8--- commit 8e742e6c84bc2f992058a03274e60c294e29ee41 Author: Tino Calancha Date: Tue Oct 2 02:00:17 2018 +0900 wdired-do-renames: Speed up for long Emacs sessions `dired-rename-file' calls unconditionally `dired-rename-subdir'. The second function performs performs a loop on all the Emacs buffers; this step is only needed if FILE is a directory. In a long lived Emacs session, this can make a difference when renaming a bunch of files with `wdired'. For instance, in my 40 days old Emacs session, with ~ 700 buffers, this patch increases the speed to rename 2000 files a factor ~ 15. * lisp/dired-aux.el (dired-rename-file): Call `dired-rename-subdir' iif FILE is a directory. Add docstring. (dired-rename-subdir, dired-remove-entry) (dired-remove-file): Add docstring. (dired-remove-entry): Move definition into `dired.el'. * lisp/wdired.el (wdired-do-renames): Use a progress-reporter. * lisp/dired.el (dired-delete-entry): Use `dired-remove-entry'. Add docstring. (dired-buffers-for-dir, dired-fun-in-all-buffers): Change comment into docstring. (dired-fun-in-all-buffers): Prefer `when' and `push' here. diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 1f13204b7c..9ec97cf3ce 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -1485,17 +1485,13 @@ dired-after-subdir-garbage ;;;###autoload (defun dired-remove-file (file) + "Remove entry FILE on each dired buffer. +Note this doesn't delete FILE in the file system. +See `dired-delete-file' in case you wish that." (dired-fun-in-all-buffers (file-name-directory file) (file-name-nondirectory file) #'dired-remove-entry file)) -(defun dired-remove-entry (file) - (save-excursion - (and (dired-goto-file file) - (let (buffer-read-only) - (delete-region (progn (beginning-of-line) (point)) - (line-beginning-position 2)))))) - ;;;###autoload (defun dired-relist-file (file) "Create or update the line for FILE in all Dired buffers it would belong in." @@ -1600,6 +1596,9 @@ dired-copy-file-recursive ;;;###autoload (defun dired-rename-file (file newname ok-if-already-exists) + "Rename FILE to NEWNAME. +Signal a `file-already-exists' error if a file NEWNAME already exists +unless OK-IF-ALREADY-EXISTS is non-nil." (dired-handle-overwrite newname) (dired-maybe-create-dirs (file-name-directory newname)) (rename-file file newname ok-if-already-exists) ; error is caught in -create-files @@ -1609,9 +1608,12 @@ dired-rename-file (set-visited-file-name newname nil t))) (dired-remove-file file) ;; See if it's an inserted subdir, and rename that, too. - (dired-rename-subdir file newname)) + (when (file-directory-p file) + (dired-rename-subdir file newname))) (defun dired-rename-subdir (from-dir to-dir) + "Rename subdir FROM-DIR to TO-DIR. +This updates the name of all buffers visiting files under FROM-DIR." (setq from-dir (file-name-as-directory from-dir) to-dir (file-name-as-directory to-dir)) (dired-fun-in-all-buffers from-dir nil diff --git a/lisp/dired.el b/lisp/dired.el index 5c7bb9599c..52399d2623 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -2607,12 +2607,12 @@ dired-copy-filename-as-kill ;; Keeping Dired buffers in sync with the filesystem and with each other (defun dired-buffers-for-dir (dir &optional file) -;; Return a list of buffers for DIR (top level or in-situ subdir). -;; If FILE is non-nil, include only those whose wildcard pattern (if any) -;; matches FILE. -;; The list is in reverse order of buffer creation, most recent last. -;; As a side effect, killed dired buffers for DIR are removed from -;; dired-buffers. + "Return a list of buffers for DIR (top level or in-situ subdir). +If FILE is non-nil, include only those whose wildcard pattern (if any) +matches FILE. +The list is in reverse order of buffer creation, most recent last. +As a side effect, killed dired buffers for DIR are removed from +dired-buffers." (setq dir (file-name-as-directory dir)) (let (result buf) (dolist (elt dired-buffers) @@ -3149,26 +3149,36 @@ dired-internal-do-deletions (dired-move-to-filename)) (defun dired-fun-in-all-buffers (directory file fun &rest args) - ;; In all buffers dired'ing DIRECTORY, run FUN with ARGS. - ;; If the buffer has a wildcard pattern, check that it matches FILE. - ;; (FILE does not include a directory component.) - ;; FILE may be nil, in which case ignore it. - ;; Return list of buffers where FUN succeeded (i.e., returned non-nil). + "In all buffers dired'ing DIRECTORY, run FUN with ARGS. +If the buffer has a wildcard pattern, check that it matches FILE. +\(FILE does not include a directory component). +FILE may be nil, in which case ignore it. +Return list of buffers where FUN succeeded (i.e., returned non-nil)." (let (success-list) (dolist (buf (dired-buffers-for-dir (expand-file-name directory) file)) (with-current-buffer buf - (if (apply fun args) - (setq success-list (cons (buffer-name buf) success-list))))) + (when (apply fun args) + (push (buffer-name buf) success-list)))) success-list)) ;; Delete the entry for FILE from -(defun dired-delete-entry (file) +(defun dired-remove-entry (file) + "Remove entry FILE in the current dired buffer. +Note this doesn't delete FILE in the file system. +See `dired-delete-file' in case you wish that." (save-excursion (and (dired-goto-file file) - (let ((inhibit-read-only t)) + (let (buffer-read-only) (delete-region (progn (beginning-of-line) (point)) - (save-excursion (forward-line 1) (point)))))) + (line-beginning-position 2)))))) + +(defun dired-delete-entry (file) + "Remove entry FILE in the current dired buffer. +Like `dired-remove-entry' followed by `dired-clean-up-after-deletion'. +Note this doesn't delete FILE in the file system. +See `dired-delete-file' in case you wish that." + (dired-remove-entry file) (dired-clean-up-after-deletion file)) (defvar dired-clean-up-buffers-too) diff --git a/lisp/wdired.el b/lisp/wdired.el index 3157e887d7..8852806dd6 100644 --- a/lisp/wdired.el +++ b/lisp/wdired.el @@ -459,10 +459,12 @@ wdired-finish-edit (defun wdired-do-renames (renames) "Perform RENAMES in parallel." - (let ((residue ()) - (progress nil) - (errors 0) - (overwrite (or (not wdired-confirm-overwrite) 1))) + (let* ((residue ()) + (progress nil) + (errors 0) + (total (1- (length renames))) + (prep (make-progress-reporter "Renaming" 0 total)) + (overwrite (or (not wdired-confirm-overwrite) 1))) (while (or renames ;; We've done one round through the renames, we have found ;; some residue, but we also made some progress, so maybe @@ -470,6 +472,7 @@ wdired-do-renames (prog1 (setq renames residue) (setq progress nil) (setq residue nil))) + (progress-reporter-update prep (- total (length renames))) (let* ((rename (pop renames)) (file-new (cdr rename))) (cond @@ -517,6 +520,7 @@ wdired-do-renames (dired-log "Rename `%s' to `%s' failed:\n%s\n" file-ori file-new err))))))))) + (progress-reporter-done prep) errors)) (defun wdired-create-parentdirs (file-new) --8<-----------------------------cut here---------------end--------------->8--- In GNU Emacs 27.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.22.11) Repository revision: 6217746dd64b43a2a2b3b66ab50cfbbfc984f36c