Mercurial > emacs
annotate lisp/wdired.el @ 69478:e8bb5df2ba7a
Add index entries around each paragraph rather than depend on entries
from beginning of node. Doing so ensures that index entries are less
likely to be forgotten if text is cut and pasted, and are necessary
anyway if the references are on a separate page. It seems that
makeinfo is now (v. 4.8) only producing one index entry per node, so
there is no longer any excuse not to. Use subheading instead of
heading. The incorrect use of heading produced very large fonts in
Info--as large as the main heading.
(From Bill Wohler): MH-E never did appear in Emacs 21--MH-E versions 6
and 7 appeared *around* the time of these Emacs releases.
author | Bill Wohler <wohler@newt.com> |
---|---|
date | Wed, 15 Mar 2006 00:26:12 +0000 |
parents | 45a2e01db282 |
children | 183934d15fbb |
rev | line source |
---|---|
55098 | 1 ;;; wdired.el --- Rename files editing their names in dired buffers |
2 | |
68651
3bd95f4f2941
Update years in copyright notice; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
68152
diff
changeset
|
3 ;; Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. |
55098 | 4 |
5 ;; Filename: wdired.el | |
61350
796b7fe4bfd8
(wdired-advise-functions, wdired-add-skip-in-replace)
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
61030
diff
changeset
|
6 ;; Author: Juan León Lahoz García <juanleon1@gmail.com> |
796b7fe4bfd8
(wdired-advise-functions, wdired-add-skip-in-replace)
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
61030
diff
changeset
|
7 ;; Version: 2.0 |
55098 | 8 ;; Keywords: dired, environment, files, renaming |
9 | |
10 ;; This file is part of GNU Emacs. | |
11 | |
12 ;; GNU Emacs is free software; you can redistribute it and/or | |
13 ;; modify it under the terms of the GNU General Public License as | |
14 ;; published by the Free Software Foundation; either version 2, or (at | |
15 ;; your option) any later version. | |
16 | |
17 ;; This program is distributed in the hope that it will be useful, but | |
18 ;; WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
20 ;; General Public License for more details. | |
21 | |
22 ;; You should have received a copy of the GNU General Public License | |
23 ;; along with GNU Emacs; see the file COPYING. If not, write to the | |
64091 | 24 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
25 ;; Boston, MA 02110-1301, USA. | |
55098 | 26 |
27 ;;; Commentary: | |
28 | |
29 ;; wdired.el (the "w" is for writable) provides an alternative way of | |
30 ;; renaming files. | |
31 ;; | |
32 ;; Have you ever wished to use C-x r t (string-rectangle), M-% | |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
33 ;; (query-replace), M-c (capitalize-word), etc... to change the name of |
61473 | 34 ;; the files in a "dired" buffer? Now you can do this. All the power |
35 ;; of Emacs commands are available to renaming files! | |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
36 ;; |
55098 | 37 ;; This package provides a function that makes the filenames of a a |
38 ;; dired buffer editable, by changing the buffer mode (which inhibits | |
39 ;; all of the commands of dired mode). Here you can edit the names of | |
40 ;; one or more files and directories, and when you press C-c C-c, the | |
41 ;; renaming takes effect and you are back to dired mode. | |
42 ;; | |
61473 | 43 ;; Another things you can do with WDired: |
55098 | 44 ;; |
45 ;; - To move files to another directory (by typing their path, | |
46 ;; absolute or relative, as a part of the new filename). | |
47 ;; | |
48 ;; - To change the target of symbolic links. | |
49 ;; | |
50 ;; - To change the permission bits of the filenames (in systems with a | |
51 ;; working unix-alike `dired-chmod-program'). See and customize the | |
61473 | 52 ;; variable `wdired-allow-to-change-permissions'. To change a single |
55098 | 53 ;; char (toggling between its two more usual values) you can press |
61473 | 54 ;; the space bar over it or left-click the mouse. To set any char to |
55098 | 55 ;; an specific value (this includes the SUID, SGID and STI bits) you |
61473 | 56 ;; can use the key labeled as the letter you want. Please note that |
55098 | 57 ;; permissions of the links cannot be changed in that way, because |
58 ;; the change would affect to their targets, and this would not be | |
59 ;; WYSIWYG :-). | |
60 ;; | |
61 ;; - To mark files for deletion, by deleting their whole filename. | |
62 | |
63 ;;; Installation: | |
64 | |
65 ;; Add this file (byte-compiling it is recommended) to your load-path. | |
66 ;; Then add one of these set of lines (or similar ones) to your config: | |
67 ;; | |
68 ;; This is the easy way: | |
69 ;; | |
70 ;; (require 'wdired) | |
71 ;; (define-key dired-mode-map "r" 'wdired-change-to-wdired-mode) | |
72 ;; | |
61473 | 73 ;; This is the recommended way for faster Emacs startup time and lower |
74 ;; memory consumption: | |
55098 | 75 ;; |
76 ;; (autoload 'wdired-change-to-wdired-mode "wdired") | |
61473 | 77 ;; (eval-after-load "dired" |
55098 | 78 ;; '(lambda () |
79 ;; (define-key dired-mode-map "r" 'wdired-change-to-wdired-mode) | |
80 ;; (define-key dired-mode-map | |
81 ;; [menu-bar immediate wdired-change-to-wdired-mode] | |
82 ;; '("Edit File Names" . wdired-change-to-wdired-mode)))) | |
83 ;; | |
61473 | 84 ;; Type "M-x customize-group RET wdired" if you want to make changes |
85 ;; to the default behavior. | |
55098 | 86 |
87 ;;; Usage: | |
88 | |
89 ;; Then, you can start editing the names of the files by typing "r" | |
90 ;; (or whatever key you choose, or M-x wdired-change-to-wdired-mode). | |
91 ;; Use C-c C-c when finished or C-c C-k to abort. You can use also the | |
92 ;; menu options: in dired mode, "Edit File Names" under "Immediate". | |
93 ;; While editing the names, a new submenu "WDired" is available at top | |
94 ;; level. You can customize the behavior of this package from this | |
95 ;; menu. | |
96 | |
97 ;;; Change Log: | |
98 | |
61473 | 99 ;; Google is your friend (previous versions with complete changelogs |
100 ;; were posted to gnu.emacs.sources) | |
55098 | 101 |
102 ;;; Code: | |
103 | |
61473 | 104 (defvar dired-backup-overwrite) ; Only in Emacs 20.x this is a custom var |
55098 | 105 |
69279
45a2e01db282
(toplevel): Require `cl' at compile-time.
John Paul Wallington <jpw@pobox.com>
parents:
68680
diff
changeset
|
106 (eval-when-compile (require 'cl)) |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
107 (require 'dired) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
108 (autoload 'dired-do-create-files-regexp "dired-aux") |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
109 (autoload 'dired-call-process "dired-aux") |
55098 | 110 |
111 (defgroup wdired nil | |
112 "Mode to rename files by editing their names in dired buffers." | |
113 :group 'dired) | |
114 | |
115 (defcustom wdired-use-interactive-rename nil | |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
116 "If non-nil, WDired requires confirmation before actually renaming files. |
61473 | 117 If nil, WDired doesn't require confirmation to change the file names, |
118 and the variable `wdired-confirm-overwrite' controls whether it is ok | |
119 to overwrite files without asking." | |
55098 | 120 :type 'boolean |
121 :group 'wdired) | |
122 | |
61473 | 123 (defcustom wdired-confirm-overwrite t |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
124 "If nil the renames can overwrite files without asking. |
61473 | 125 This variable has no effect at all if `wdired-use-interactive-rename' |
126 is not nil." | |
55098 | 127 :type 'boolean |
128 :group 'wdired) | |
129 | |
61473 | 130 (defcustom wdired-use-dired-vertical-movement nil |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
131 "If t, the \"up\" and \"down\" movement works as in Dired mode. |
55098 | 132 That is, always move the point to the beginning of the filename at line. |
133 | |
134 If `sometimes, only move to the beginning of filename if the point is | |
135 before it, and `track-eol' is honored. This behavior is very handy | |
136 when editing several filenames. | |
137 | |
138 If nil, \"up\" and \"down\" movement is done as in any other buffer." | |
139 :type '(choice (const :tag "As in any other mode" nil) | |
140 (const :tag "Smart cursor placement" sometimes) | |
141 (other :tag "As in dired mode" t)) | |
142 :group 'wdired) | |
143 | |
144 (defcustom wdired-allow-to-redirect-links t | |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
145 "If non-nil, the target of the symbolic links are editable. |
55098 | 146 In systems without symbolic links support, this variable has no effect |
147 at all." | |
148 :type 'boolean | |
149 :group 'wdired) | |
150 | |
151 (defcustom wdired-allow-to-change-permissions nil | |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
152 "If non-nil, the permissions bits of the files are editable. |
55098 | 153 |
154 If t, to change a single bit, put the cursor over it and press the | |
155 space bar, or left click over it. You can also hit the letter you want | |
156 to set: if this value is allowed, the character in the buffer will be | |
157 changed. Anyway, the point is advanced one position, so, for example, | |
61473 | 158 you can keep the <x> key pressed to give execution permissions to |
55098 | 159 everybody to that file. |
160 | |
161 If `advanced, the bits are freely editable. You can use | |
162 `string-rectangle', `query-replace', etc. You can put any value (even | |
163 newlines), but if you want your changes to be useful, you better put a | |
164 intelligible value. | |
165 | |
61473 | 166 Anyway, the real change of the permissions is done by the external |
55098 | 167 program `dired-chmod-program', which must exist." |
168 :type '(choice (const :tag "Not allowed" nil) | |
55109
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
169 (const :tag "Toggle/set bits" t) |
55098 | 170 (other :tag "Bits freely editable" advanced)) |
171 :group 'wdired) | |
172 | |
55109
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
173 (defvar wdired-mode-map |
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
174 (let ((map (make-sparse-keymap))) |
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
175 (define-key map "\C-x\C-s" 'wdired-finish-edit) |
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
176 (define-key map "\C-c\C-c" 'wdired-finish-edit) |
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
177 (define-key map "\C-c\C-k" 'wdired-abort-changes) |
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
178 (define-key map "\C-c\C-[" 'wdired-abort-changes) |
61473 | 179 (define-key map "\C-m" 'ignore) |
180 (define-key map "\C-j" 'ignore) | |
181 (define-key map "\C-o" 'ignore) | |
55109
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
182 (define-key map [up] 'wdired-previous-line) |
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
183 (define-key map "\C-p" 'wdired-previous-line) |
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
184 (define-key map [down] 'wdired-next-line) |
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
185 (define-key map "\C-n" 'wdired-next-line) |
55098 | 186 |
55109
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
187 (define-key map [menu-bar wdired] |
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
188 (cons "WDired" (make-sparse-keymap "WDired"))) |
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
189 (define-key map [menu-bar wdired wdired-customize] |
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
190 '("Options" . wdired-customize)) |
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
191 (define-key map [menu-bar wdired dashes] |
55098 | 192 '("--")) |
55109
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
193 (define-key map [menu-bar wdired wdired-abort-changes] |
68152
3a7458f9152d
(wdired-mode-map): Add help echo for wdired-abort-changes.
Nick Roberts <nickrob@snap.net.nz>
parents:
67561
diff
changeset
|
194 '(menu-item "Abort Changes" wdired-abort-changes |
3a7458f9152d
(wdired-mode-map): Add help echo for wdired-abort-changes.
Nick Roberts <nickrob@snap.net.nz>
parents:
67561
diff
changeset
|
195 :help "Abort changes and return to dired mode")) |
55109
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
196 (define-key map [menu-bar wdired wdired-finish-edit] |
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
197 '("Commit Changes" . wdired-finish-edit)) |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
198 |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
199 (define-key map [remap upcase-word] 'wdired-upcase-word) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
200 (define-key map [remap capitalize-word] 'wdired-capitalize-word) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
201 (define-key map [remap downcase-word] 'wdired-downcase-word) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
202 |
55109
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
203 map)) |
55098 | 204 |
55109
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
205 (defvar wdired-mode-hook nil |
61473 | 206 "Hooks run when changing to WDired mode.") |
55098 | 207 |
208 ;; Local variables (put here to avoid compilation gripes) | |
209 (defvar wdired-col-perm) ;; Column where the permission bits start | |
210 (defvar wdired-old-content) | |
67561
827930ad591b
(wdired-old-point): New internal variable.
Juri Linkov <juri@jurta.org>
parents:
65582
diff
changeset
|
211 (defvar wdired-old-point) |
55098 | 212 |
213 | |
214 (defun wdired-mode () | |
215 "\\<wdired-mode-map>File Names Editing mode. | |
216 | |
61473 | 217 Press \\[wdired-finish-edit] to make the changes to take effect |
218 and exit. To abort the edit, use \\[wdired-abort-changes]. | |
55098 | 219 |
61473 | 220 In this mode you can edit the names of the files, the target of |
221 the links and the permission bits of the files. You can use | |
222 \\[customize-group] RET wdired to customize WDired behavior. | |
55098 | 223 |
61473 | 224 The only editable texts in a WDired buffer are filenames, |
225 symbolic link targets, and filenames permission." | |
55098 | 226 (interactive) |
227 (error "This mode can be enabled only by `wdired-change-to-wdired-mode'")) | |
228 (put 'wdired-mode 'mode-class 'special) | |
229 | |
230 | |
231 ;;;###autoload | |
232 (defun wdired-change-to-wdired-mode () | |
233 "Put a dired buffer in a mode in which filenames are editable. | |
61473 | 234 \\<wdired-mode-map> |
235 This mode allows the user to change the names of the files, and after | |
236 typing \\[wdired-finish-edit] Emacs renames the files and directories | |
237 in disk. | |
55098 | 238 |
239 See `wdired-mode'." | |
240 (interactive) | |
241 (set (make-local-variable 'wdired-old-content) | |
242 (buffer-substring (point-min) (point-max))) | |
67561
827930ad591b
(wdired-old-point): New internal variable.
Juri Linkov <juri@jurta.org>
parents:
65582
diff
changeset
|
243 (set (make-local-variable 'wdired-old-point) (point)) |
61350
796b7fe4bfd8
(wdired-advise-functions, wdired-add-skip-in-replace)
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
61030
diff
changeset
|
244 (set (make-local-variable 'query-replace-skip-read-only) t) |
55098 | 245 (use-local-map wdired-mode-map) |
55109
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
246 (force-mode-line-update) |
55098 | 247 (setq buffer-read-only nil) |
248 (dired-unadvertise default-directory) | |
249 (add-hook 'kill-buffer-hook 'wdired-check-kill-buffer nil t) | |
250 (setq major-mode 'wdired-mode) | |
61473 | 251 (setq mode-name "Editable Dired") |
55098 | 252 (setq revert-buffer-function 'wdired-revert) |
253 ;; I temp disable undo for performance: since I'm going to clear the | |
254 ;; undo list, it can save more than a 9% of time with big | |
255 ;; directories because setting properties modify the undo-list. | |
256 (buffer-disable-undo) | |
257 (wdired-preprocess-files) | |
258 (if wdired-allow-to-change-permissions | |
259 (wdired-preprocess-perms)) | |
260 (if (and wdired-allow-to-redirect-links (fboundp 'make-symbolic-link)) | |
261 (wdired-preprocess-symlinks)) | |
262 (buffer-enable-undo) ; Performance hack. See above. | |
263 (set-buffer-modified-p nil) | |
264 (setq buffer-undo-list nil) | |
62746
0fe5c8d2cd65
(wdired-change-to-wdired-mode): Use run-mode-hooks.
Lute Kamstra <lute@gnu.org>
parents:
61473
diff
changeset
|
265 (run-mode-hooks 'wdired-mode-hook) |
67561
827930ad591b
(wdired-old-point): New internal variable.
Juri Linkov <juri@jurta.org>
parents:
65582
diff
changeset
|
266 (message "%s" (substitute-command-keys |
827930ad591b
(wdired-old-point): New internal variable.
Juri Linkov <juri@jurta.org>
parents:
65582
diff
changeset
|
267 "Press \\[wdired-finish-edit] when finished \ |
61030
6b0506554db8
(wdired-change-to-wdired-mode):
Juri Linkov <juri@jurta.org>
parents:
60141
diff
changeset
|
268 or \\[wdired-abort-changes] to abort changes"))) |
55098 | 269 |
270 | |
271 ;; Protect the buffer so only the filenames can be changed, and put | |
272 ;; properties so filenames (old and new) can be easily found. | |
273 (defun wdired-preprocess-files () | |
274 (put-text-property 1 2 'front-sticky t) | |
275 (save-excursion | |
276 (goto-char (point-min)) | |
277 (let ((b-protection (point)) | |
278 filename) | |
279 (while (not (eobp)) | |
280 (setq filename (dired-get-filename nil t)) | |
55109
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
281 (when (and filename |
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
282 (not (member (file-name-nondirectory filename) '("." "..")))) |
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
283 (dired-move-to-filename) |
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
284 (put-text-property (- (point) 2) (1- (point)) 'old-name filename) |
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
285 (put-text-property b-protection (1- (point)) 'read-only t) |
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
286 (setq b-protection (dired-move-to-end-of-filename t))) |
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
287 (put-text-property (point) (1+ (point)) 'end-name t) |
55098 | 288 (forward-line)) |
289 (put-text-property b-protection (point-max) 'read-only t)))) | |
290 | |
291 ;; This code is a copy of some dired-get-filename lines. | |
292 (defsubst wdired-normalize-filename (file) | |
293 (setq file | |
55109
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
294 ;; FIXME: shouldn't we check for a `b' argument or somesuch before |
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
295 ;; doing such unquoting? --Stef |
55098 | 296 (read (concat |
55109
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
297 "\"" (replace-regexp-in-string |
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
298 "\\([^\\]\\|\\`\\)\"" "\\1\\\\\"" file) |
55098 | 299 "\""))) |
300 (and file buffer-file-coding-system | |
301 (not file-name-coding-system) | |
302 (not default-file-name-coding-system) | |
303 (setq file (encode-coding-string file buffer-file-coding-system))) | |
304 file) | |
305 | |
306 (defun wdired-get-filename (&optional no-dir old) | |
307 "Return the filename at line. | |
55109
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
308 Similar to `dired-get-filename' but it doesn't rely on regexps. It |
61473 | 309 relies on WDired buffer's properties. Optional arg NO-DIR with value |
55098 | 310 non-nil means don't include directory. Optional arg OLD with value |
311 non-nil means return old filename." | |
55109
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
312 ;; FIXME: Use dired-get-filename's new properties. |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
313 (let* ((end (line-end-position)) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
314 (beg (next-single-property-change |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
315 (line-beginning-position) 'old-name nil end))) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
316 (unless (eq beg end) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
317 (let ((file |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
318 (if old |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
319 (get-text-property beg 'old-name) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
320 (wdired-normalize-filename |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
321 (buffer-substring-no-properties |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
322 (+ 2 beg) (next-single-property-change (1+ beg) 'end-name)))))) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
323 (if (or no-dir old) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
324 file |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
325 (and file (> (length file) 0) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
326 (concat (dired-current-directory) file))))))) |
55098 | 327 |
328 | |
329 (defun wdired-change-to-dired-mode () | |
330 "Change the mode back to dired." | |
331 (let ((inhibit-read-only t)) | |
332 (remove-text-properties (point-min) (point-max) | |
333 '(read-only nil local-map nil))) | |
334 (put-text-property 1 2 'front-sticky nil) | |
335 (use-local-map dired-mode-map) | |
55109
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
336 (force-mode-line-update) |
55098 | 337 (setq buffer-read-only t) |
338 (setq major-mode 'dired-mode) | |
339 (setq mode-name "Dired") | |
340 (dired-advertise) | |
341 (remove-hook 'kill-buffer-hook 'wdired-check-kill-buffer t) | |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
342 (set (make-local-variable 'revert-buffer-function) 'dired-revert)) |
55098 | 343 |
344 | |
345 (defun wdired-abort-changes () | |
346 "Abort changes and return to dired mode." | |
347 (interactive) | |
348 (let ((inhibit-read-only t)) | |
349 (erase-buffer) | |
67561
827930ad591b
(wdired-old-point): New internal variable.
Juri Linkov <juri@jurta.org>
parents:
65582
diff
changeset
|
350 (insert wdired-old-content) |
827930ad591b
(wdired-old-point): New internal variable.
Juri Linkov <juri@jurta.org>
parents:
65582
diff
changeset
|
351 (goto-char wdired-old-point)) |
55098 | 352 (wdired-change-to-dired-mode) |
353 (set-buffer-modified-p nil) | |
55371
a96e9558b1ea
(wdired-change-to-wdired-mode): Quote wdired-mode-hook in run-hooks.
Lars Hansen <larsh@soem.dk>
parents:
55109
diff
changeset
|
354 (setq buffer-undo-list nil) |
a96e9558b1ea
(wdired-change-to-wdired-mode): Quote wdired-mode-hook in run-hooks.
Lars Hansen <larsh@soem.dk>
parents:
55109
diff
changeset
|
355 (message "Changes aborted")) |
55098 | 356 |
357 (defun wdired-finish-edit () | |
358 "Actually rename files based on your editing in the Dired buffer." | |
359 (interactive) | |
360 (wdired-change-to-dired-mode) | |
61473 | 361 (let ((overwrite (or (not wdired-confirm-overwrite) 1)) |
55098 | 362 (changes nil) |
363 (files-deleted nil) | |
364 (errors 0) | |
365 file-ori file-new tmp-value) | |
366 (save-excursion | |
367 (if (and wdired-allow-to-redirect-links | |
368 (fboundp 'make-symbolic-link)) | |
369 (progn | |
370 (setq tmp-value (wdired-do-symlink-changes)) | |
371 (setq errors (cdr tmp-value)) | |
372 (setq changes (car tmp-value)))) | |
373 (if (and wdired-allow-to-change-permissions | |
374 (boundp 'wdired-col-perm)) ; could have been changed | |
375 (progn | |
376 (setq tmp-value (wdired-do-perm-changes)) | |
377 (setq errors (+ errors (cdr tmp-value))) | |
378 (setq changes (or changes (car tmp-value))))) | |
379 (goto-char (point-max)) | |
380 (while (not (bobp)) | |
381 (setq file-ori (wdired-get-filename nil t)) | |
382 (if file-ori | |
383 (setq file-new (wdired-get-filename))) | |
384 (if (and file-ori (not (equal file-new file-ori))) | |
385 (progn | |
386 (setq changes t) | |
387 (if (not file-new) ;empty filename! | |
388 (setq files-deleted (cons file-ori files-deleted)) | |
389 (progn | |
390 (setq file-new (substitute-in-file-name file-new)) | |
391 (if wdired-use-interactive-rename | |
392 (wdired-search-and-rename file-ori file-new) | |
56545
c3fa830eb56c
(wdired-finish-edit): Require dired-aux before locally binding dired-backup-overwrite.
Lars Hansen <larsh@soem.dk>
parents:
55371
diff
changeset
|
393 ;; If dired-rename-file autoloads dired-aux while |
c3fa830eb56c
(wdired-finish-edit): Require dired-aux before locally binding dired-backup-overwrite.
Lars Hansen <larsh@soem.dk>
parents:
55371
diff
changeset
|
394 ;; dired-backup-overwrite is locally bound, |
c3fa830eb56c
(wdired-finish-edit): Require dired-aux before locally binding dired-backup-overwrite.
Lars Hansen <larsh@soem.dk>
parents:
55371
diff
changeset
|
395 ;; dired-backup-overwrite won't be initialized. |
c3fa830eb56c
(wdired-finish-edit): Require dired-aux before locally binding dired-backup-overwrite.
Lars Hansen <larsh@soem.dk>
parents:
55371
diff
changeset
|
396 ;; So we must ensure dired-aux is loaded. |
c3fa830eb56c
(wdired-finish-edit): Require dired-aux before locally binding dired-backup-overwrite.
Lars Hansen <larsh@soem.dk>
parents:
55371
diff
changeset
|
397 (require 'dired-aux) |
55098 | 398 (condition-case err |
399 (let ((dired-backup-overwrite nil)) | |
400 (dired-rename-file file-ori file-new | |
401 overwrite)) | |
402 (error | |
403 (setq errors (1+ errors)) | |
404 (dired-log (concat "Rename `" file-ori "' to `" | |
405 file-new "' failed:\n%s\n") | |
406 err)))))))) | |
407 (forward-line -1))) | |
408 (if changes | |
409 (revert-buffer) ;The "revert" is necessary to re-sort the buffer | |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
410 (let ((inhibit-read-only t)) |
55098 | 411 (remove-text-properties (point-min) (point-max) |
412 '(old-name nil end-name nil old-link nil | |
413 end-link nil end-perm nil | |
414 old-perm nil perm-changed nil)) | |
415 (message "(No changes to be performed)"))) | |
416 (if files-deleted | |
417 (wdired-flag-for-deletion files-deleted)) | |
418 (if (> errors 0) | |
419 (dired-log-summary (format "%d rename actions failed" errors) nil))) | |
420 (set-buffer-modified-p nil) | |
421 (setq buffer-undo-list nil)) | |
422 | |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
423 ;; Rename a file, searching it in a modified dired buffer, in order |
55098 | 424 ;; to be able to use `dired-do-create-files-regexp' and get its |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
425 ;; "benefits". |
55098 | 426 (defun wdired-search-and-rename (filename-ori filename-new) |
427 (save-excursion | |
428 (goto-char (point-max)) | |
429 (forward-line -1) | |
430 (let ((exit-while nil) | |
431 curr-filename) | |
432 (while (not exit-while) | |
433 (setq curr-filename (wdired-get-filename)) | |
434 (if (and curr-filename | |
435 (equal (substitute-in-file-name curr-filename) filename-new)) | |
436 (progn | |
437 (setq exit-while t) | |
438 (let ((inhibit-read-only t)) | |
439 (dired-move-to-filename) | |
440 (search-forward (wdired-get-filename t) nil t) | |
441 (replace-match (file-name-nondirectory filename-ori) t t)) | |
442 (dired-do-create-files-regexp | |
443 (function dired-rename-file) | |
444 "Move" 1 ".*" filename-new nil t)) | |
445 (progn | |
446 (forward-line -1) | |
447 (beginning-of-line) | |
448 (setq exit-while (= 1 (point))))))))) | |
449 | |
450 ;; marks a list of files for deletion | |
451 (defun wdired-flag-for-deletion (filenames-ori) | |
452 (save-excursion | |
453 (goto-char (point-min)) | |
454 (while (not (eobp)) | |
455 (if (member (dired-get-filename nil t) filenames-ori) | |
456 (dired-flag-file-deletion 1) | |
457 (forward-line))))) | |
458 | |
459 (defun wdired-customize () | |
61473 | 460 "Customize WDired options." |
55098 | 461 (interactive) |
462 (customize-apropos "wdired" 'groups)) | |
463 | |
464 (defun wdired-revert (&optional arg noconfirm) | |
61473 | 465 "Discard changes in the buffer and update it based on changes on disk. |
466 Optional arguments are ignored." | |
55098 | 467 (wdired-change-to-dired-mode) |
468 (revert-buffer) | |
469 (wdired-change-to-wdired-mode)) | |
470 | |
471 (defun wdired-check-kill-buffer () | |
55109
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
472 ;; FIXME: Can't we use the normal mechanism for that? --Stef |
55098 | 473 (if (and |
474 (buffer-modified-p) | |
475 (not (y-or-n-p "Buffer changed. Discard changes and kill buffer? "))) | |
476 (error nil))) | |
477 | |
478 (defun wdired-next-line (arg) | |
479 "Move down lines then position at filename or the current column. | |
61473 | 480 See `wdired-use-dired-vertical-movement'. Optional prefix ARG |
55098 | 481 says how many lines to move; default is one line." |
482 (interactive "p") | |
483 (next-line arg) | |
61473 | 484 (if (or (eq wdired-use-dired-vertical-movement t) |
485 (and wdired-use-dired-vertical-movement | |
55098 | 486 (< (current-column) |
487 (save-excursion (dired-move-to-filename) | |
488 (current-column))))) | |
489 (dired-move-to-filename))) | |
490 | |
491 (defun wdired-previous-line (arg) | |
492 "Move up lines then position at filename or the current column. | |
61473 | 493 See `wdired-use-dired-vertical-movement'. Optional prefix ARG |
55098 | 494 says how many lines to move; default is one line." |
495 (interactive "p") | |
496 (previous-line arg) | |
61473 | 497 (if (or (eq wdired-use-dired-vertical-movement t) |
498 (and wdired-use-dired-vertical-movement | |
55098 | 499 (< (current-column) |
500 (save-excursion (dired-move-to-filename) | |
501 (current-column))))) | |
502 (dired-move-to-filename))) | |
503 | |
504 ;; Put the needed properties to allow the user to change links' targets | |
505 (defun wdired-preprocess-symlinks () | |
506 (let ((inhibit-read-only t)) | |
507 (save-excursion | |
508 (goto-char (point-min)) | |
509 (while (not (eobp)) | |
510 (if (looking-at dired-re-sym) | |
511 (progn | |
512 (re-search-forward " -> \\(.*\\)$") | |
513 (put-text-property (- (match-beginning 1) 2) | |
514 (1- (match-beginning 1)) 'old-link | |
515 (match-string-no-properties 1)) | |
516 (put-text-property (match-end 1) (1+ (match-end 1)) 'end-link t) | |
517 (put-text-property (1- (match-beginning 1)) | |
518 (match-end 1) 'read-only nil))) | |
519 (forward-line) | |
520 (beginning-of-line))))) | |
521 | |
522 | |
523 (defun wdired-get-previous-link (&optional old move) | |
524 "Return the next symlink target. | |
525 If OLD, return the old target. If MOVE, move point before it." | |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
526 (let ((beg (previous-single-property-change (point) 'old-link nil))) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
527 (when beg |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
528 (let ((target |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
529 (if old |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
530 (get-text-property (1- beg) 'old-link) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
531 (buffer-substring-no-properties |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
532 (1+ beg) (next-single-property-change beg 'end-link))))) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
533 (if move (goto-char (1- beg))) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
534 (and target (wdired-normalize-filename target)))))) |
55098 | 535 |
536 ;; Perform the changes in the target of the changed links. | |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
537 (defun wdired-do-symlink-changes () |
55098 | 538 (let ((changes nil) |
539 (errors 0) | |
540 link-to-ori link-to-new link-from) | |
541 (goto-char (point-max)) | |
542 (while (setq link-to-new (wdired-get-previous-link)) | |
543 (setq link-to-ori (wdired-get-previous-link t t)) | |
544 (setq link-from (wdired-get-filename nil t)) | |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
545 (unless (equal link-to-new link-to-ori) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
546 (setq changes t) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
547 (if (equal link-to-new "") ;empty filename! |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
548 (setq link-to-new "/dev/null")) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
549 (condition-case err |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
550 (progn |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
551 (delete-file link-from) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
552 (make-symbolic-link |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
553 (substitute-in-file-name link-to-new) link-from)) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
554 (error |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
555 (setq errors (1+ errors)) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
556 (dired-log (concat "Link `" link-from "' to `" |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
557 link-to-new "' failed:\n%s\n") |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
558 err))))) |
55098 | 559 (cons changes errors))) |
560 | |
561 ;; Perform a "case command" skipping read-only words. | |
562 (defun wdired-xcase-word (command arg) | |
563 (if (< arg 0) | |
564 (funcall command arg) | |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
565 (while (> arg 0) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
566 (condition-case err |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
567 (progn |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
568 (funcall command 1) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
569 (setq arg (1- arg))) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
570 (error |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
571 (if (not (forward-word 1)) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
572 (setq arg 0))))))) |
55098 | 573 |
574 (defun wdired-downcase-word (arg) | |
61473 | 575 "WDired version of `downcase-word'. |
55098 | 576 Like original function but it skips read-only words." |
577 (interactive "p") | |
578 (wdired-xcase-word 'downcase-word arg)) | |
579 | |
580 (defun wdired-upcase-word (arg) | |
61473 | 581 "WDired version of `upcase-word'. |
55098 | 582 Like original function but it skips read-only words." |
583 (interactive "p") | |
584 (wdired-xcase-word 'upcase-word arg)) | |
585 | |
586 (defun wdired-capitalize-word (arg) | |
61473 | 587 "WDired version of `capitalize-word'. |
55098 | 588 Like original function but it skips read-only words." |
589 (interactive "p") | |
590 (wdired-xcase-word 'capitalize-word arg)) | |
591 | |
592 | |
593 ;; The following code deals with changing the access bits (or | |
594 ;; permissions) of the files. | |
595 | |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
596 (defvar wdired-perm-mode-map |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
597 (let ((map (make-sparse-keymap))) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
598 (define-key map " " 'wdired-toggle-bit) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
599 (define-key map "r" 'wdired-set-bit) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
600 (define-key map "w" 'wdired-set-bit) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
601 (define-key map "x" 'wdired-set-bit) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
602 (define-key map "-" 'wdired-set-bit) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
603 (define-key map "S" 'wdired-set-bit) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
604 (define-key map "s" 'wdired-set-bit) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
605 (define-key map "T" 'wdired-set-bit) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
606 (define-key map "t" 'wdired-set-bit) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
607 (define-key map "s" 'wdired-set-bit) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
608 (define-key map "l" 'wdired-set-bit) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
609 (define-key map [down-mouse-1] 'wdired-mouse-toggle-bit) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
610 map)) |
55098 | 611 |
612 ;; Put a local-map to the permission bits of the files, and store the | |
613 ;; original name and permissions as a property | |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
614 (defun wdired-preprocess-perms () |
55098 | 615 (let ((inhibit-read-only t) |
616 filename) | |
617 (set (make-local-variable 'wdired-col-perm) nil) | |
618 (save-excursion | |
619 (goto-char (point-min)) | |
620 (while (not (eobp)) | |
621 (if (and (not (looking-at dired-re-sym)) | |
622 (setq filename (wdired-get-filename))) | |
623 (progn | |
624 (re-search-forward dired-re-perms) | |
625 (or wdired-col-perm | |
626 (setq wdired-col-perm (- (current-column) 9))) | |
627 (if (eq wdired-allow-to-change-permissions 'advanced) | |
628 (put-text-property (match-beginning 0) (match-end 0) | |
629 'read-only nil) | |
630 (put-text-property (1+ (match-beginning 0)) (match-end 0) | |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
631 'keymap wdired-perm-mode-map)) |
55098 | 632 (put-text-property (match-end 0) (1+ (match-end 0)) 'end-perm t) |
633 (put-text-property (match-beginning 0) (1+ (match-beginning 0)) | |
634 'old-perm (match-string-no-properties 0)))) | |
635 (forward-line) | |
636 (beginning-of-line))))) | |
637 | |
638 (defun wdired-perm-allowed-in-pos (char pos) | |
639 (cond | |
640 ((= char ?-) t) | |
641 ((= char ?r) (= (% pos 3) 0)) | |
642 ((= char ?w) (= (% pos 3) 1)) | |
643 ((= char ?x) (= (% pos 3) 2)) | |
644 ((memq char '(?s ?S)) (memq pos '(2 5))) | |
645 ((memq char '(?t ?T)) (= pos 8)) | |
646 ((= char ?l) (= pos 5)))) | |
647 | |
648 (defun wdired-set-bit () | |
649 "Set a permission bit character." | |
650 (interactive) | |
651 (if (wdired-perm-allowed-in-pos last-command-char | |
652 (- (current-column) wdired-col-perm)) | |
653 (let ((new-bit (char-to-string last-command-char)) | |
654 (inhibit-read-only t) | |
655 (pos-prop (- (point) (- (current-column) wdired-col-perm)))) | |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
656 (put-text-property 0 1 'keymap wdired-perm-mode-map new-bit) |
55098 | 657 (put-text-property 0 1 'read-only t new-bit) |
658 (insert new-bit) | |
659 (delete-char 1) | |
660 (put-text-property pos-prop (1- pos-prop) 'perm-changed t)) | |
661 (forward-char 1))) | |
662 | |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
663 (defun wdired-toggle-bit () |
55098 | 664 "Toggle the permission bit at point." |
665 (interactive) | |
666 (let ((inhibit-read-only t) | |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
667 (new-bit (cond |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
668 ((not (eq (char-after (point)) ?-)) "-") |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
669 ((= (% (- (current-column) wdired-col-perm) 3) 0) "r") |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
670 ((= (% (- (current-column) wdired-col-perm) 3) 1) "w") |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
671 (t "x"))) |
55098 | 672 (pos-prop (- (point) (- (current-column) wdired-col-perm)))) |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
673 (put-text-property 0 1 'keymap wdired-perm-mode-map new-bit) |
55098 | 674 (put-text-property 0 1 'read-only t new-bit) |
675 (insert new-bit) | |
676 (delete-char 1) | |
677 (put-text-property pos-prop (1- pos-prop) 'perm-changed t))) | |
678 | |
679 (defun wdired-mouse-toggle-bit (event) | |
680 "Toggle the permission bit that was left clicked." | |
681 (interactive "e") | |
682 (mouse-set-point event) | |
683 (wdired-toggle-bit)) | |
684 | |
685 ;; Allowed chars for 4000 bit are Ss in position 3 | |
686 ;; Allowed chars for 2000 bit are Ssl in position 6 | |
687 ;; Allowed chars for 1000 bit are Tt in position 9 | |
688 (defun wdired-perms-to-number (perms) | |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
689 (+ |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
690 (if (= (elt perms 1) ?-) 0 400) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
691 (if (= (elt perms 2) ?-) 0 200) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
692 (case (elt perms 3) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
693 (?- 0) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
694 (?S 4000) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
695 (?s 4100) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
696 (t 100)) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
697 (if (= (elt perms 4) ?-) 0 40) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
698 (if (= (elt perms 5) ?-) 0 20) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
699 (case (elt perms 6) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
700 (?- 0) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
701 (?S 2000) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
702 (?s 2010) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
703 (t 10)) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
704 (if (= (elt perms 7) ?-) 0 4) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
705 (if (= (elt perms 8) ?-) 0 2) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
706 (case (elt perms 9) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
707 (?- 0) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
708 (?T 1000) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
709 (?t 1001) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
710 (t 1)))) |
55098 | 711 |
712 ;; Perform the changes in the permissions of the files that have | |
713 ;; changed. | |
714 (defun wdired-do-perm-changes () | |
715 (let ((changes nil) | |
716 (errors 0) | |
717 (prop-wanted (if (eq wdired-allow-to-change-permissions 'advanced) | |
718 'old-perm 'perm-changed)) | |
719 filename perms-ori perms-new perm-tmp) | |
720 (goto-char (next-single-property-change (point-min) prop-wanted | |
721 nil (point-max))) | |
722 (while (not (eobp)) | |
723 (setq perms-ori (get-text-property (point) 'old-perm)) | |
724 (setq perms-new (buffer-substring-no-properties | |
725 (point) (next-single-property-change (point) 'end-perm))) | |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
726 (unless (equal perms-ori perms-new) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
727 (setq changes t) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
728 (setq filename (wdired-get-filename nil t)) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
729 (if (= (length perms-new) 10) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
730 (progn |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
731 (setq perm-tmp |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
732 (int-to-string (wdired-perms-to-number perms-new))) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
733 (unless (equal 0 (dired-call-process dired-chmod-program |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
734 t perm-tmp filename)) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
735 (setq errors (1+ errors)) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
736 (dired-log (concat dired-chmod-program " " perm-tmp |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
737 " `" filename "' failed\n\n")))) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
738 (setq errors (1+ errors)) |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
739 (dired-log (concat "Cannot parse permission `" perms-new |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
740 "' for file `" filename "'\n\n")))) |
55098 | 741 (goto-char (next-single-property-change (1+ (point)) prop-wanted |
742 nil (point-max)))) | |
743 (cons changes errors))) | |
744 | |
745 (provide 'wdired) | |
746 | |
68680
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
747 ;; Local Variables: |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
748 ;; coding: latin-1 |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
749 ;; byte-compile-dynamic: t |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
750 ;; End: |
bdaa27dd39d3
(wdired-mode-map): Use remap.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
68671
diff
changeset
|
751 |
55109
043dd9a4d1b4
(wdired-mode-map): Move init into declaration. Fix `return' binding.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
55107
diff
changeset
|
752 ;; arch-tag: bc00902e-526f-4305-bc7f-8862a559184f |
55098 | 753 ;;; wdired.el ends here |