From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Arthur Miller Newsgroups: gmane.emacs.devel Subject: Re: [PATCH] Lazy wdired preprocessing Date: Sat, 27 Mar 2021 08:39:35 +0100 Message-ID: References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="8347"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) Cc: emacs-devel@gnu.org To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sat Mar 27 08:56:06 2021 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lQ3nh-00024Q-CW for ged-emacs-devel@m.gmane-mx.org; Sat, 27 Mar 2021 08:56:05 +0100 Original-Received: from localhost ([::1]:56608 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lQ3ng-0007P2-E5 for ged-emacs-devel@m.gmane-mx.org; Sat, 27 Mar 2021 03:56:04 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:56336) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lQ3mU-0006gw-Mz for emacs-devel@gnu.org; Sat, 27 Mar 2021 03:54:50 -0400 Original-Received: from mail-oln040092069013.outbound.protection.outlook.com ([40.92.69.13]:44590 helo=EUR02-VE1-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lQ3mN-00034n-0A for emacs-devel@gnu.org; Sat, 27 Mar 2021 03:54:50 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=lAPYy1v76CdSW0Ig6ZvVreF9io9A7CnNIFTCUXOzkvzHeQusvYClUCANFhN0VNxCKI/kNdmmA6w08mvtlR/EZ+BHGuUmKthnV5D421aYlt/FjNJqiQIMeZiUU9+hvW8IMuCosSfCmsocNdvDldtFO9vmPGDwpy0Mp9oPY1Jwpw2fyCITSd2ktAlHAnYUTfanDVT+BU8D96RBprvlzbLPSOwTVDLrz5hzVq5CKekBFpFVQJbj4taSbVoriqVruoIytM+WWIj9FzgQC+cR6mMMLgJBi3Dq2VDGtKN37bHll3+CaaZ2huoLfvFPvXbtok3KkPKOE3SWU5kTqNhsZgW4oQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Cib+RbjOce2ugz4Q4bNE/8Z8JS6CkbvOOrKLARB2Sl8=; b=SzFFWURmtH/eRx5CGtCoLi2EYSdD6s8uJ3cUmJZJHmTj7nEWLmlVf94WfPLZRIbt1psgYL7SmKkp+U/nvvDVGGkKJjwZ5Bqr3twSBBa7/6svSzo9QTV+jV8NZrjuA7ni10dl90IQjkuxaTjdnisd8YopDkjXYi+98kfbeiw6uFojmMhWpIt92jImA1sFkS7iabqiBwAxBoxFZIl1kHugOmCsry9Y/D8B3XKVndqQjc1rU1H5t+Ec9Vrei+k4xs0J9tJ+ykU7LGqdmEaYmWF5seHtR2hVph7xwiPpNKlSmo8ncTHEZu5+ErgxwdVDu1fXJOLqxacZ7MUP6YGnfAlnnA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=live.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Cib+RbjOce2ugz4Q4bNE/8Z8JS6CkbvOOrKLARB2Sl8=; b=hakthz8CyGULIXEhAvMy7hVtmOfC5cei7TyzR52IRbDQ+6loYWZLImZ5Wc7wpah9W5Qqpd/xDkyDwDkQCraXgWJUQAO46Agg/8L/w6UcYGJcJSNK/CSqjnks6JUfC7nshAwaJTOMyGgrxeMKAkJLhH0aK9vhSlPCijOLSGG36IjSQngNMUv8nuqVQjOeUDXPLwOywJQZqqpiai2PD0q2TMoaOjzJZFpEDYlkpndWkT7F18dyF9ws6Qt8iQdHtt4vELAQ9AThw/W/baRa4WQVAdIOhxYf2+MF3NWLfB0oyHs1Lh8AIfo6vChmfmoaaWiBHtrAiwIAbeAkXLTMtMZdvg== Original-Received: from VE1EUR02FT021.eop-EUR02.prod.protection.outlook.com (2a01:111:e400:7e1e::51) by VE1EUR02HT094.eop-EUR02.prod.protection.outlook.com (2a01:111:e400:7e1e::181) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3977.29; Sat, 27 Mar 2021 07:39:36 +0000 Original-Received: from AM9PR09MB4977.eurprd09.prod.outlook.com (2a01:111:e400:7e1e::45) by VE1EUR02FT021.mail.protection.outlook.com (2a01:111:e400:7e1e::111) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3977.25 via Frontend Transport; Sat, 27 Mar 2021 07:39:36 +0000 X-IncomingTopHeaderMarker: OriginalChecksum:92150E1DD5FA45D23F7FC5C26FC7C249358B2E972BDE7447F34BA6C6A41AE909; UpperCasedChecksum:D909C932E4C7296777E6DFC3887A7CEF473CFBA87DB83082677467B5EE5836B8; SizeAsReceived:7507; Count:46 Original-Received: from AM9PR09MB4977.eurprd09.prod.outlook.com ([fe80::2103:e705:bc0c:5a8b]) by AM9PR09MB4977.eurprd09.prod.outlook.com ([fe80::2103:e705:bc0c:5a8b%6]) with mapi id 15.20.3977.031; Sat, 27 Mar 2021 07:39:36 +0000 In-Reply-To: (Stefan Monnier's message of "Fri, 26 Mar 2021 15:37:25 -0400") X-TMN: [nwpq2aFXlD+4EPIiER1Pr0yhu8iS1sXv] X-ClientProxiedBy: AM5PR0402CA0011.eurprd04.prod.outlook.com (2603:10a6:203:90::21) To AM9PR09MB4977.eurprd09.prod.outlook.com (2603:10a6:20b:304::20) X-Microsoft-Original-Message-ID: <87lfa9cafc.fsf@live.com> X-MS-Exchange-MessageSentRepresentingType: 1 Original-Received: from pascal.homepc (90.230.29.56) by AM5PR0402CA0011.eurprd04.prod.outlook.com (2603:10a6:203:90::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3977.25 via Frontend Transport; Sat, 27 Mar 2021 07:39:35 +0000 X-MS-PublicTrafficType: Email X-IncomingHeaderCount: 46 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-Correlation-Id: 4c2576cc-ad1f-4ea0-c9d1-08d8f0f37832 X-MS-TrafficTypeDiagnostic: VE1EUR02HT094: X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: PbnEQTSqe+rXDlHj9hMf2Ayuve/VQaPPOYv8YRogAzzDMxMnjs3L/MNgXOz+yDuO82NgDLLJE0QKtfWUzjTdht/D06gmtJ/koIdKoVXyF8YwtWAqbjgN8y+Ae0WdJIlQqhn2KDKapi8/GODF8GjaytEayIYpI6a2rCrYuYZrQbHBIptJoNAld+zyL+tQOiJn0SBvZA73hot/K0NU7khA08HymikOgQHR7AWaRoRKnPHvMR37da4frCoc9RDe1N/kdPME2REcK7T0LKbeJkbUT43bSe/FzDpOs6tbq1t3i8sSdCefkoxYeBIl6amAc/KBLsqEyNSerbk3ThKcOhk4q9VMLmyZNgTA6AiHG4O0xflTGJMR7S+xVRnES3B7yylOPmfedtcHWY2gxUtxaUVb2A== X-MS-Exchange-AntiSpam-MessageData: Do8V4a4GsTEF3ZPStv4j7IAMDqM4WbnhPpicSJiywrKC4Xj7+X99BR3RSI1g2xhANjYbfDjS3pswj6y7d+Bnn1YGKLWF1gHknlDyPQAiOXQUZlvRcxoWnYCYKlGLa+Znal1IV2AucWEA9uPAu2PTHw== X-OriginatorOrg: live.com X-MS-Exchange-CrossTenant-Network-Message-Id: 4c2576cc-ad1f-4ea0-c9d1-08d8f0f37832 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Mar 2021 07:39:36.6856 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-AuthSource: VE1EUR02FT021.eop-EUR02.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: Internet X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1EUR02HT094 Received-SPF: pass client-ip=40.92.69.13; envelope-from=arthur.miller@live.com; helo=EUR02-VE1-obe.outbound.protection.outlook.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, MSGID_FROM_MTA_HEADER=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:267096 Archived-At: --=-=-= Content-Type: text/plain Stefan Monnier writes: >> +(defvar wdired-perm-beg) ;; Column where the permission bits start >> +(defvar wdired-perm-end) ;; Column where the permission bits stop > > I think this should use "--" in the names since they are internal variables. I just followed naming as already was in wdired. In general I tried to change as little as possible, so I didn't re-factor any existing code unless needed. Partly to save my time, partly to not mess up unnecessary. I have now changed all global vars to use '--' in name. I was thinking about "private" functions too, but I'll leave that for some other time or as exercise to someone else. >> (setq mode-name "Editable Dired") >> - (add-function :override (local 'revert-buffer-function) #'wdired-revert) >> - ;; I temp disable undo for performance: since I'm going to clear the >> - ;; undo list, it can save more than a 9% of time with big >> - ;; directories because setting properties modify the undo-list. >> - (buffer-disable-undo) >> - (wdired-preprocess-files) >> - (if wdired-allow-to-change-permissions >> - (wdired-preprocess-perms)) >> - (if (fboundp 'make-symbolic-link) >> - (wdired-preprocess-symlinks)) >> - (buffer-enable-undo) ; Performance hack. See above. >> + (setq revert-buffer-function 'wdired-revert) >> (set-buffer-modified-p nil) > > This reverts part of my recent change to the way we set > `revert-buffer-function` (most likely an oversight while merging my changes). You commited changes to wdired? :-) Yeah, I copy-pasted entire function from my working file, so yes indeed, it was an oversight on my part, fixed. >> (setq buffer-undo-list nil) >> + ;; find one column with permissions and set permision text boundaries >> + (save-excursion >> + (goto-char (point-min)) >> + (unless (re-search-forward dired-re-perms nil t 1) >> + (wdired-abort-changes) >> + (error "No files to be renamed - Exiting to Dired mode.")) >> + (goto-char (match-beginning 0)) >> + (setq-local wdired-perm-beg (current-column)) >> + (goto-char (match-end 0)) >> + (setq-local wdired-perm-end (current-column))) > > I'd recommend you put this in a separate function. I have refactored that a bit more and am using directory-empty-p to exit earlier. Hope we can use default-directory there. Check the code. >> + (define-key wdired-mode-map [remap self-insert-command] #'wdired--self-insert) > > Why is this done here instead of in the definition of `wdired-mode-map`? Was typing as I was thinking ... :-). Fixed. >> +(defun wdired--point-at-perms-p () >> + (and (>= (current-column) wdired-perm-beg) >> + (<= (current-column) wdired-perm-end))) > > `current-column` can be somewhat costly, so we should refrain from > calling it twice gratuitously. And here we can even take advantage of > the (rarely used and rarely applicable) multi-arg form of `<=` to fix > that "for free": Ok. Didn't know that (current-column) was expensive. I use now a good 'nuff implementation for this purpose (wdired--current-column). > (<= wdired-perm-beg (current-column) wdired-perm-end) Cool; thnks, didn't know we can write so. >> +(defun wdired--self-insert () >> + (interactive) >> + (if (wdired--point-at-perms-p) >> + (when (not (get-text-property (line-beginning-position) 'front-sticky)) >> + (wdired--before-change-fn (line-beginning-position) (line-end-position)) >> + (setq unread-command-events (nconc (listify-key-sequence >> + (this-command-keys)) >> + unread-command-events))) >> + (call-interactively 'self-insert-command))) > > I think this deserves a comment about why we look at `front-sticky`. > Better yet: move this test to a helper function to which you can give > a meaningful name (like `wdired--processed-p`). Sure, it makes code more self-documented. > Also, instead of using `unread-command-events`, you can just call the > appropriate command directly, no? As I stated about refactoring above, I tried to change as little as possible. Partly because I was lazy to look into the old code and partly because I tried to "plug" into already existing (and hopefully debugged) code. But sure toggle-bit is the one I think. >> - (remove-hook 'kill-buffer-hook #'wdired-check-kill-buffer t) >> - (remove-hook 'after-change-functions #'wdired--restore-properties t) >> - (remove-function (local 'revert-buffer-function) #'wdired-revert)) >> + (remove-hook 'kill-buffer-hook 'wdired-check-kill-buffer t) >> + (remove-hook 'before-change-functions 'wdired--before-change-fn t) >> + (remove-hook 'after-change-functions 'wdired--restore-properties t) >> + (setq-local revert-buffer-function 'dired-revert)) > > This also look like the merge wasn't done right. No idea; mr. git format-patch seems to shuffle lines around, and I trust it to do what it has to do. >> (defun wdired-abort-changes () >> - "Abort changes and return to dired mode." >> + "Abort changes and return to dired mode. " > > What happened here? No idea. :-). It's all yours now. I don't think I will have more time nor possibility to work on this, so if this one is not good enough, you will to finnish it on your own, or someone else could help. We are waiting a kid any day now, so no hobby programming for quite some time over for me :-). Thnks for the guidance. Cheers --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=lazy-wdired.patch >From 7e6a6f2d7c958228882a7cdd34533d2c322093b4 Mon Sep 17 00:00:00 2001 From: Arthur Miller Date: Sat, 27 Mar 2021 08:29:44 +0100 Subject: [PATCH] lazy wdired --- lisp/wdired.el | 223 ++++++++++++++++++++++++++++--------------------- 1 file changed, 129 insertions(+), 94 deletions(-) diff --git a/lisp/wdired.el b/lisp/wdired.el index 43026d4bb7..df78082596 100644 --- a/lisp/wdired.el +++ b/lisp/wdired.el @@ -172,6 +172,7 @@ wdired-mode-map (define-key map [remap upcase-word] #'wdired-upcase-word) (define-key map [remap capitalize-word] #'wdired-capitalize-word) (define-key map [remap downcase-word] #'wdired-downcase-word) + (define-key map [remap self-insert-command] #'wdired--self-insert) map) "Keymap used in `wdired-mode'.") @@ -188,10 +189,12 @@ wdired-mode-hook "Hooks run when changing to WDired mode.") ;; Local variables (put here to avoid compilation gripes) -(defvar wdired-col-perm) ;; Column where the permission bits start -(defvar wdired-old-content) -(defvar wdired-old-point) -(defvar wdired-old-marks) +(defvar wdired--col-perm) ;; Column where the permission bits start +(defvar wdired--perm-beg) ;; Column where the permission bits start +(defvar wdired--perm-end) ;; Column where the permission bits stop +(defvar wdired--old-content) +(defvar wdired--old-point) +(defvar wdired--old-marks) (defun wdired-mode () "Writable Dired (WDired) mode. @@ -230,11 +233,14 @@ wdired-change-to-wdired-mode (interactive) (unless (derived-mode-p 'dired-mode) (error "Not a Dired buffer")) + (when (directory-empty-p (expand-file-name default-directory)) + (error "No files to be renamed")) (setq-local wdired-old-content (buffer-substring (point-min) (point-max))) - (setq-local wdired-old-marks + (setq-local wdired--old-marks (dired-remember-marks (point-min) (point-max))) - (setq-local wdired-old-point (point)) + (setq-local wdired--old-point (point)) + (wdired--set-permission-bounds) (setq-local query-replace-skip-read-only t) (add-function :after-while (local 'isearch-filter-predicate) #'wdired-isearch-filter-read-only) @@ -243,20 +249,11 @@ wdired-change-to-wdired-mode (setq buffer-read-only nil) (dired-unadvertise default-directory) (add-hook 'kill-buffer-hook #'wdired-check-kill-buffer nil t) + (add-hook 'before-change-functions #'wdired--before-change-fn nil t) (add-hook 'after-change-functions #'wdired--restore-properties nil t) (setq major-mode 'wdired-mode) (setq mode-name "Editable Dired") (add-function :override (local 'revert-buffer-function) #'wdired-revert) - ;; I temp disable undo for performance: since I'm going to clear the - ;; undo list, it can save more than a 9% of time with big - ;; directories because setting properties modify the undo-list. - (buffer-disable-undo) - (wdired-preprocess-files) - (if wdired-allow-to-change-permissions - (wdired-preprocess-perms)) - (if (fboundp 'make-symbolic-link) - (wdired-preprocess-symlinks)) - (buffer-enable-undo) ; Performance hack. See above. (set-buffer-modified-p nil) (setq buffer-undo-list nil) (run-mode-hooks 'wdired-mode-hook) @@ -264,6 +261,53 @@ wdired-change-to-wdired-mode "Press \\[wdired-finish-edit] when finished \ or \\[wdired-abort-changes] to abort changes"))) +(defun wdired--set-permission-bounds () + (save-excursion + (goto-char (point-min)) + (re-search-forward dired-re-perms nil t 1) + (goto-char (match-beginning 0)) + (setq-local wdired--perm-beg (current-column)) + (goto-char (match-end 0)) + (setq-local wdired--perm-end (current-column)))) + +(defun wdired--current-column () + (- (point) (line-beginning-position))) + +(defun wdired--point-at-perms-p () + (<= wdired-perm-beg (wdired--current-column) wdired-perm-end)) + +(defun wdired--line-preprocessed-p () + (get-text-property (line-beginning-position) 'front-sticky)) + +(defun wdired--self-insert () + (interactive) + (if (wdired--point-at-perms-p) + (unless (wdired--line-preprocessed-p) + (wdired--before-change-fn (line-beginning-position) (line-end-position)) + (wdired-toggle-bit)) + (call-interactively 'self-insert-command))) + +(defun wdired--before-change-fn (beg end) + (save-excursion + ;; make sure to process entire lines + (goto-char beg) + (setq beg (line-beginning-position)) + (goto-char end) + (setq end (line-end-position)) + + (while (< beg end) + (unless (wdired--line-preprocessed-p) + (put-text-property beg (1+ beg) 'front-sticky t) + (wdired--preprocess-files) + (when wdired-allow-to-change-permissions + (wdired--preprocess-perms)) + (when (fboundp 'make-symbolic-link) + (wdired--preprocess-symlinks))) + (forward-line) + (setq beg (point))) + ;; is this good enough? assumes no extra white lines from dired + (put-text-property (1- (point-max)) (point-max) 'read-only t))) + (defun wdired-isearch-filter-read-only (beg end) "Skip matches that have a read-only property." (not (text-property-not-all (min beg end) (max beg end) @@ -271,14 +315,12 @@ wdired-isearch-filter-read-only ;; Protect the buffer so only the filenames can be changed, and put ;; properties so filenames (old and new) can be easily found. -(defun wdired-preprocess-files () - (put-text-property (point-min) (1+ (point-min))'front-sticky t) +(defun wdired--preprocess-files () (save-excursion - (goto-char (point-min)) - (let ((b-protection (point)) - (used-F (dired-check-switches dired-actual-switches "F" "classify")) - filename) - (while (not (eobp)) + (with-silent-modifications + (beginning-of-line) + (let ((used-F (dired-check-switches dired-actual-switches "F" "classify")) + filename) (setq filename (dired-get-filename nil t)) (when (and filename (not (member (file-name-nondirectory filename) '("." "..")))) @@ -287,19 +329,16 @@ wdired-preprocess-files ;; the filename can't be modified. (add-text-properties (1- (point)) (point) `(old-name ,filename rear-nonsticky (read-only))) - (put-text-property b-protection (point) 'read-only t) + (put-text-property (- (point) 1) (point) 'read-only t) (dired-move-to-end-of-filename t) (put-text-property (point) (1+ (point)) 'end-name t)) - (when (and used-F (looking-at "[*/@|=>]$")) (forward-char)) - (when (save-excursion - (and (re-search-backward - dired-permission-flags-regexp nil t) - (looking-at "l") - (search-forward " -> " (line-end-position) t))) - (goto-char (line-end-position))) - (setq b-protection (point)) - (forward-line)) - (put-text-property b-protection (point-max) 'read-only t)))) + (when (and used-F (looking-at "[*/@|=>]$")) (forward-char)) + (when (save-excursion + (and (re-search-backward + dired-permission-flags-regexp nil t) + (looking-at "l") + (search-forward " -> " (line-end-position) t))) + (goto-char (line-end-position))))))) ;; This code is a copy of some dired-get-filename lines. (defsubst wdired-normalize-filename (file unquotep) @@ -362,7 +401,6 @@ wdired-get-filename (and file (> (length file) 0) (concat (dired-current-directory) file)))))) - (defun wdired-change-to-dired-mode () "Change the mode back to dired." (or (eq major-mode 'wdired-mode) @@ -379,17 +417,19 @@ wdired-change-to-dired-mode (setq major-mode 'dired-mode) (setq mode-name "Dired") (dired-advertise) - (remove-hook 'kill-buffer-hook #'wdired-check-kill-buffer t) - (remove-hook 'after-change-functions #'wdired--restore-properties t) - (remove-function (local 'revert-buffer-function) #'wdired-revert)) + (remove-hook 'kill-buffer-hook 'wdired-check-kill-buffer t) + (remove-hook 'before-change-functions 'wdired--before-change-fn t) + (remove-hook 'after-change-functions 'wdired--restore-properties t) + (setq-local revert-buffer-function 'dired-revert)) (defun wdired-abort-changes () "Abort changes and return to dired mode." (interactive) - (let ((inhibit-read-only t)) + (remove-hook 'before-change-functions 'wdired--before-change-fn t) + (with-silent-modifications (erase-buffer) (insert wdired-old-content) - (goto-char wdired-old-point)) + (goto-char wdired--old-point)) (wdired-change-to-dired-mode) (set-buffer-modified-p nil) (setq buffer-undo-list nil) @@ -411,7 +451,7 @@ wdired-finish-edit (setq errors (cdr tmp-value)) (setq changes (car tmp-value))) (when (and wdired-allow-to-change-permissions - (boundp 'wdired-col-perm)) ; could have been changed + (boundp 'wdired--col-perm)) ; could have been changed (setq tmp-value (wdired-do-perm-changes)) (setq errors (+ errors (cdr tmp-value))) (setq changes (or changes (car tmp-value)))) @@ -429,11 +469,11 @@ wdired-finish-edit (let ((mark (cond ((integerp wdired-keep-marker-rename) wdired-keep-marker-rename) (wdired-keep-marker-rename - (cdr (assoc file-old wdired-old-marks))) + (cdr (assoc file-old wdired--old-marks))) (t nil)))) (when mark (push (cons (substitute-in-file-name file-new) mark) - wdired-old-marks)))) + wdired--old-marks)))) (push (cons file-old (substitute-in-file-name file-new)) files-renamed)))) (forward-line -1))) @@ -458,7 +498,7 @@ wdired-finish-edit ;; Re-sort the buffer. (revert-buffer) (let ((inhibit-read-only t)) - (dired-mark-remembered wdired-old-marks))) + (dired-mark-remembered wdired--old-marks))) (let ((inhibit-read-only t)) (remove-text-properties (point-min) (point-max) '(old-name nil end-name nil old-link nil @@ -702,21 +742,19 @@ wdired-previous-line (dired-move-to-filename))) ;; Put the needed properties to allow the user to change links' targets -(defun wdired-preprocess-symlinks () - (let ((inhibit-read-only t)) - (save-excursion - (goto-char (point-min)) - (while (not (eobp)) - (when (looking-at dired-re-sym) - (re-search-forward " -> \\(.*\\)$") - (put-text-property (1- (match-beginning 1)) - (match-beginning 1) 'old-link - (match-string-no-properties 1)) - (put-text-property (match-end 1) (1+ (match-end 1)) 'end-link t) - (unless wdired-allow-to-redirect-links - (put-text-property (match-beginning 0) - (match-end 1) 'read-only t))) - (forward-line))))) +(defun wdired--preprocess-symlinks () + (save-excursion + (with-silent-modifications + (beginning-of-line) + (when (looking-at dired-re-sym) + (re-search-forward " -> \\(.*\\)$") + (put-text-property (1- (match-beginning 1)) + (match-beginning 1) 'old-link + (match-string-no-properties 1)) + (put-text-property (match-end 1) (1+ (match-end 1)) 'end-link t) + (unless wdired-allow-to-redirect-links + (put-text-property (match-beginning 0) + (match-end 1) 'read-only t)))))) (defun wdired-get-previous-link (&optional old move) "Return the next symlink target. @@ -800,10 +838,8 @@ wdired-capitalize-word (interactive "p") (wdired-xcase-word 'capitalize-word arg)) - ;; The following code deals with changing the access bits (or ;; permissions) of the files. - (defvar wdired-perm-mode-map (let ((map (make-sparse-keymap))) (define-key map " " #'wdired-toggle-bit) @@ -822,34 +858,33 @@ wdired-perm-mode-map ;; Put a keymap property to the permission bits of the files, and store the ;; original name and permissions as a property -(defun wdired-preprocess-perms () - (let ((inhibit-read-only t)) - (setq-local wdired-col-perm nil) - (save-excursion - (goto-char (point-min)) - (while (not (eobp)) - (when (and (not (looking-at dired-re-sym)) - (wdired-get-filename) - (re-search-forward dired-re-perms (line-end-position) 'eol)) - (let ((begin (match-beginning 0)) - (end (match-end 0))) - (unless wdired-col-perm - (setq wdired-col-perm (- (current-column) 9))) - (if (eq wdired-allow-to-change-permissions 'advanced) - (progn - (put-text-property begin end 'read-only nil) - ;; make first permission bit writable - (put-text-property - (1- begin) begin 'rear-nonsticky '(read-only))) - ;; avoid that keymap applies to text following permissions - (add-text-properties - (1+ begin) end - `(keymap ,wdired-perm-mode-map rear-nonsticky (keymap)))) - (put-text-property end (1+ end) 'end-perm t) - (put-text-property - begin (1+ begin) 'old-perm (match-string-no-properties 0)))) - (forward-line) - (beginning-of-line))))) +(defun wdired--preprocess-perms () + (save-excursion + (with-silent-modifications + (setq-local wdired--col-perm nil) + (beginning-of-line) + (when (and (not (looking-at dired-re-sym)) + (wdired-get-filename) + (re-search-forward dired-re-perms + (line-end-position) 'eol)) + (let ((begin (match-beginning 0)) + (end (match-end 0))) + (unless wdired--col-perm + (setq wdired--col-perm (- (current-column) 9))) + (if (eq wdired-allow-to-change-permissions 'advanced) + (progn + (put-text-property begin end 'read-only nil) + ;; make first permission bit writable + (put-text-property + (1- begin) begin 'rear-nonsticky '(read-only))) + ;; avoid that keymap applies to text following permissions + (add-text-properties + (1+ begin) end + `(keymap ,wdired-perm-mode-map rear-nonsticky (keymap)))) + (put-text-property end (1+ end) 'end-perm t) + (put-text-property + begin (1+ begin) + 'old-perm (match-string-no-properties 0))))))) (defun wdired-perm-allowed-in-pos (char pos) (cond @@ -865,10 +900,10 @@ wdired-set-bit "Set a permission bit character." (interactive) (if (wdired-perm-allowed-in-pos last-command-event - (- (current-column) wdired-col-perm)) + (- (current-column) wdired--col-perm)) (let ((new-bit (char-to-string last-command-event)) (inhibit-read-only t) - (pos-prop (- (point) (- (current-column) wdired-col-perm)))) + (pos-prop (- (point) (- (current-column) wdired--col-perm)))) (put-text-property 0 1 'keymap wdired-perm-mode-map new-bit) (put-text-property 0 1 'read-only t new-bit) (insert new-bit) @@ -882,11 +917,11 @@ wdired-toggle-bit (interactive) (let ((inhibit-read-only t) (new-bit "-") - (pos-prop (- (point) (- (current-column) wdired-col-perm)))) + (pos-prop (- (point) (- (current-column) wdired--col-perm)))) (if (eq (char-after (point)) ?-) (setq new-bit - (if (= (% (- (current-column) wdired-col-perm) 3) 0) "r" - (if (= (% (- (current-column) wdired-col-perm) 3) 1) "w" + (if (= (% (- (current-column) wdired--col-perm) 3) 0) "r" + (if (= (% (- (current-column) wdired--col-perm) 3) 1) "w" "x")))) (put-text-property 0 1 'keymap wdired-perm-mode-map new-bit) (put-text-property 0 1 'read-only t new-bit) -- 2.31.0 --=-=-=--