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 16:17:29 +0100 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="34911"; 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 16:18:56 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 1lQAiF-0008yD-EJ for ged-emacs-devel@m.gmane-mx.org; Sat, 27 Mar 2021 16:18:55 +0100 Original-Received: from localhost ([::1]:41734 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lQAiE-0000mb-FQ for ged-emacs-devel@m.gmane-mx.org; Sat, 27 Mar 2021 11:18:54 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:41782) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lQAh2-0000JT-CP for emacs-devel@gnu.org; Sat, 27 Mar 2021 11:17:40 -0400 Original-Received: from mail-oln040092073055.outbound.protection.outlook.com ([40.92.73.55]:16894 helo=EUR04-HE1-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 1lQAgx-0004bM-BB for emacs-devel@gnu.org; Sat, 27 Mar 2021 11:17:39 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=TIRnkvq0x32yONBKmfhqijQtMXFZjDlCnBkQ2aoRSG8UEtJZm6tCpmbinkTV7kDdGx+25XslKNWSHWZmQwEILuc4flYVjVKE+SeNTIry+kAmRkiddR2GGbQfYcMCjQO6tjdw9Ob+MLnr7FsvICVYWvnfSw0vTzk8Y8kEFW3GUEpaO+6QJAyj4++l6l0QIsnDmOXo5Rjq5oQEpqfRBKm/yJOnwoyZL2ZzYJSyuWYzR9bsCJXkHfvoBrPA0daxqFvBBNwTqngy9VKXAKfMJsj6M6PigvjfEovfNpOPqOgZnPGFbXzBndTrzlkO/u68nigWa/ZuUqDMV+0qY4ttYhr4hg== 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=uwevW3OeE5AZoX5XyUUx7Q0IhnkRPlia/i+GUfxjBFY=; b=JwlhpkUJogM+x7xTv+8E7D7yt3xqOZGCn21wrRuzC/4qSdYvIAppG0MYeXwyNvRBKXiH5AilgtjZQmXkJT40oYATEThqXdQGLN3tTMr5XsjVFHcsGcnaeNmIgs+is+4sHEHI7LxT6w+HP9bU/UGBzW+U/Y6WsYpNPLqaSdU/SmFgUNjGkOutBp3N3Om2/iBaQEltgdtxNaZjyhqWwLpTcGzipJUO5tHGknWowElgt+KJOhLJMG1nOmOhbmD6oMAc/DhZAENVBR2MEn5XrehUFSPS1DGMHEKQ/cBY0JlJM+sC/YdiLFwvQotJZsbRPMi3RC0hESd7HOfKuDo/AvF5MA== 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=uwevW3OeE5AZoX5XyUUx7Q0IhnkRPlia/i+GUfxjBFY=; b=ZZLi2VFLsj57qA6onsNPIg+RIEMvUp9q+e9Vu5id/dZ9LR5Qw/ZwYfBOyTza/swU/5MC56Ix3ZkccGE3qTfj8cK92wecMhj7Jo0o0lSFW0uOAm17lVBu2RTgFOhZ/bY+k4kQwby7+ohA5ifZ7ee6hwTPyz6BKCDI9ZLOqxCwUvTf9u4wBj0p4m3UVa2Gmv1V7sX6PoVXwba7DQ3sGalzlmQ6n295f8GEAbnfhjR529hJjILvmhT/WbhH5KQgstYENFEEVK22DNyLmutzriHBHG4BlEXN1R2aN9FmyFbm38xVak4P8mPs9KfHtB+CldtBP24HJydAvkkPp4v0LqOOnA== Original-Received: from DB3EUR04FT022.eop-eur04.prod.protection.outlook.com (2a01:111:e400:7e0c::4f) by DB3EUR04HT076.eop-eur04.prod.protection.outlook.com (2a01:111:e400:7e0c::333) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3977.25; Sat, 27 Mar 2021 15:17:31 +0000 Original-Received: from DB9PR09MB4986.eurprd09.prod.outlook.com (2a01:111:e400:7e0c::44) by DB3EUR04FT022.mail.protection.outlook.com (2a01:111:e400:7e0c::285) 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 15:17:31 +0000 X-IncomingTopHeaderMarker: OriginalChecksum:C480402E968C3A7DAAB296704E5202BFD3112D292805E2F0CA03E5F4C771271E; UpperCasedChecksum:1B2423F826D493EFE8264E3F4FA91588D86434352959BF741CBD539E1A1DBA3D; SizeAsReceived:7609; Count:46 Original-Received: from DB9PR09MB4986.eurprd09.prod.outlook.com ([fe80::940:96e9:22e5:8403]) by DB9PR09MB4986.eurprd09.prod.outlook.com ([fe80::940:96e9:22e5:8403%6]) with mapi id 15.20.3977.032; Sat, 27 Mar 2021 15:17:31 +0000 In-Reply-To: (Stefan Monnier's message of "Sat, 27 Mar 2021 10:56:01 -0400") X-TMN: [CvmoCy9ko1uOoy2z7xeW/a7LiGdBTK7A] X-ClientProxiedBy: AM5PR1001CA0027.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:206:2::40) To DB9PR09MB4986.eurprd09.prod.outlook.com (2603:10a6:10:2a9::19) X-Microsoft-Original-Message-ID: <87v99caanq.fsf@live.com> X-MS-Exchange-MessageSentRepresentingType: 1 Original-Received: from pascal.homepc (90.230.29.56) by AM5PR1001CA0027.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:206:2::40) 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 15:17:30 +0000 X-MS-PublicTrafficType: Email X-IncomingHeaderCount: 46 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-Correlation-Id: e875ebc9-d76c-4a6d-c680-08d8f13370a1 X-MS-TrafficTypeDiagnostic: DB3EUR04HT076: X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 5dN2NKCeXclHjXO7ZVBNzCRH0HJ0zn66lbpRNBp3rbO6MzhWp2D80wDHhctrKtem9U15/Jxvgr2ncjN4eI4gS/6GiNQcYKfzIllEE0zM9pd40PrbE9/NePTbA2ueQj9sLqIUoP1s+/ZoYjrWfkD61lQjaxU9JxQyA0uwJiKD5JK6Pq7SJUhu2wCzPsXuE+iKTReCZgiWvrjivHREqyib4z/o83/a5QfjkAob1FQ6I2L85P7NPVieBAnIY+S5X/lNuXTG8Cf4GSIxfI5BqcWwYwev9C0SM3jqaRwJ9MfAO50fs2W2n47W6RAi1rp64pigLO7Yuf0rKmfGdulKWjG7E8FSxgogURXzhgEH1hDgllZatLe64OU4nTayhbT9cdTHK8nCDEFvisTbWgvHlrtMUQ== X-MS-Exchange-AntiSpam-MessageData: gBFcmocdsofkfIloCID30fWWANOiJIa8u38ATtJslG/DYQULE8Ig1DPV0G4Wi++XLlAtl1fn4XoO//j4oz8WPfx2Qi0ecwwNxlO/DWdbtiwKMAHOrOr+tnbMAxJSPK871LgGuMDvqQOwkasXKt91AA== X-OriginatorOrg: live.com X-MS-Exchange-CrossTenant-Network-Message-Id: e875ebc9-d76c-4a6d-c680-08d8f13370a1 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Mar 2021 15:17:31.1357 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-AuthSource: DB3EUR04FT022.eop-eur04.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: DB3EUR04HT076 Received-SPF: pass client-ip=40.92.73.55; envelope-from=arthur.miller@live.com; helo=EUR04-HE1-obe.outbound.protection.outlook.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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_NONE=-0.0001, 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:267101 Archived-At: 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. > > I know; fixing all the old code to use such conventions is hard, but > I try and make sure that new code at least follows those conventions ;-) > >>> `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). > > Oh, not *that* costly. Just in the sense that it's > better not to feel free to call it redundantly. > But, I think `wdired--current-column` looks fine: it completely > side-steps the question of what happens if some of the text is > currently invisible. > >> 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 :-). > > Would it be time to plug in Richard's endorsement of reproduction here? Hmm, I don't think I know what it's about; but I trust your and RMS judgement! :-) > I pushed your change with the following additional patch on top, Cool, thnks! > > Stefan > > > commit ed6b9586d74795605debf614bd4328611e1f1c22 > Author: Stefan Monnier > Date: Sat Mar 27 10:54:10 2021 -0400 > > * lisp/wdired.el: Fix minor regressions and simplify a bit > > Use `wdired--current-column` more consistently to avoid mayhem when it > doesn't return the same result as `current-column`. > > (wdired--col-perm): Remove, redundant with `wdired--perm-beg`. > (wdired-change-to-wdired-mode): Don't error in empty directory. > (wdired--set-permission-bounds): Set `wdired--perm-beg` when we can't > find permissions. Move `wdired--perm-beg` 1 char further (like > `wdired--col-perm`). Use `wdired--current-column`. > (wdired--point-at-perms-p): Fix when `wdired--perm-beg` is nil. > (wdired--self-insert): Lookup the keymap to know command to call. > (wdired--before-change-fn): Just use `point` instead of `beg`. > Use `with-silent-modifications` here rather than in each of the > `wdired--preprocess-*` functions. > (wdired--preprocess-files): Presume we're at BOL and within > `with-silent-modifications`. Fix application of `read-only`. > (wdired-abort-changes): Don't use `with-silent-modifications` since > we're really modifying the buffer. > (wdired--preprocess-symlinks): Presume we're at BOL and within > `with-silent-modifications`. > (wdired--preprocess-perms): Presume we're at BOL and within > `with-silent-modifications`. > (wdired-set-bit): Add `char` argument. Use `wdired--current-column`. > Copy previous text properties rather than duplicating the code of > `wdired--preprocess-perms`. > (wdired-toggle-bit): Delegate to `wdired-set-bit`. > > diff --git a/lisp/wdired.el b/lisp/wdired.el > index 61272d947f..97861a4474 100644 > --- a/lisp/wdired.el > +++ b/lisp/wdired.el > @@ -189,7 +189,6 @@ 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--perm-beg) ;; Column where the permission bits start > (defvar wdired--perm-end) ;; Column where the permission bits stop > (defvar wdired--old-content) > @@ -233,8 +232,6 @@ 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 > @@ -264,49 +261,60 @@ wdired-change-to-wdired-mode > (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)))) > + (if (not (re-search-forward dired-re-perms nil t 1)) > + (progn > + (setq-local wdired--perm-beg nil) > + (setq-local wdired--perm-end nil)) > + (goto-char (match-beginning 0)) > + ;; Add 1 since the first char matched by `dired-re-perms' is the > + ;; one describing the nature of the entry (dir/symlink/...) rather > + ;; than its permissions. > + (setq-local wdired--perm-beg (1+ (wdired--current-column))) > + (goto-char (match-end 0)) > + (setq-local wdired--perm-end (wdired--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)) > + (and wdired--perm-beg > + (<= 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))) > + (if (wdired--line-preprocessed-p) > + (call-interactively 'self-insert-command) > + (wdired--before-change-fn (line-beginning-position) (line-end-position)) > + (let ((map (get-text-property (point) 'keymap))) > + (when map > + (let ((cmd (lookup-key map (this-command-keys)))) > + (call-interactively (or cmd '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)) > + ;; Make sure to process entire lines. > (goto-char end) > (setq end (line-end-position)) > + (goto-char beg) > + (forward-line 0) > > - (while (< beg end) > + (while (< (point) 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))) > + (with-silent-modifications > + (put-text-property (point) (1+ (point)) '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)) > + (when (eobp) > + (with-silent-modifications > + ;; 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." > @@ -317,28 +325,26 @@ wdired-isearch-filter-read-only > ;; properties so filenames (old and new) can be easily found. > (defun wdired--preprocess-files () > (save-excursion > - (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) '("." "..")))) > - (dired-move-to-filename) > - ;; The rear-nonsticky property below shall ensure that text preceding > - ;; the filename can't be modified. > - (add-text-properties > - (1- (point)) (point) `(old-name ,filename rear-nonsticky (read-only))) > - (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))))))) > + (let ((used-F (dired-check-switches dired-actual-switches "F" "classify")) > + (beg (point)) > + (filename (dired-get-filename nil t))) > + (when (and filename > + (not (member (file-name-nondirectory filename) '("." "..")))) > + (dired-move-to-filename) > + ;; The rear-nonsticky property below shall ensure that text preceding > + ;; the filename can't be modified. > + (add-text-properties > + (1- (point)) (point) `(old-name ,filename rear-nonsticky (read-only))) > + (put-text-property beg (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)))))) > > ;; This code is a copy of some dired-get-filename lines. > (defsubst wdired-normalize-filename (file unquotep) > @@ -425,8 +431,8 @@ wdired-change-to-dired-mode > (defun wdired-abort-changes () > "Abort changes and return to dired mode." > (interactive) > - (remove-hook 'before-change-functions 'wdired--before-change-fn t) > - (with-silent-modifications > + (remove-hook 'before-change-functions #'wdired--before-change-fn t) > + (let ((inhibit-read-only t)) > (erase-buffer) > (insert wdired--old-content) > (goto-char wdired--old-point)) > @@ -451,7 +457,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 > + wdired--perm-beg) ; could have been changed > (setq tmp-value (wdired-do-perm-changes)) > (setq errors (+ errors (cdr tmp-value))) > (setq changes (or changes (car tmp-value)))) > @@ -744,17 +750,15 @@ wdired-previous-line > ;; Put the needed properties to allow the user to change links' targets > (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)))))) > + (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. > @@ -861,31 +865,26 @@ wdired-perm-mode-map > ;; original name and permissions as a property > (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))))))) > + (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))) > + (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 > @@ -897,39 +896,30 @@ wdired-perm-allowed-in-pos > ((memq char '(?t ?T)) (= pos 8)) > ((= char ?l) (= pos 5)))) > > -(defun wdired-set-bit () > +(defun wdired-set-bit (&optional char) > "Set a permission bit character." > - (interactive) > - (if (wdired-perm-allowed-in-pos last-command-event > - (- (current-column) wdired--col-perm)) > - (let ((new-bit (char-to-string last-command-event)) > + (interactive (list last-command-event)) > + (unless char (setq char last-command-event)) > + (if (wdired-perm-allowed-in-pos char > + (- (wdired--current-column) wdired--perm-beg)) > + (let ((new-bit (char-to-string char)) > (inhibit-read-only t) > - (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) > + (pos-prop (+ (line-beginning-position) wdired--perm-beg))) > + (set-text-properties 0 1 (text-properties-at (point)) new-bit) > (insert new-bit) > (delete-char 1) > - (put-text-property (1- pos-prop) pos-prop 'perm-changed t) > - (put-text-property (1- (point)) (point) 'rear-nonsticky '(keymap))) > + (put-text-property (1- pos-prop) pos-prop 'perm-changed t)) > (forward-char 1))) > > (defun wdired-toggle-bit () > "Toggle the permission bit at point." > (interactive) > - (let ((inhibit-read-only t) > - (new-bit "-") > - (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" > - "x")))) > - (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) > - (delete-char 1) > - (put-text-property (1- pos-prop) pos-prop 'perm-changed t) > - (put-text-property (1- (point)) (point) 'rear-nonsticky '(keymap)))) > + (wdired-set-bit > + (cond > + ((not (eq (char-after (point)) ?-)) ?-) > + ((= (% (- (wdired--current-column) wdired--perm-beg) 3) 0) ?r) > + ((= (% (- (wdired--current-column) wdired--perm-beg) 3) 1) ?w) > + (t ?x)))) > > (defun wdired-mouse-toggle-bit (event) > "Toggle the permission bit that was left clicked."