aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config.org19
-rw-r--r--local-lib/dired+.el12379
2 files changed, 12396 insertions, 2 deletions
diff --git a/config.org b/config.org
index 44afa00..37864e0 100644
--- a/config.org
+++ b/config.org
@@ -185,9 +185,21 @@ I use jweigly's [[https://github.com/jwiegley/use-package][use-package]] to mana
185 (package-install 'use-package)) 185 (package-install 'use-package))
186(eval-when-compile 186(eval-when-compile
187 (require 'use-package)) 187 (require 'use-package))
188
188;; slight optimization for use-package's :bind directive 189;; slight optimization for use-package's :bind directive
189(require 'bind-key) 190(require 'bind-key)
190#+END_SRC 191#+END_SRC
192
193Emacs on *nix systems may use a different set of environment variables. This
194package can be used to copy over variables from the shell
195
196#+BEGIN_SRC emacs-lisp
197(use-package exec-path-from-shell
198 :ensure t
199 :init
200 (exec-path-from-shell-copy-env "RUST_SRC_PATH")
201 (exec-path-from-shell-initialize))
202#+END_SRC
191* Themes 203* Themes
192[[https://github.com/synic/jbeans-emacs][jbeans]] is a jellybeans.vim clone maintained by synic 204[[https://github.com/synic/jbeans-emacs][jbeans]] is a jellybeans.vim clone maintained by synic
193 205
@@ -288,7 +300,7 @@ Features include:
288- Dired current file and file at point commands (C-x C-j) 300- Dired current file and file at point commands (C-x C-j)
289 301
290#+BEGIN_SRC emacs-lisp 302#+BEGIN_SRC emacs-lisp
291(require 'dired-x) 303;; (require 'dired-x)
292#+END_SRC 304#+END_SRC
293 305
294Emacs' philosophy is to create a new buffer for new content. This makes sense 306Emacs' philosophy is to create a new buffer for new content. This makes sense
@@ -296,8 +308,11 @@ for an editor but a file manager usually reuses it's window as you browse the
296file system. This reverts dired to that behavior, but doesn't fix it if you use 308file system. This reverts dired to that behavior, but doesn't fix it if you use
297the mouse to click a directory or filename. 309the mouse to click a directory or filename.
298 310
311- Downloaded dired+.el from https://www.emacswiki.org/emacs/DiredPlus
312
299#+BEGIN_SRC emacs-lisp 313#+BEGIN_SRC emacs-lisp
300(put 'dired-find-alternate-file 'disabled nil) 314(require 'dired+)
315(toggle-diredp-find-file-reuse-dir 1)
301#+END_SRC 316#+END_SRC
302** avy 317** avy
303[[https://github.com/abo-abo/avy][avy]] is a quick way to jump around buffers 318[[https://github.com/abo-abo/avy][avy]] is a quick way to jump around buffers
diff --git a/local-lib/dired+.el b/local-lib/dired+.el
new file mode 100644
index 0000000..627c257
--- /dev/null
+++ b/local-lib/dired+.el
@@ -0,0 +1,12379 @@
1;;; dired+.el --- Extensions to Dired.
2;;
3;; Filename: dired+.el
4;; Description: Extensions to Dired.
5;; Author: Drew Adams
6;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com")
7;; Copyright (C) 1999-2018, Drew Adams, all rights reserved.
8;; Created: Fri Mar 19 15:58:58 1999
9;; Version: 2017.10.23
10;; Package-Requires: ()
11;; Last-Updated: Sat Jun 30 15:00:20 2018 (-0700)
12;; By: dradams
13;; Update #: 10981
14;; URL: https://www.emacswiki.org/emacs/download/dired%2b.el
15;; Doc URL: https://www.emacswiki.org/emacs/DiredPlus
16;; Keywords: unix, mouse, directories, diredp, dired
17;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x, 24.x, 25.x, 26.x
18;;
19;; Features that might be required by this library:
20;;
21;; `apropos', `apropos+', `autofit-frame', `avoid', `bookmark',
22;; `bookmark+', `bookmark+-1', `bookmark+-bmu', `bookmark+-key',
23;; `bookmark+-lit', `dired', `dired+', `dired-aux', `dired-x',
24;; `easymenu', `ffap', `fit-frame', `frame-fns', `help+20',
25;; `highlight', `image-dired', `image-file', `info', `info+20',
26;; `kmacro', `menu-bar', `menu-bar+', `misc-cmds', `misc-fns',
27;; `naked', `pp', `pp+', `second-sel', `strings', `subr-21',
28;; `thingatpt', `thingatpt+', `unaccent', `w32-browser',
29;; `w32browser-dlgopen', `wid-edit', `wid-edit+', `widget'.
30;;
31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
32;;
33;;; Commentary:
34;;
35;; Extensions to Dired.
36;;
37;; This file extends functionalities provided by standard GNU Emacs
38;; files `dired.el', `dired-aux.el', and `dired-x.el'.
39;;
40;; Key bindings changed. Menus redefined. `diredp-mouse-3-menu'
41;; popup menu added. New commands. Some commands enhanced.
42;;
43;; All of the new functions, variables, and faces defined here have
44;; the prefix `diredp-' (for Dired Plus) in their names.
45;;
46;;
47;; Wraparound Navigation
48;; ---------------------
49;;
50;; In vanilla Dired, `dired-next-marked-file' (`M-}' or `* C-n') and
51;; `dired-previous-marked-file' (`M-{' or `* C-p') wrap around when
52;; you get to the end or the beginning of the Dired buffer. Handy.
53;;
54;; But the other navigation commands do not wrap around. In `Dired+'
55;; they do, provided option `diredp-wrap-around-flag' is non-nil,
56;; which it is by default. This means the following commands:
57;;
58;; `diredp-next-line' - `n', `C-n', `down', `SPC'
59;; `diredp-previous-line' - `p', `C-p', `up'
60;; `diredp-next-dirline' - `>'
61;; `diredp-prev-dirline' - `<'
62;; `diredp-next-subdir' - `C-M-n'
63;; `diredp-prev-subdir' - `C-M-p'
64;;
65;;
66;; Quick Viewing While Navigating
67;; ------------------------------
68;;
69;; You can use key `C-down' or `C-up' to navigate to the next or
70;; previous file line, respectively, and at the same time show its
71;; file in another window. The focus remains on the Dired buffer.
72;; A numeric prefix arg means move that many lines first.
73;;
74;; Names of files and directories that match either of the options
75;; `diredp-visit-ignore-extensions' or `diredp-visit-ignore-regexps'
76;; are skipped.
77;;
78;; You can use `e' to show the file of the current line. If it is
79;; already shown in the same frame, and if Dired is the only other
80;; window there, then the file is hidden (its window is deleted).
81;;
82;;
83;; Font-Lock Highlighting
84;; ----------------------
85;;
86;; If you want a maximum or minimum fontification for Dired mode,
87;; then customize option `font-lock-maximum-decoration'. If you want
88;; a different fontification level for Dired than for other modes,
89;; you can do this too by customizing
90;; `font-lock-maximize-decoration'.
91;;
92;; A few of the user options defined here have an effect on
93;; font-locking, and this effect is established only when Dired+ is
94;; loaded, which defines the font-lock keywords for Dired. These
95;; options include `diredp-compressed-extensions',
96;; `diredp-ignore-compressed-flag', and `dired-omit-extensions'.
97;; This means that if you change the value of such an option then you
98;; will see the change only in a new Emacs session.
99;;
100;; (You can see the effect in the same session if you use `C-M-x' on
101;; the `defvar' sexp for `diredp-font-lock-keywords-1', and then you
102;; toggle font-lock off and back on.)
103;;
104;;
105;; Act on All Files
106;; ----------------
107;;
108;; Most of the commands (such as `C' and `M-g') that operate on the
109;; marked files have the added feature here that multiple `C-u' use
110;; not the files that are marked or the next or previous N files, but
111;; *all* of the files in the Dired buffer. Just what "all" files
112;; means changes with the number of `C-u', as follows:
113;;
114;; `C-u C-u' - Use all files present, but no directories.
115;; `C-u C-u C-u' - Use all files and dirs except `.' and `..'.
116;; `C-u C-u C-u C-u' - use all files and dirs, `.' and `..'.
117;;
118;; (More than four `C-u' act the same as two.)
119;;
120;; This feature can be particularly useful when you have a Dired
121;; buffer with files chosen from multiple directories.
122;;
123;; Note that in most cases this behavior is described only in the doc
124;; string of function `dired-get-marked-files'. It is generally
125;; *not* described in the doc strings of the various commands,
126;; because that would require redefining each command separately
127;; here. Instead, we redefine macro `dired-map-over-marks' and
128;; function `dired-get-filename' in order to achieve this effect.
129;;
130;; Commands such as `dired-do-load' for which it does not make sense
131;; to act on directories generally treat more than two `C-u' the same
132;; as two `C-u'.
133;;
134;; Exceptions to the general behavior described here are called out
135;; in the doc strings. In particular, the behavior of a prefix arg
136;; for `dired-do-query-replace-regexp' is different, so that you can
137;; use it also to specify word-delimited replacement.
138;;
139;;
140;; Act on Marked (or All) Files Here and Below
141;; -------------------------------------------
142;;
143;; The prefix argument behavior just described does not apply to the
144;; `diredp-*-recursive' commands. These commands act on the marked
145;; files in the current Dired buffer or on all files in the directory
146;; if none are marked.
147;;
148;; But these commands also handle marked subdirectories recursively,
149;; in the same way. That is, they act also on the marked files in
150;; any marked subdirectories, found recursively. If such a
151;; descendant directory is listed in a Dired buffer then its marked
152;; files and subdirs are handled the same way. If there is no Dired
153;; buffer that lists a given marked subdirectory then all of its
154;; files and subdirs are acted on.
155;;
156;; For most such here-and-below commands, a prefix argument means
157;; ignore all marks. The commands then act on all files in the
158;; current Dired buffer and all of its subdirectories, recursively.
159;;
160;; But here-and-below commands that unmark or change marks act
161;; differently for different kinds of prefix argument:
162;;
163;; * A non-positive prefix arg means ignore subdir markings and act
164;; instead on ALL subdirs.
165;;
166;; * A non-negative prefix arg means do not change marks on subdirs
167;; themselves.
168;;
169;; For example, `M-+ U' removes all marks, including from marked
170;; subdirs, recursively. `C-- M-+ U' removes them from all files in
171;; all subdirs (marked or not), recursively. `C-9 M-+ U' removes all
172;; marks, recursively, except the marks on subdirs themselves. `C-0
173;; M-+ U' acts like those two combined: it descends everywhere,
174;; ignoring which subdirs are marked, but it does not remove marks
175;; from subdirs themselves.
176;;
177;; All of the `diredp-*-recursive' commands are on prefix key `M-+',
178;; and all are available on submenu `Marked Here and Below' of the
179;; `Multiple' menu-bar menu. The commands that unmark and change
180;; marks are also in submenu `Here and Below' of menu-bar menu
181;; `Marks'.
182;;
183;; If you use library `Icicles' then you have the following
184;; additional commands/keys that act recursively on marked files.
185;; They are in the `Icicles' submenu of menu `Multiple' > `Marked
186;; Here and Below'.
187;;
188;; * `M-+ M-s M-s' or `M-s M-s m' - Use Icicles search (and its
189;; on-demand replace) on the marked files.
190;;
191;; * Save the names of the marked files:
192;;
193;; `M-+ C-M->' - Save as a completion set, for use during
194;; completion (e.g. with `C-x C-f').
195;;
196;; `M-+ C->' - Add marked names to the names in the current saved
197;; completion set.
198;;
199;; `M-+ C-}' - Save persistently to an Icicles cache file, for
200;; use during completion in another session.
201;;
202;; `icicle-dired-save-marked-to-fileset-recursive' - Like `M-+
203;; C-}', but save persistently to an Emacs fileset.
204;;
205;; `M-+ C-M-}' - Save to a Lisp variable.
206;;
207;;
208;; In the other direction, if you have a saved set of file names then
209;; you can use `C-M-<' (`icicle-dired-chosen-files-other-window') in
210;; Dired to open a Dired buffer for just those files. So you can
211;; mark some files and subdirs in a hierarchy of Dired buffers, use
212;; `M-+ C-}' to save their names persistently, then later use `C-{'
213;; to retrieve them, and `C-M-<' (in Dired) to open Dired on them.
214;;
215;;
216;; Image Files
217;; -----------
218;;
219;; `Dired+' provides several enhancements regarding image files.
220;; Most of these require standard library `image-dired.el'. One of
221;; them, command `diredp-do-display-images', which displays all of
222;; the marked image files, requires standard library `image-file.el'.
223;;
224;; `Dired+' loads these libraries automatically, if available, which
225;; means an Emacs version that supports image display (Emacs 22 or
226;; later). (You must of course have installed whatever else your
227;; Emacs version needs to display images.)
228;;
229;; Besides command `diredp-do-display-images', see the commands whose
230;; names have prefix `diredp-image-'. And see options
231;; `diredp-image-preview-in-tooltip' and
232;; `diredp-auto-focus-frame-for-thumbnail-tooltip-flag'.
233;;
234;;
235;; Inserted Subdirs, Multiple Dired Buffers, Files from Anywhere,...
236;; -----------------------------------------------------------------
237;;
238;; These three standard Dired features are worth pointing out. The
239;; third in particular is little known because (a) it is limited in
240;; vanilla Dired and (b) you cannot use it interactively.
241;;
242;; * You can pass a glob pattern with wildcards to `dired'
243;; interactively, as the file name.
244;;
245;; * You can insert multiple subdirectory listings into a single
246;; Dired buffer using `i' on each subdir line. Use `C-u i' to
247;; specify `ls' switches. Specifying switch `R' inserts the
248;; inserted subdirectory's subdirs also, recursively. You can
249;; also use `i' to bounce between a subdirectory line and its
250;; inserted-listing header line. You can delete a subdir listing
251;; using `C-u k' on its header line. You can hide/show an
252;; inserted subdir using `$'. You can use `C-_' to undo any of
253;; these operations.
254;;
255;; * You can open a Dired buffer for an arbitrary set of files from
256;; different directories. You do this by invoking `dired'
257;; non-interactively, passing it a cons of a Dired buffer name and
258;; the file names. Relative file names are interpreted relative
259;; to the value of `default-directory'. Use absolute file names
260;; when appropriate.
261;;
262;; `Dired+' makes these features more useful.
263;;
264;; `$' is improved: It is a simple toggle - it does not move the
265;; cursor forward. `M-$' advances the cursor, in addition to
266;; toggling like `$'. `C-u $' does hide/show all (what `M-$' does in
267;; vanilla Dired).
268;;
269;; `i' is improved in these ways:
270;;
271;; * Once a subdir has been inserted, `i' bounces between the subdir
272;; listing and the subdir line in the parent listing. If the
273;; parent dir is hidden, then `i' from a subdir opens the parent
274;; listing so it can move to the subdir line there (Emacs 24+).
275;;
276;; * Vanilla Dired lets you create a Dired listing with files and
277;; directories from arbitrary locations, but you cannot insert
278;; (`i') such a directory if it is not in the same directory tree
279;; as the `default-directory' used to create the Dired buffer.
280;; `Dired+' removes this limitation; you can insert any non-root
281;; directories (that is, not `/', `c:/', etc.).
282;;
283;; `Dired+' lets you create Dired buffers that contain arbitrary
284;; files and directories interactively, not just using Lisp. Just
285;; use a non-positive prefix arg (e.g., `C--') when invoking `dired'.
286;;
287;; You are then prompted for the Dired buffer name (anything you
288;; like, not necessarily a directory name) and the individual files
289;; and directories that you want listed.
290;;
291;; A non-negative prefix arg still prompts you for the `ls' switches
292;; to use. (So `C-0' does both: prompts for `ls' switches and for
293;; the Dired buffer name and the files to list.)
294;;
295;; `Dired+' adds commands for combining and augmenting Dired
296;; listings:
297;;
298;; * `diredp-add-to-dired-buffer', bound globally to `C-x D A', lets
299;; you add arbitrary file and directory names to an existing Dired
300;; buffer.
301;;
302;; * `diredp-dired-union', bound globally to `C-x D U', lets you
303;; take the union of multiple Dired listings, or convert an
304;; ordinary Dired listing to an explicit list of absolute file
305;; names. With a non-positive prefix arg, you can add extra file
306;; and directory names, just as for `diredp-add-to-dired-buffer'.
307;;
308;; You can optionally add a header line to a Dired buffer using
309;; toggle command `diredp-breadcrumbs-in-header-line-mode'. (A
310;; header line remains at the top of the window - no need to scroll
311;; to see it.) If you want to show the header line automatically in
312;; all Dired buffers, you can do this:
313;;
314;; (add-hook 'dired-before-readin-hook
315;; 'diredp-breadcrumbs-in-header-line-mode)
316;;
317;; Some other libraries, such as `Bookmark+' and `Icicles', make it
318;; easy to create or re-create Dired buffers that list specific files
319;; and have a particular set of markings. `Bookmark+' records Dired
320;; buffers persistently, remembering `ls' switches, markings, subdir
321;; insertions, and hidden subdirs. If you use `Icicles' then `dired'
322;; is a multi-command: you can open multiple Dired buffers with one
323;; `dired' invocation.
324;;
325;; Dired can help you manage projects. You might have multiple Dired
326;; buffers with quite specific contents. You might have some
327;; subdirectories inserted in the same Dired buffer, and you might
328;; have separate Dired buffers for some subdirectories. Sometimes it
329;; is useful to have both for the same subdirectory. And sometimes
330;; it is useful to move from one presentation to the other.
331;;
332;; This is one motivation for the `Dired+' `diredp-*-recursive'
333;; commands, which act on the marked files in marked subdirectories,
334;; recursively. In one sense, these commands are an alternative to
335;; using a single Dired buffer with inserted subdirectories. They
336;; let you use the same operations on the files in a set of Dired
337;; directories, without inserting those directories into an ancestor
338;; Dired buffer.
339;;
340;; You can use command `diredp-dired-inserted-subdirs' to open a
341;; separate Dired buffer for each of the subdirs that is inserted in
342;; the current Dired buffer. Markings and Dired switches are
343;; preserved.
344;;
345;; In the opposite direction, if you use `Icicles' then you can use
346;; multi-command `icicle-dired-insert-as-subdir', which lets you
347;; insert any number of directories you choose interactively into a
348;; Dired ancestor directory listing. If a directory you choose to
349;; insert already has its own Dired buffer, then its markings and
350;; switches are preserved for the new, subdirectory listing in the
351;; ancestor Dired buffer.
352;;
353;;
354;; Hide/Show Details
355;; -----------------
356;;
357;; Starting with Emacs 24.4, listing details are hidden by default.
358;; Note that this is different from the vanilla Emacs behavior, which
359;; is to show details by default.
360;;
361;; Use `(' anytime to toggle this hiding. You can use option
362;; `diredp-hide-details-initially-flag' to change the default/initial
363;; state. See also option `diredp-hide-details-propagate-flag'.
364;;
365;; NOTE: If you do not want to hide details initially then you must
366;; either (1) change `diredp-hide-details-initially-flag' using
367;; Customize (recommended) or (2) set it to `nil' (e.g., using
368;; `setq') *BEFORE* loading `dired+.el'.
369;;
370;; If you have an Emacs version older than 24.4, you can use library
371;; `dired-details+.el' (plus `dired-details.el') to get similar
372;; behavior.
373;;
374;;
375;; Mode-Line
376;; ---------
377;;
378;; The number of files and dirs that are marked with `*', and the
379;; number that are flagged for deletion (marked `D') are indicated in
380;; the mode-line. When the cursor is on such a line the indication
381;; tells you how many more there are. For example, if the cursor is
382;; on the line of the third file that is marked `*', and there are
383;; seven of them total, then the mode-line shows `3/7*'.
384;;
385;; The mode-line also indicates, for the current listing (which could
386;; be a subdir listing), how many files and dirs are listed. If the
387;; cursor is on the 27th file in a listing of 78 files then the
388;; mode-line shows 27/78.
389;;
390;; For counting files and dirs in a listing, option
391;; `diredp-count-.-and-..-flag' controls whether to count the lines
392;; for `.' and `..'. By default it is nil, meaning they are not
393;; counted.
394;;
395;;
396;; If You Use Dired+ in Terminal Mode
397;; ----------------------------------
398;;
399;; By default, Dired+ binds some keys that can be problematic in some
400;; terminals when you use Emacs in terminal mode (i.e., `emacs -nw').
401;; This is controlled by option
402;; `diredp-bind-problematic-terminal-keys'.
403;;
404;; In particular, keys that use modifiers Meta and Shift together can
405;; be problematic. If you use Dired+ in text-only terminal, and you
406;; find that your terminal does not support such keys, then you might
407;; want to customize the option to set the value to `nil', and then
408;; bind the commands to some other keys, which your terminal
409;; supports.
410;;
411;; The problematic keys used by Dired+ include these:
412;;
413;; `M-M' (aka `M-S-m') - `diredp-chmod-this-file'
414;; `M-O' (aka `M-S-o') - `diredp-chown-this-file'
415;; `M-T' (aka `M-S-t') - `diredp-touch-this-file'
416;; `C-M-B' (aka `C-M-S-b') - `diredp-do-bookmark-in-bookmark-file'
417;; `C-M-G' (aka `C-M-S-g') - `diredp-chgrp-this-file'
418;; `C-M-R' (aka `C-M-S-r') - `diredp-toggle-find-file-reuse-dir'
419;; `C-M-T' (aka `C-M-S-t') - `dired-do-touch'
420;; `M-+ M-B' (aka `M-+ M-S-b') -
421;; `diredp-do-bookmark-dirs-recursive'
422;; `M-+ C-M-B' (aka `M-+ C-M-S-b') -
423;; `diredp-do-bookmark-in-bookmark-file-recursive'
424;; `M-+ C-M-T' (aka `M-+ C-M-S-t') - `diredp-do-touch-recursive'
425;;
426;; (See also `(info "(org) TTY keys")' for more information about
427;; keys that can be problematic in a text-only terminal.)
428;;
429;;
430;; Faces defined here:
431;;
432;; `diredp-autofile-name', `diredp-compressed-file-suffix',
433;; `diredp-date-time', `diredp-deletion',
434;; `diredp-deletion-file-name', `diredp-dir-heading',
435;; `diredp-dir-priv', `diredp-exec-priv', `diredp-executable-tag',
436;; `diredp-file-name', `diredp-file-suffix', `diredp-flag-mark',
437;; `diredp-flag-mark-line', `diredp-get-file-or-dir-name',
438;; `diredp-ignored-file-name', `diredp-link-priv',
439;; `diredp-mode-line-flagged', `diredp-mode-line-marked'
440;; `diredp-no-priv', `diredp-number', `diredp-other-priv',
441;; `diredp-rare-priv', `diredp-read-priv', `diredp-symlink',
442;; `diredp-tagged-autofile-name', `diredp-write-priv'.
443;;
444;; Commands defined here:
445;;
446;; `diredp-add-to-dired-buffer', `diredp-add-to-this-dired-buffer',
447;; `diredp-do-apply-function',
448;; `diredp-do-apply-function-recursive',
449;; `diredp-async-shell-command-this-file',
450;; `diredp-bookmark-this-file',
451;; `diredp-breadcrumbs-in-header-line-mode' (Emacs 22+),
452;; `diredp-byte-compile-this-file', `diredp-capitalize',
453;; `diredp-capitalize-recursive', `diredp-capitalize-this-file',
454;; `diredp-change-marks-recursive' (Emacs 22+),
455;; `diredp-chgrp-this-file', `diredp-chmod-this-file',
456;; `diredp-chown-this-file',
457;; `diredp-compilation-files-other-window' (Emacs 24+),
458;; `diredp-compress-this-file',
459;; `diredp-copy-abs-filenames-as-kill',
460;; `diredp-copy-abs-filenames-as-kill-recursive',
461;; `diredp-copy-filename-as-kill-recursive',
462;; `diredp-copy-tags-this-file', `diredp-copy-this-file',
463;; `diredp-decrypt-this-file', `diredp-delete-this-file',
464;; `diredp-describe-autofile', `diredp-describe-file',
465;; `diredp-describe-marked-autofiles', `diredp-describe-mode',
466;; `diredp-dired-for-files', `diredp-dired-for-files-other-window',
467;; `diredp-dired-inserted-subdirs', `diredp-dired-plus-help',
468;; `diredp-dired-recent-dirs',
469;; `diredp-dired-recent-dirs-other-window',
470;; `diredp-dired-this-subdir', `diredp-dired-union',
471;; `diredp-do-async-shell-command-recursive', `diredp-do-bookmark',
472;; `diredp-do-bookmark-dirs-recursive',
473;; `diredp-do-bookmark-in-bookmark-file',
474;; `diredp-do-bookmark-in-bookmark-file-recursive',
475;; `diredp-do-bookmark-recursive', `diredp-do-chmod-recursive',
476;; `diredp-do-chgrp-recursive', `diredp-do-chown-recursive',
477;; `diredp-do-copy-recursive', `diredp-do-decrypt-recursive',
478;; `diredp-do-delete-recursive', `diredp-do-display-images' (Emacs
479;; 22+), `diredp-do-encrypt-recursive',
480;; `diredp-do-find-marked-files-recursive', `diredp-do-grep',
481;; `diredp-do-grep-recursive', `diredp-do-hardlink-recursive',
482;; `diredp-do-isearch-recursive',
483;; `diredp-do-isearch-regexp-recursive',
484;; `diredp-do-move-recursive', `diredp-do-paste-add-tags',
485;; `diredp-do-paste-replace-tags', `diredp-do-print-recursive',
486;; `diredp-do-query-replace-regexp-recursive',
487;; `diredp-do-redisplay-recursive',
488;; `diredp-do-relsymlink-recursive', `diredp-do-remove-all-tags',
489;; `diredp-do-search-recursive', `diredp-do-set-tag-value',
490;; `diredp-do-shell-command-recursive', `diredp-do-sign-recursive',
491;; `diredp-do-symlink-recursive', `diredp-do-tag',
492;; `diredp-do-touch-recursive', `diredp-do-untag',
493;; `diredp-do-verify-recursive', `diredp-downcase-recursive',
494;; `diredp-downcase-this-file', `diredp-ediff',
495;; `diredp-encrypt-this-file', `diredp-fileset',
496;; `diredp-fileset-other-window', `diredp-find-a-file',
497;; `diredp-find-a-file-other-frame',
498;; `diredp-find-a-file-other-window',
499;; `diredp-find-file-other-frame',
500;; `diredp-find-file-reuse-dir-buffer',
501;; `diredp-find-line-file-other-window',
502;; `diredp-flag-auto-save-files-recursive',
503;; `diredp-flag-region-files-for-deletion',
504;; `diredp-grepped-files-other-window', `diredp-grep-this-file',
505;; `diredp-hardlink-this-file', `diredp-highlight-autofiles-mode',
506;; `diredp-image-dired-comment-file',
507;; `diredp-image-dired-comment-files-recursive',
508;; `diredp-image-dired-copy-with-exif-name',
509;; `diredp-image-dired-create-thumb',
510;; `diredp-image-dired-delete-tag',
511;; `diredp-image-dired-delete-tag-recursive',
512;; `diredp-image-dired-display-thumb',
513;; `diredp-image-dired-display-thumbs-recursive',
514;; `diredp-image-dired-edit-comment-and-tags',
515;; `diredp-image-dired-tag-file',
516;; `diredp-image-dired-tag-files-recursive',
517;; `diredp-image-show-this-file', `diredp-insert-as-subdir',
518;; `diredp-insert-subdirs', `diredp-insert-subdirs-recursive',
519;; `diredp-kill-this-tree', `diredp-list-marked-recursive',
520;; `diredp-load-this-file', `diredp-mark-autofiles',
521;; `diredp-marked', `diredp-marked-other-window',
522;; `diredp-marked-recursive',
523;; `diredp-marked-recursive-other-window',
524;; `diredp-mark-extension-recursive',
525;; `diredp-mark-files-regexp-recursive',
526;; `diredp-mark-files-tagged-all', `diredp-mark-files-tagged-none',
527;; `diredp-mark-files-tagged-not-all',
528;; `diredp-mark-files-tagged-some',
529;; `diredp-mark-files-tagged-regexp', `diredp-mark-region-files',
530;; `diredp-mark/unmark-autofiles', `diredp-mark/unmark-extension',
531;; `diredp-mouse-3-menu', `diredp-mouse-backup-diff',
532;; `diredp-mouse-copy-tags', `diredp-mouse-describe-autofile',
533;; `diredp-mouse-describe-file', `diredp-mouse-diff',
534;; `diredp-mouse-do-bookmark', `diredp-mouse-do-byte-compile',
535;; `diredp-mouse-do-chgrp', `diredp-mouse-do-chmod',
536;; `diredp-mouse-do-chown', `diredp-mouse-do-compress',
537;; `diredp-mouse-do-copy', `diredp-mouse-do-delete',
538;; `diredp-mouse-do-grep', `diredp-mouse-do-hardlink',
539;; `diredp-mouse-do-load', `diredp-mouse-do-print',
540;; `diredp-mouse-do-remove-all-tags', `diredp-mouse-do-rename',
541;; `diredp-mouse-do-set-tag-value',
542;; `diredp-mouse-do-shell-command', `diredp-mouse-do-symlink',
543;; `diredp-mouse-do-tag', `diredp-mouse-do-untag',
544;; `diredp-mouse-downcase', `diredp-mouse-ediff',
545;; `diredp-mouse-find-line-file-other-window',
546;; `diredp-mouse-find-file-other-frame',
547;; `diredp-mouse-find-file-reuse-dir-buffer',
548;; `diredp-mouse-flag-file-deletion', `diredp-mouse-mark',
549;; `diredp-mouse-mark-region-files', `diredp-mouse-mark/unmark',
550;; `diredp-mouse-unmark', `diredp-mouse-upcase',
551;; `diredp-mouse-view-file',
552;; `diredp-multiple-w32-browser-recursive',
553;; `diredp-nb-marked-in-mode-name', `diredp-next-dirline',
554;; `diredp-next-line', `diredp-next-subdir', `diredp-omit-marked',
555;; `diredp-omit-unmarked', `diredp-paste-add-tags-this-file',
556;; `diredp-paste-files', `diredp-paste-replace-tags-this-file',
557;; `diredp-prev-dirline', `diredp-previous-line',
558;; `diredp-prev-subdir', `diredp-print-this-file',
559;; `diredp-relsymlink-this-file',
560;; `diredp-remove-all-tags-this-file', `diredp-rename-this-file',
561;; `diredp-send-bug-report',
562;; `diredp-set-bookmark-file-bookmark-for-marked',
563;; `diredp-set-bookmark-file-bookmark-for-marked-recursive',
564;; `diredp-set-tag-value-this-file',
565;; `diredp-shell-command-this-file', `diredp-show-metadata',
566;; `diredp-show-metadata-for-marked', `diredp-sign-this-file',
567;; `diredp-symlink-this-file', `diredp-tag-this-file',
568;; `diredp-toggle-find-file-reuse-dir',
569;; `diredp-toggle-marks-in-region', `diredp-touch-this-file',
570;; `diredp-unmark-all-files-recursive' (Emacs 22+),
571;; `diredp-unmark-all-marks-recursive' (Emacs 22+),
572;; `diredp-unmark-autofiles', `diredp-unmark-files-tagged-all',
573;; `diredp-unmark-files-tagged-none',
574;; `diredp-unmark-files-tagged-not-all',
575;; `diredp-unmark-files-tagged-some', `diredp-unmark-region-files',
576;; `diredp-untag-this-file', `diredp-upcase-recursive',
577;; `diredp-up-directory', `diredp-up-directory-reuse-dir-buffer',
578;; `diredp-upcase-this-file', `diredp-verify-this-file',
579;; `diredp-visit-next-file', `diredp-visit-previous-file',
580;; `diredp-visit-this-file', `diredp-w32-drives',
581;; `diredp-w32-drives-mode', `diredp-yank-files',
582;; `global-dired-hide-details-mode' (Emacs 24.4+),
583;; `toggle-diredp-find-file-reuse-dir'.
584;;
585;; User options defined here:
586;;
587;; `diredp-auto-focus-frame-for-thumbnail-tooltip-flag',
588;; `diredp-bind-problematic-terminal-keys',
589;; `diredp-compressed-extensions', `diredp-count-.-and-..-flag'
590;; (Emacs 22+), `diredp-dwim-any-frame-flag' (Emacs 22+),
591;; `diredp-image-preview-in-tooltip', `diff-switches',
592;; `diredp-hide-details-initially-flag' (Emacs 24.4+),
593;; `diredp-highlight-autofiles-mode',
594;; `diredp-hide-details-propagate-flag' (Emacs 24.4+),
595;; `diredp-ignore-compressed-flag',
596;; `diredp-image-show-this-file-use-frame-flag' (Emacs 22+),
597;; `diredp-max-frames', `diredp-prompt-for-bookmark-prefix-flag',
598;; `diredp-visit-ignore-extensions', `diredp-visit-ignore-regexps',
599;; `diredp-w32-local-drives', `diredp-wrap-around-flag'.
600;;
601;; Non-interactive functions defined here:
602;;
603;; `derived-mode-p' (Emacs < 22), `diredp-all-files',
604;; `diredp-ancestor-dirs', `diredp-bookmark',
605;; `diredp-create-files-non-directory-recursive',
606;; `diredp-delete-dups', `diredp-delete-if-not',
607;; `diredp-directories-within', `diredp-dired-plus-description',
608;; `diredp-dired-plus-description+links',
609;; `diredp-dired-plus-help-link', `diredp-dired-union-1',
610;; `diredp-dired-union-interactive-spec', `diredp-display-image'
611;; (Emacs 22+), `diredp-do-chxxx-recursive',
612;; `diredp-do-create-files-recursive', `diredp-do-grep-1',
613;; `diredp-ensure-bookmark+', `diredp-ensure-mode',
614;; `diredp-existing-dired-buffer-p', `diredp-fewer-than-2-files-p',
615;; `diredp-fileset-1', `diredp-find-a-file-read-args',
616;; `diredp-file-for-compilation-hit-at-point' (Emacs 24+),
617;; `diredp-files-within', `diredp-files-within-1',
618;; `diredp-fit-frame-unless-buffer-narrowed' (Emacs 24.4+),
619;; `diredp-get-confirmation-recursive', `diredp-get-files',
620;; `diredp-get-files-for-dir', `diredp-get-subdirs',
621;; `diredp-hide-details-if-dired' (Emacs 24.4+),
622;; `diredp-hide/show-details' (Emacs 24.4+),
623;; `diredp-highlight-autofiles', `diredp-image-dired-required-msg',
624;; `diredp-get-image-filename', `diredp-internal-do-deletions',
625;; `diredp-list-files', `diredp-looking-at-p',
626;; `diredp-make-find-file-keys-reuse-dirs',
627;; `diredp-make-find-file-keys-not-reuse-dirs', `diredp-maplist',
628;; `diredp-marked-here', `diredp-mark-files-tagged-all/none',
629;; `diredp-mark-files-tagged-some/not-all',
630;; `diredp-nonempty-region-p', `diredp-parent-dir',
631;; `diredp-paste-add-tags', `diredp-paste-replace-tags',
632;; `diredp-read-bookmark-file-args', `diredp-read-include/exclude',
633;; `diredp-read-regexp', `diredp-recent-dirs',
634;; `diredp-refontify-buffer', `diredp-remove-if',
635;; `diredp-remove-if-not', `diredp--reuse-dir-buffer-helper',
636;; `diredp-root-directory-p', `diredp-set-header-line-breadcrumbs'
637;; (Emacs 22+), `diredp-set-tag-value', `diredp-set-union',
638;; `diredp--set-up-font-locking', `diredp-string-match-p',
639;; `diredp-tag', `diredp-this-file-marked-p',
640;; `diredp-this-file-unmarked-p', `diredp-this-subdir',
641;; `diredp-untag', `diredp-visit-ignore-regexp',
642;; `diredp-y-or-n-files-p'.
643;;
644;; Variables defined here:
645;;
646;; `diredp-bookmark-menu', `diredp-file-line-overlay',
647;; `diredp-files-within-dirs-done', `diredp-font-lock-keywords-1',
648;; `diredp-hide-details-last-state' (Emacs 24.4+),
649;; `diredp-hide-details-toggled' (Emacs 24.4+),
650;; `diredp-hide/show-menu', `diredp-images-recursive-menu',
651;; `diredp-last-copied-filenames', `diredp-list-files-map',
652;; `diredp-loaded-p', `diredp-marks-recursive-menu',
653;; `diredp-menu-bar-dir-menu', `diredp-menu-bar-marks-menu',
654;; `diredp-menu-bar-multiple-menu', `diredp-menu-bar-regexp-menu',
655;; `diredp-menu-bar-single-menu', `diredp-multiple-bookmarks-menu',
656;; `diredp-multiple-delete-menu', `diredp-multiple-dired-menu',
657;; `diredp-multiple-images-menu',
658;; `diredp-multiple-encryption-menu',
659;; `diredp-multiple-move-copy-link-menu',
660;; `diredp-multiple-omit-menu', `diredp-multiple-recursive-menu',
661;; `diredp-multiple-rename-menu', `diredp-multiple-search-menu',
662;; `diredp-navigate-menu', `diredp-regexp-recursive-menu',
663;; `diredp-re-no-dot', `diredp-single-bookmarks-menu',
664;; `diredp-single-encryption-menu', `diredp-single-image-menu',
665;; `diredp-single-move-copy-link-menu', `diredp-single-open-menu',
666;; `diredp-single-rename-menu', `diredp-w32-drives-mode-map'.
667;;
668;; Macros defined here:
669;;
670;; `diredp-mark-if', `diredp-user-error',
671;; `diredp-with-help-window'.
672;;
673;;
674;; ***** NOTE: The following macros defined in `dired.el' have
675;; been REDEFINED HERE:
676;;
677;; `dired-map-over-marks' - Treat multiple `C-u' specially.
678;;
679;;
680;; ***** NOTE: The following functions defined in `dired.el' have
681;; been REDEFINED or ADVISED HERE:
682;;
683;; `dired' - Handle non-positive prefix arg.
684;; `dired-do-delete' - Display message to warn that marked,
685;; not flagged, files will be deleted.
686;; `dired-do-flagged-delete' - Display message to warn that flagged,
687;; not marked, files will be deleted.
688;; `dired-dwim-target-directory' - Uses `diredp-dwim-any-frame-flag'.
689;; `dired-find-file' - Allow `.' and `..' (Emacs 20 only).
690;; `dired-get-filename' - Test `./' and `../' (like `.', `..').
691;; `dired-get-marked-files' - Can include `.' and `..'.
692;; Allow FILTER + DISTINGUISH-ONE-MARKED.
693;; `dired-goto-file' - Fix Emacs bug #7126.
694;; Remove `/' from dir before compare.
695;; (Emacs < 24 only.)
696;; `dired-hide-details-mode' - Respect new user options:
697;; * `diredp-hide-details-initially-flag'
698;; * `diredp-hide-details-propagate-flag'
699;; (Emacs 24.4+)
700;; `dired-insert-directory' - Compute WILDCARD arg for
701;; `insert-directory' for individual file
702;; (don't just use nil). (Emacs 23+, and
703;; only for MS Windows)
704;; `dired-insert-set-properties' - `mouse-face' on whole line.
705;; `dired-flag-auto-save-files', `dired-mark-directories',
706;; `dired-mark-executables', `dired-mark-files-containing-regexp',
707;; `dired-mark-files-regexp', `dired-mark-symlinks'
708;; - Use `diredp-mark-if', not `dired-mark-if'.
709;; `dired-mark-files-regexp' - Add regexp to `regexp-search-ring'.
710;; More matching possibilities.
711;; Added optional arg LOCALP.
712;; `dired-mark-pop-up' - Delete the window or frame popped up,
713;; afterward, and bury its buffer. Do not
714;; show a menu bar for pop-up frame.
715;; `dired-other-frame' - Handle non-positive prefix arg.
716;; `dired-other-window' - Handle non-positive prefix arg.
717;; `dired-pop-to-buffer' - Put window point at bob (bug #12281).
718;; (Emacs 22-24.1)
719;; `dired-read-dir-and-switches' - Non-positive prefix arg behavior.
720;;
721;;; NOT YET:
722;;; ;; `dired-readin-insert' - Use t as WILDCARD arg to
723;;; ;; `dired-insert-directory'. (Emacs 23+,
724;;; ;; and only for MS Windows)
725;;
726;; `dired-revert' - Reset `mode-line-process' to nil.
727;; `dired-switches-escape-p' - Made compatible with Emacs 20, 21.
728;;
729;;
730;; ***** NOTE: The following functions are included here with little
731;; or no change to their definitions. They are here to
732;; take advantage of the new definition of macro
733;; `dired-map-over-marks':
734;;
735;; `dired-do-redisplay', `dired-map-over-marks-check',
736;; `image-dired-dired-insert-marked-thumbs',
737;; `image-dired-dired-toggle-marked-thumbs'.
738;;
739;;
740;; ***** NOTE: The following functions defined in `dired-aux.el' have
741;; been REDEFINED HERE:
742;;
743;; `dired-do-byte-compile', `dired-do-compress', `dired-do-load' -
744;; Redisplay only if at most one file is being treated.
745;; `dired-do-isearch', `dired-do-isearch-regexp',
746;; `dired-do-query-replace-regexp', `dired-do-search' -
747;; Use new `dired-get-marked-files'.
748;; `dired-insert-subdir-newpos' - If not a descendent, put at eob.
749;; `dired-insert-subdir-validate' - Do nothing: no restrictions.
750;; `dired-maybe-insert-subdir' - Go back to subdir line if in listing.
751;;
752;;
753;; ***** NOTE: The following functions defined in `dired-x.el' have
754;; been REDEFINED HERE:
755;;
756;; `dired-copy-filename-as-kill' -
757;; Put file names also in var `diredp-last-copied-filenames'.
758;; `dired-do-find-marked-files' -
759;; Call `dired-get-marked-files' with original ARG.
760;; Added optional arg INTERACTIVEP - no error if nil and no files.
761;; `dired-do-run-mail' - Require confirmation.
762;; `dired-mark-sexp' - 1. Variable `s' -> `blks'.
763;; 2. Fixes to `uid' and `gid'.
764;; `dired-mark-unmarked-files' (Emacs < 24 only) - Emacs 24+ version.
765;; `dired-simultaneous-find-file' -
766;; Use separate frames instead of windows if `pop-up-frames' is
767;; non-nil, or if prefix arg < 0.
768;;
769;;
770;; ***** NOTE: (Emacs 20 only) The following variable defined in
771;; `dired.el' has been REDEFINED HERE:
772;;
773;; `dired-move-to-filename-regexp' - Recognize file size in k etc.
774;;
775;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
776;;
777;;; Change Log:
778;;
779;; 2018/06/30 dadams
780;; Added: diredp-delete-if-not.
781;; 2018/06/16 dadams
782;; Added: diredp-visit-ignore-extensions, diredp-visit-ignore-regexps, diredp-visit-next-file,
783;; diredp-visit-previous-file, diredp-visit-this-file, diredp-visit-ignore-regexp.
784;; Bind the commands to C-down, C-up, e.
785;; 2018/03/25 dadams
786;; Added: diredp-user-error.
787;; Updated for Emacs 27-pretest-2 change in dired-get-marked-files signature.
788;; dired-get-marked-files: Added optional arg ERROR-IF-NONE-P.
789;; diredp-list-marked, diredp-insert-subdirs, dired-do-(i)search(-regexp), dired-do-query-replace-regexp,
790;; dired-do-find-marked-files, diredp-describe-marked-autofiles:
791;; Added optional arg INTERACTIVEP.
792;; Pass non-nil ERROR-IF-NONE-P to dired-get-marked-files when INTERACTIVEP. (See Emacs bug #30938.)
793;; 2018/03/23 dadams
794;; Added diredp-mark-if. Removed: redefinition of dired-mark-if.
795;; Differences: msg and return value include both number of matches and number of changes.
796;; Added redefinitions (use diredp-mark-if) of dired-flag-auto-save-files,
797;; dired-mark-(files-containing-regexp|symlinks|directories|executables).
798;; Everywhere: Use diredp-mark-if, not dired-mark-if.
799;; 2018/03/03 dadams
800;; diredp-delete-dups: defalias the symbol, not its symbol-function (dunno why I did the latter).
801;; 2018/02/28 dadams
802;; Added: diredp-last-copied-filenames, diredp-copy-abs-filenames-as-kill-recursive,
803;; and redefinition of vanilla diredp-last-copied-filenames.
804;; diredp-copy-abs-filenames-as-kill: Use diredp-ensure-mode in interactive spec.
805;; diredp-copy-filename-as-kill-recursive: Update diredp-last-copied-filenames with filenames string.
806;; diredp-yank-files: Require confirmation for pasting, using diredp-y-or-n-files-p.
807;; Get file names from variable diredp-last-copied-filenames, not kill-ring.
808;; Added NO-CONFIRM-P arg.
809;; diredp-ensure-mode: Added doc string.
810;; diredp-do-grep, diredp-do-grep-recursive: Changed bindings to C-M-G and M-+ C-M-G, due to M-g conflict.
811;; 2018/02/27 dadams
812;; Added: diredp-copy-abs-filenames-as-kill, diredp-yank-files (aka diredp-paste-files) (bound to C-y).
813;; diredp-menu-bar-multiple-menu: Added diredp-copy-abs-filenames-as-kill.
814;; diredp-menu-bar-dir-menu: Added diredp-yank-files.
815;; 2018/01/11 dadams
816;; diredp-get-files:
817;; Set IGNORE-MARKS-P to non-nil if nothing marked here. (It was not getting all if nothing marked.)
818;; diredp-marked-recursive(-other-window):
819;; Corrected interactive spec, which was missing nil DIRNAME arg. Corrected body: use DIRNAME.
820;; diredp-get-files-for-dir, diredp-do-bookmark-dirs-recursive, diredp-change-marks-recursive,
821;; diredp-unmark-all-files-recursive, diredp-mark-files-regexp-recursive, diredp-mark-recursive-1,
822;; diredp-do-delete-recursive:
823;; Factor out (dired-buffers-for-dir (expand-file-name directory)).
824;; 2018/01/03 dadams
825;; dired-mark-files-regexp: Corrected doc string wrt prefix args. Thx to John Mastro.
826;; diredp-do-grep-recursive: Removed unused optional arg IGNORE-MARKS-P.
827;; diredp-marked-recursive(-other-window): Moved handling of optional arg from interactive spec to body.
828;; 2018/01/02 dadams
829;; Added: diredp-flag-auto-save-files-recursive. Bound to M-+ #.
830;; diredp-get-file-or-dir-name, diredp-marked-here: Doubled backslashes to escape dots.
831;; diredp-marked-here: Fixed regexp to match only double-dot, not single-dot.
832;; diredp-flag-auto-save-files-recursive: Updated to include more M-+ keys.
833;; diredp-marks-recursive-menu: Added diredp-flag-auto-save-files-recursive.
834;; 2017/12/31 dadams
835;; diredp-get-files-for-dir: Pass non-nil NO-DOT-DOT-P arg to diredp-marked-here.
836;; dired-get-marked-files: Allow use of FILTER and DISTINGUISH-ONE-MARKED together.
837;; diredp-marked-here: Added optional arg NO-DOT-DOT-P.
838;; diredp-change-marks-recursive, diredp-unmark-all-files-recursive: Removed unused vars include-dirs, files.
839;; 2017/12/30 dadams
840;; Added: diredp-change-marks-recursive, diredp-unmark-all-files-recursive, diredp-unmark-all-marks-recursive.
841;; Bound to M-+ * c, M-+ M-DEL, M-+ U, respectively.
842;; diredp-menu-bar-marks-menu: Rename item Change Marks to Change Mark.
843;; diredp-marks-recursive-menu, diredp-multiple-recursive-menu:
844;; Added diredp-change-marks-recursive, diredp-unmark-all-(files|marks)-recursive.
845;; 2017/12/21 dadams
846;; Added: diredp-mark-recursive-1. Forgot to add it last June.
847;; 2017/12/17 dadams
848;; Removed: diredp-display-graphic-p.
849;; Do not use diredp-display-graphic-p to allow binding diredp-bind-problematic-terminal-keys by default.
850;; 2017/11/25 dadams
851;; diredp-nb-marked-in-mode-name: Wrap last :eval sexp in save-excursion.
852;; Protect Call dired-current-directory only when dired-subdir-alist.
853;; 2017/10/23 dadams
854;; Added: diredp-count-.-and-..-flag, diredp--reuse-dir-buffer-helper.
855;; Removed: diredp-mouse-find-file.
856;; diredp-find-file-reuse-dir-buffer, diredp-mouse-find-file-reuse-dir-buffer,
857;; diredp-up-directory-reuse-dir-buffer:
858;; Use diredp--reuse-dir-buffer-helper.
859;; diredp-find-file-reuse-dir-buffer: Changed logic: do find-alternate-file only if target is a dir not in
860;; Dired and current Dired buffer is in only this window.
861;; diredp-mouse-find-file-reuse-dir-buffer: Added optional args FIND-FILE-FUNC and FIND-DIR-FUNC.
862;; diredp-up-directory, diredp-up-directory-reuse-dir-buffer: Pass OTHER-WINDOW arg to diredp-w32-drives.
863;; diredp-nb-marked-in-mode-name: Show also number of lines in current listing, and listing-relative lineno,
864;; respecting diredp-count-.-and-..-flag.
865;; diredp-find-a-file*: Added autoload cookies.
866;; 2017/08/18 dadams
867;; Fixed emacswiki URLs everywhere. They changed the locations and changed http to https.
868;; 2017/06/30 dadams
869;; Added: diredp-bind-problematic-terminal-keys, diredp-display-graphic-p.
870;; Guard bindings of problematic keys with diredp-display-graphic-p & diredp-bind-problematic-terminal-keys.
871;; Documented problematic keys for terminal mode in commentary.
872;; 2017/06/23 dadams
873;; Added: diredp-read-regexp (removed alias to read-regexp), diredp-marks-recursive-menu,
874;; diredp-mark-executables-recursive (bound to M-+ * *),
875;; diredp-mark-directories-recursive (bound to M-+ * /),
876;; diredp-mark-extension-recursive (bound to M-+ * .),
877;; diredp-mark-autofiles-recursive (bound to M-+ * B),
878;; diredp-mark-executables-recursive (bound to M-+ * *),
879;; diredp-mark-directories-recursive (bound to M-+ * /),
880;; diredp-mark-symlinks-recursive (bound to M-+ * @),
881;; Bind diredp-mark-autofiles to * B.
882;; diredp-marked-here: Bind dired-marker-char to ?*.
883;; diredp-mark-files-regexp-recursive: Better msgs - show total count.
884;; Everywhere: Use diredp-looking-at, not looking-at. Use diredp-read-regexp, not dired-read-regexp.
885;; 2017/05/30 dadams
886;; Fixed typo: direp--set-up-font-locking -> diredp--set-up-font-locking.
887;; 2017/05/22 dadams
888;; Added: direp--set-up-font-locking.
889;; Use direp--set-up-font-locking instead of lambda in dired-mode-hook.
890;; 2017/04/09 dadams
891;; Version 2017.04.09.
892;; Added: diredp-multiple-move-copy-link-menu, diredp-multiple-rename-menu, diredp-multiple-dired-menu,
893;; diredp-multiple-omit-menu, diredp-multiple-delete-menu, diredp-single-bookmarks-menu,
894;; diredp-single-encryption-menu, diredp-single-image-menu, diredp-single-open-menu,
895;; diredp-single-move-copy-link-menu, diredp-single-rename-menu.
896;; Moved single menu items there.
897;; Renamed: diredp-menu-bar-encryption-menu to diredp-multiple-encryption-menu,
898;; diredp-menu-bar-mark-menu to diredp-menu-bar-marks-menu,
899;; diredp-menu-bar-operate-menu to diredp-menu-bar-multiple-menu,
900;; diredp-menu-bar-operate-bookmarks-menu to diredp-multiple-bookmarks-menu,
901;; diredp-menu-bar-operate-recursive-menu to diredp-multiple-recursive-menu,
902;; diredp-menu-bar-operate-search-menu to diredp-multiple-search-menu,
903;; diredp-menu-bar-images-menu to diredp-multiple-images-menu,
904;; diredp-menu-bar-images-recursive-menu to diredp-images-recursive-menu,
905;; diredp-menu-bar-immediate-menu to diredp-menu-bar-single-menu,
906;; diredp-menu-bar-regexp-recursive-menu to diredp-regexp-recursive-menu,
907;; diredp-menu-bar-subdir-menu to diredp-menu-bar-dir-menu.
908;; Added dired-do-rename to diredp-multiple-rename-menu.
909;; diredp-nonempty-region-p: Ensure (mark) also.
910;; 2017/03/30 dadams
911;; Moved key bindings to end of file. Moved defgroup before defcustoms.
912;; Bind dired-multiple-w32-browser to C-M-RET, diredp-multiple-w32-browser-recursive to M-+ C-M-RET.
913;; 2017/03/29 dadams
914;; Added: diredp-dired-union-other-window, diredp-add-to-dired-buffer-other-window.
915;; diredp-dired-union-1: Added optional arg OTHERWIN.
916;; diredp-dired-plus-description: Updated doc string.
917;; diredp-menu-bar-subdir-menu: Added diredp-dired-for-files.
918;; Bind diredp-w32-drives to :/, diredp-dired-inserted-subdirs to C-M-i.
919;; Bind diredp-add-to-dired-buffer to C-x D A (not C-x E), diredp-dired-union to C-x D U (not C-x D),
920;; diredp-fileset to C-x D S (not C-M-f), diredp-dired-recent-dirs to C-x D R (not C-x R),
921;; diredp-dired-for-files to C-x D F, plus other-window versions.
922;; 2017/03/24 dadams
923;; Added defalias for dired-read-regexp.
924;; diredp-mouse-3-menu: Removed second arg to mouse-save-then-kill.
925;; 2017/02/20 dadams
926;; diredp-(next|previous)-line, diredp-(next|prev)-dirline, diredp-(next|prev)-subdir:
927;; Update interactive spec to use (in effect) ^p for prefix arg (for shift-select-mode).
928;; 2017/01/12 dadams
929;; dired-mark-files-regexp: Swapped prefix-arg behavior for relative and absolute name matching.
930;; 2017/01/01 dadams
931;; dired-mark-files-regexp: Fix to prompt for no prefix arg.
932;; 2016/12/28 dadams
933;; dired-mark-files-regexp: Corrected prompt string for Mark/UNmark. Thx to Tino Calancha.
934;; 2016/11/20 dadams
935;; diredp-menu-bar-operate-search-menu: Added dired-do-find-regexp and dired-do-find-regexp-and-replace.
936;; Bind dired-do-search to M-a and dired-do-query(-replace)-regexp to M-q.
937;; diredp-dired-plus-description: Added dired-do-find-regexp and dired-do-find-regexp-and-replace.
938;; 2016/10/12 dadams
939;; diredp-compressed-extensions: Added extensions .xz and .lzma. Thx to xuhdev (https://www.topbug.net/).
940;; 2016/09/20 dadams
941;; Emacs 25.1: Bind M-z to dired-do-compress-to (replaces c). (Emacs bug #24484.)
942;; diredp-menu-bar-operate-menu: Added item: Compress to (dired-do-compress-to).
943;; 2016/09/15 dadams
944;; Added: diredp-max-frames.
945;; dired-do-find-marked-files: Pass non-nil ARG to dired-get-marked-files only if it is a cons.
946;; Clarified doc string wrt prefix arg.
947;; dired-simultaneous-find-file: Require confirmation if more files than diredp-max-frames.
948;; diredp-do-find-marked-files-recursive: Clarified doc string wrt prefix arg.
949;; Thx to Tino Calancha.
950;; 2016/09/14 dadams
951;; diredp-dired-plus-description: Added entry for dired-hide-details-mode - ( key.
952;; 2016/08/26 dadams
953;; diredp-y-or-n-files-p: pop-to-buffer only when the buffer was created.
954;; Update wrt vanilla (scroll actions).
955;; diredp-do-query-replace-regexp-recursive:
956;; Call diredp-get-confirmation-recursive.
957;; Use only diredp-get-files, not dired-get-marked-files.
958;; Non-positive prefix arg means DELIMITED.
959;; 2016/08/08 dadams
960;; diredp-menu-bar-mark-menu:
961;; Added: dired-mark-files-containing-regexp, dired-mark-sexp, image-dired-mark-tagged-files,
962;; 2016/05/28 dadams
963;; diredp-mark-files-regexp-recursive: Use nil for dired-get-filename LOCALP arg.
964;; dired-mark-files-regexp: Corrected doc string: absolute filename matching by default.
965;; 2016/05/24 dadams
966;; dired-mark-files-regexp: Added optional arg LOCALP, so can mark/unmark matching different file-name forms.
967;; 2016/05/15 dadams
968;; Added: diredp-bookmark-menu, diredp-hide/show-menu, diredp-navigate-menu.
969;; Move insert after revert and rename it to Insert/Move-To This Subdir. Move create-directory before revert.
970;; 2016/04/29 dadams
971;; diredp-next-line: Respect goal-column.
972;; 2016/01/24 dadams
973;; Added: diredp-ensure-bookmark+, diredp-mark-autofiles, diredp-unmark-autofiles,
974;; diredp-mark/unmark-autofiles, diredp-describe-autofile, diredp-show-metadata,
975;; diredp-mouse-describe-autofile, diredp-describe-marked-autofiles, diredp-show-metadata-for-marked
976;; Soft-require help-fns+.el (Emacs 22+) or help+20.el (Emacs 20-21).
977;; Add to menu-bar menus:
978;; diredp-(un)mark-autofiles, diredp-describe-autofile, diredp-describe-marked-autofiles.
979;; diredp-menu-bar-immediate-menu: Add diredp-describe-file only if defined.
980;; Bind diredp-describe-file to keys only if defined.
981;; Use diredp-ensure-bookmark+ everywhere, instead of its definition.
982;; diredp(-mouse)-describe-file: Define only if describe-file is defined. Removed raising error if not.
983;; diredp-mouse-3-menu: Use diredp-describe-autofile if diredp-describe-file is not defined.
984;; diredp-dired-plus-description: Add diredp-mouse-describe-autofile, when bound.
985;; dired-mark-if: Do not count non-changes.
986;; 2015/12/15 dadams
987;; diredp-font-lock-keywords-1: Follow # with optional [/ ], for face diredp-number. Thx to Tino Calancha.
988;; 2015/11/10 dadams
989;; diredp-fileset(-other-window): Separate error msgs for unloaded filesets.el and empty filesets-data.
990;; 2015/10/02 dadams
991;; dired-mark-sexp: Like vanilla, skip extended attributes marker before setting NLINK. Thx to Tino Calancha.
992;; 2015/09/29 dadams
993;; diredp-delete-this-file: Redefined to use delete-file instead of dired-do-delete.
994;; 2015/09/07 dadams
995;; diredp-font-lock-keywords-1: Do not test diredp-ignore-compressed-flag when highlighting file names.
996;; Use separate entries for compressed and non-compressed file names.
997;; Added missing \\| before ignored compressed extensions.
998;; 2015/09/06 dadams
999;; diredp-compressed-extensions: Added .tgz. Removed duplicate .gz.
1000;; diredp-font-lock-keywords-1: Use regexp-opt where possible, instead of mapcar regexp-quote.
1001;; 2015/09/05 dadams
1002;; Added: diredp-compressed-extensions, diredp-ignore-compressed-flag, diredp-compressed-file-name,
1003;; diredp-dir-name.
1004;; diredp-font-lock-keywords-1:
1005;; Allow spaces in symlink names. Highlight compressed-file names, if diredp-ignore-compressed-flag.
1006;; Use diredp-compressed-extensions instead of hardcoding extensions.
1007;; Highlight d with diredp-dir-priv (fix).
1008;; Treat l in third column the same as - and d there.
1009;; Highlight whole line for D-flagged files, with face diredp-deletion-file-name.
1010;; Thx to Nick Helm.
1011;; 2015/08/30 dadams
1012;; dired-mark-sexp: Updated per Emacs 25 code.
1013;; 2015/07/30 dadams
1014;; diredp-fileset(-other-window): Changed key binding from C-x F to C-x C-M-f (conflicted with find-function).
1015;; 2015/06/24 dadams
1016;; Added: diredp-parent-dir, diredp-breadcrumbs-in-header-line-mode, diredp-set-header-line-breadcrumbs.
1017;; 2015/06/06 dadams
1018;; Added dired-other-(frame|window).
1019;; diredp-font-lock-keywords-1:
1020;; Use dired-re-maybe-mark and dired-re-inode-size for permission matchings and directory names.
1021;; dired(-other-(frame|window)) advice:
1022;; Add interactive spec, to handle arg <= 0 (broken by change to dired-read-dir-and-switches 2015/02/02).
1023;; diredp-dired-for-files: Typo: pass empy string.
1024;; 2015/06/05 dadams
1025;; Added: diredp-grepped-files-other-window as alias for diredp-compilation-files-other-window.
1026;; diredp-compilation-files-other-window: Added SWITCHES optional arg (prefix arg).
1027;; 2015/06/04 dadams
1028;; diredp-dired-for-files(-other-window):
1029;; Updated to fit change to dired-read-dir-and-switches made 2015/02/02: addition of READ-EXTRA-FILES-P.
1030;; Use prefix arg to prompt for switches.
1031;; 2015/05/31 dadams
1032;; Added: diredp-image-show-this-file,diredp-image-show-this-file-use-frame-flag, diredp-get-image-filename.
1033;; image-dired-dired-toggle-marked-thumbs, diredp-menu-bar-immediate-menu [image]:
1034;; Use diredp-get-image-filename.
1035;; Bound diredp-image-show-this-file to C-t I.
1036;; diredp-menu-bar-immediate-image-menu: Added diredp-image-show-this-file and dired-find-file.
1037;; Added autoload cookies for image commands.
1038;; 2015/04/16 dadams
1039;; Added: diredp-do-apply-function, diredp-do-apply-function-recursive. Added to menus. Bind to @, M-+ @.
1040;; dired-do-query-replace-regexp: Handle nil ARG properly.
1041;; 2015/03/26 dadams
1042;; Added: redefinitions of dired-do-isearch, dired-do-isearch-regexp, dired-do-query-replace-regexp,
1043;; dired-do-search, to handle multi-C-u.
1044;; Added: dired-nondirectory-p (Emacs 20), diredp-refontify-buffer.
1045;; dired-do-byte-compile, dired-do-load, : Corrected interactive spec, to treat more than two C-u as two.
1046;; dired-after-readin-hook: Add diredp-refontify-buffer. In particular, this ensures that reverting Dired
1047;; for a listing of explicit file names gets refontified. (Just turn-on-font-lock does not refontify.)
1048;; 2015/03/24 dadams
1049;; Added: diredp-compilation-files-other-window, diredp-file-for-compilation-hit-at-point.
1050;; 2015/03/06 dadams
1051;; Renamed: diredp-menu-bar-recursive-marked-menu to diredp-menu-bar-operate-recursive-menu.
1052;; Added: diredp-do-delete-recursive: M-+ D. Added to diredp-menu-bar-operate-recursive-menu.
1053;; Added: diredp-mark-files-regexp-recursive: M-+ % m. Added to diredp-menu-bar-regexp-recursive-menu.
1054;; 2015/03/04 dadams
1055;; Added: diredp-dwim-any-frame-flag, (redefinition of) dired-dwim-target-directory.
1056;; 2015/02/22 dadams
1057;; diredp-bookmark: Corrected for use without Bookmark+ - bookmark-store signature.
1058;; Pass correct value to bmkp-autofile-set for its MSG-P arg.
1059;; diredp-mouse-do-bookmark: Do not pass non-nil NO-MSG-P arg to diredp-bookmark.
1060;; 2015/02/03 dadams
1061;; Added: diredp-add-to-this-dired-buffer.
1062;; Removed: diredp-add-to-dired-buffer-other-window, diredp-dired-union-other-window.
1063;; diredp-dired-union-1: Removed optional arg OTHER-WINDOW-P.
1064;; diredp-menu-bar-subdir-menu: Added diredp-add-to-this-dired-buffer.
1065;; dired-read-dir-and-switches, diredp-dired-union-interactive-spec:
1066;; Added optional arg DIRED-BUFFER. If nil, use current buffer name as default when reading buffer name.
1067;; 2015/02/02 dadams
1068;; Added: diredp-add-to-dired-buffer, diredp-add-to-dired-buffer-other-window, diredp-set-union,
1069;; diredp-existing-dired-buffer-p.
1070;; Bind diredp-add-to-dired-buffer(-other-window) globally to C-x E, C-x 4 E.
1071;; diredp-dired-union(-other-window):
1072;; Added args DIRNAME and EXTRA. Pass them to diredp-dired-union-1. Moved "UNION" to *-interactive-spec.
1073;; Pass values for new args NO-DIRED-BUFS and READ-EXTRA-FILES-P to diredp-dired-union-interactive-spec.
1074;; diredp-dired-union-interactive-spec:
1075;; Added args NO-DIRED-BUFS and READ-EXTRA-FILES-P. Use (updated) dired-read-dir-and-switches.
1076;; Delete dead buffers from dired-buffers. Remove DIRNAME buffer as candidate.
1077;; Apply expand-file-name to default-directory. Return list of DIRNAME BUFS SWITCHES EXTRA-FILES.
1078;; diredp-dired-union-1:
1079;; Added args DIRED-NAME and EXTRA.
1080;; For existing Dired buffer whose dired-directory is a cons:
1081;; Include its current listing. Replace buffer with new one of same name, after deleting its window.
1082;; dired-read-dir-and-switches:
1083;; Added arg READ-EXTRA-FILES-P.
1084;; If chosen Dired buffer exists and is an ordinary listing then start out with its directory-files.
1085;; diredp-dired-union, diredp-fileset, diredp-dired-recent-dirs: Bind globally, not just in Dired mode.
1086;; 2015/01/30 dadams
1087;; dired-read-dir-and-switches: Remove any killed buffers from dired-buffers, before using for completion.
1088;; 2014/10/25 dadams
1089;; diredp-dired-union-interactive-spec: Typo: quote buffer-name-history. Pass other-window STRING.
1090;; diredp-dired-union-other-window: Pass other-window STRING.
1091;; dired-read-dir-and-switches: Include STRING for reading buffer name also.
1092;; dired (defadvice): Corrected doc string for prefix arg >= and <= 0.
1093;; 2014/10/15 dadams
1094;; diredp-hide-details-initially-flag:
1095;; Added :set, to ensure that diredp-hide-details-last-state is kept up-to-date.
1096;; 2014/09/28 dadams
1097;; Added: diredp-recent-dirs, diredp-read-include/exclude, diredp-root-directory-p, diredp-remove-if.
1098;; diredp-dired-recent-dirs(-other-window): Added optional ARG. Use diredp-recent-dirs. Pass SWITCHES.
1099;; dired-read-dir-and-switches: Use diredp-root-directory-p.
1100;; Bound diredp-dired-recent-dirs(-other-window) to C-x R and C-x 4 R.
1101;; Added diredp-dired-recent-dirs to Dir menu.
1102;; 2014/09/27 dadams
1103;; Added: diredp-dired-recent-dirs, diredp-dired-recent-dirs-other-window, diredp-delete-dups.
1104;; 2014/09/26 dadams
1105;; diredp-mouseover-help: dired-get-filename etc. has to be inside the save-excursion.
1106;; diredp-image-dired-create-thumb: Added FILE arg. Use numeric prefix arg as the new thumbnail size.
1107;; 2014/09/22 dadams
1108;; diredp-mouse-3-menu: Do not place overlay unless on a file/dir name (i.e., dired-get-filename).
1109;; 2014/09/15 dadams
1110;; dired-read-dir-and-switches: Made it (thus dired too) an Icicles multi-command.
1111;; dired (defadvice): Added doc about using it with Icicles.
1112;; 2014/09/14 dadams
1113;; Added: diredp-kill-this-tree.
1114;; Removed: diredp-dired-files(-other-window), diredp-dired-files-interactive-spec.
1115;; dired-read-dir-and-switches:
1116;; Based on diredp-dired-files-interactive-spec implementation now, but:
1117;; Moved unwind-protect outside call to list. completing-read, not read-string, for DIRBUF.
1118;; Do not allow inclusion of root directories. Protected icicle-sort-comparer with boundp.
1119;; dired-insert-subdir-validate: Make it a no-op.
1120;; dired advice (doc string): Mention wildcards, Icicles.
1121;; diredp-dired-for-files(-other-window):
1122;; Use dired-read-dir-and-switches and dired, not diredp-dired-files-interactive-spec and
1123;; diredp-dired-files.
1124;; diredp-menu-bar-immediate-menu, diredp-mouse-3-menu:
1125;; Added item for diredp-kill-this-tree.
1126;; Corrected visible condition: expand-file-name, so ~/ compares with its expansion.
1127;; diredp-font-lock-keywords-1: Include period (.) for diredp(-compressed)-file-suffix.
1128;; 2014/09/09 dadams
1129;; Added: dired-read-dir-and-switches.
1130;; Advise dired, for doc string.
1131;; dired-get-filename: Hack for Emacs 20-22, to expand ~/...
1132;; 2014/09/07 dadams
1133;; Added: redefinitions of dired-insert-subdir-newpos, dired-insert-subdir-validate.
1134;; 2014/07/26 dadams
1135;; diredp-do-find-marked-files-recursive:
1136;; Only ARG >= 0 ignores marks now. And ARG <= 0 means find but do not display.
1137;; 2014/07/13 dadams
1138;; diredp-mouseover-help: Wrap (goto-char pos) in save-excursion (Emacs bug #18011).
1139;; 2014/07/12 dadams
1140;; Faces diredp(-tagged)-autofile-name: Made paler/darker (less saturated).
1141;; Moved diredp-highlight-autofiles before diredp-highlight-autofiles-mode, so will be
1142;; defined for first revert.
1143;; diredp-mouse-3-menu: Renamed items Tag, Untag to Add Tags, Remove Tags.
1144;; diredp-dired-plus-description: Updated.
1145;; 2014/07/11 dadams
1146;; Added: diredp-highlight-autofiles-mode, diredp-highlight-autofiles,
1147;; diredp-autofile-name, diredp-tagged-autofile-name.
1148;; Soft-require bookmark+.el. Soft-require highlight.el if bookmark+.el is provided.
1149;; diredp-menu-bar-subdir-menu: Added item Toggle Autofile Highlighting.
1150;; Removed unused face: diredp-display-msg.
1151;; 2014/06/29 dadams
1152;; dired-get-marked-files, diredp-internal-do-deletions:
1153;; Remove nils from dired-map-over-marks result.
1154;; 2014/05/28 dadams
1155;; diredp-mode-line-marked: Use DarkViolet for both light and dark background modes.
1156;; 2014/05/23 dadams
1157;; Added: diredp-with-help-window.
1158;; diredp-list-files, diredp-dired-plus-help:
1159;; Use diredp-with-help-window, not with-output-to-temp-buffer. See Emacs bug #17109.
1160;; 2014/05/06 dadams
1161;; Added: diredp-image-dired-required-msg, diredp-list-files-map,
1162;; diredp-find-line-file-other-window, diredp-mouse-find-line-file-other-window,
1163;; image-dired-dired-toggle-marked-thumbs, diredp-list-marked.
1164;; Soft-require image-dired.el and image-file.el.
1165;; diredp-image-dired-create-thumb: Define unconditionally.
1166;; image-dired-dired-insert-marked-thumbs, diredp-image-dired-comment-file,
1167;; diredp-image-dired-tag-file, diredp-image-dired-delete-tag,
1168;; diredp-image-dired-display-thumb, diredp-image-dired-copy-with-exif-name,
1169;; diredp-image-dired-edit-comment-and-tags, diredp-do-display-images:
1170;; Define unconditionally and raise error if no image-(dired|file).el.
1171;; diredp-menu-bar-immediate-image-menu, diredp-menu-bar-images-menu,
1172;; diredp-menu-bar-images-recursive-menu, image-dired-mark-tagged-files:
1173;; Define unconditionally and use :enable.
1174;; diredp-menu-bar-images-menu, diredp-menu-bar-images-recursive-menu:
1175;; Add defalias so can use menu-item with :enable.
1176;; diredp-list-files: Add properties mouse-face, keymap, and help-echo.
1177;; diredp-mouseover-help: Make it work also for diredp-list-files listings.
1178;; image-dired-dired-insert-marked-thumbs: Add autoload cookie.
1179;; dired-get-marked-files: Pass non-nil 2nd arg to dired-get-filename, to include . and .. .
1180;; Bind diredp-list-marked to C-M-l and diredp-list-marked-recursive to M+ C-M-l.
1181;; diredp-insert-subdirs: Exclude . and .., as dired-get-marked-files can now include them.
1182;; diredp-menu-bar-operate-menu: Add diredp-menu-bar-operate-menu to menu.
1183;; diredp-dired-plus-description: Mention diredp-list-marked*.
1184;; 2014/05/03 dadams
1185;; dired-switches-escape-p: Use dired-switches-check if available, based on bug #17218 fix.
1186;; 2014/04/25 dadams
1187;; diredp-image-dired-create-thumb:
1188;; Do not call diredp-image-dired-create-thumb twice: reuse THUMB-NAME.
1189;; 2014/04/24 dadams
1190;; Added: diredp-mouseover-help, diredp-auto-focus-frame-for-thumbnail-tooltip-flag,
1191;; diredp-image-preview-in-tooltip.
1192;; dired-insert-set-properties: Show image-file preview in tooltip.
1193;; diredp-image-dired-create-thumb: Return thumbnail file name or nil.
1194;; 2014/04/23 dadams
1195;; Added: diredp-looking-at-p.
1196;; dired-insert-set-properties: Applied fix for bug #17228.
1197;; 2014/04/05 dadams
1198;; Added: diredp-do-bookmark-dirs-recursive.
1199;; Renamed from bmkp-create-dired-bookmarks-recursive in bookmark+-1.el (removed).
1200;; Bound to M-B (aka M-S-b).
1201;; Added to menus *-subdir-menu, *-operate-bookmarks-menu, *-bookmarks-menu.
1202;; diredp-get-confirmation-recursive: Added optional TYPE arg.
1203;; diredp-insert-subdirs-recursive: Call diredp-get-confirmation-recursive with TYPE arg.
1204;; 2014/02/16 dadams
1205;; dired-pop-to-buffer: Do not redefine for Emacs > 24.1.
1206;; dired-mark-pop-up: Updated doc string.
1207;; 2014/02/13 dadams
1208;; Added: diredp-fileset-other-window, diredp-fileset-1.
1209;; diredp-fileset: Use diredp-fileset-1.
1210;; Bind diredp-dired-union(-other-window) to C-x D, C-x 4 D,
1211;; diredp-fileset(-other-window) to C-x F, C-x 4 F.
1212;; Use diredp-fileset-other-window, not diredp-fileset, in menu.
1213;; 2014/02/03 dadams
1214;; Added: diredp-hide-subdir-nomove.
1215;; Added: dired-goto-file for Emacs 24+ - open hidden parent dir, so can goto destination.
1216;; Replace bindings for dired-hide-subdir with diredp-hide-subdir-nomove.
1217;; Bind dired-hide-subdir to M-$ (not $).
1218;; 2014/02/02 dadams
1219;; dired-goto-file: Redefine only for Emacs < 24.
1220;; 2014/01/15 dadams
1221;; Bind diredp-toggle-find-file-reuse-dir to C-M-R (aka C-M-S-r).
1222;; 2014/01/05 dadams
1223;; Bind dired-omit-mode (aka dired-omit-toggle) to C-x M-o.
1224;; 2013/12/05 dadams
1225;; diredp-do-grep-1: Call grep-default-command with arg, if grep+.el is loaded.
1226;; 2013/11/05 dadams
1227;; Added: diredp-get-subdirs.
1228;; diredp-get-files, diredp-get-files-for-dir, diredp-marked-here: Added optional arg NIL-IF-NONE-P.
1229;; diredp-get-files: Pass INCLUDE-DIRS-P to diredp-files-within.
1230;; 2013/11/04 dadams
1231;; Renamed Bookmarks submenus to Bookmark.
1232;; Added Bookmark Dired Buffer to Dir menu.
1233;; Alias dired-toggle-marks to dired-do-toggle for Emacs 20, instead of backwards for others.
1234;; Use dired-toggle-marks everywhere instead of dired-do-toggle.
1235;; 2013/11/03 dadams
1236;; Created submenus of Multiple menu: Bookmarks, Search.
1237;; Created submenus of Multiple > Marked Here and Below menu:
1238;; Images, Encryption, Search, Bookmarks.
1239;; Reordered menus.
1240;; 2013/09/26 dadams
1241;; diredp-next-line: Use let*, so line-move sees let bindings.
1242;; 2013/08/11 dadams
1243;; diredp-dired-files-interactive-spec:
1244;; Protect icicle-file-sort with boundp. Thx to Vladimir Lomov.
1245;; 2013/08/06 dadams
1246;; diredp-display-image,diredp-menu-bar-immediate-image-menu (:enable's):
1247;; Protect diredp-string-match-p from nil argument.
1248;; 2013/07/24 dadams
1249;; Added: diredp-nonempty-region-p. Use everywhere, in place of its definition.
1250;; 2013/07/21 dadams
1251;; Added: diredp-image-dired-(comment-file|copy-with-exif-name|(create|display)-thumb|
1252;; delete-tag|edit-comment-and-tags|tag-file),
1253;; diredp-string-match-p, diredp-menu-bar-immediate-image-menu.
1254;; Put this-file image commands on new menu diredp-menu-bar-immediate-image-menu.
1255;; diredp-menu-bar-images-menu: Added diredp-do-display-images.
1256;; Use diredp-string-match-p instead of string-match where appropriate.
1257;; diredp-find-a-file-read-args: Removed #' from lambda.
1258;; 2013/07/19 dadams
1259;; Added redefinition of dired-hide-details-mode.
1260;; Added: diredp-hide-details-propagate-flag, diredp-hide-details-initially-flag,
1261;; diredp-hide-details-last-state, diredp-hide-details-toggled,
1262;; diredp-hide-details-if-dired, global-dired-hide-details-mode,
1263;; diredp-fit-frame-unless-buffer-narrowed, diredp-hide/show-details,
1264;; diredp-do-display-images, diredp-display-image.
1265;; On dired-after-readin-hook: diredp-hide/show-details.
1266;; On dired-hide-details-mode-hook: diredp-fit-frame-unless-buffer-narrowed.
1267;; diredp-maplist: Use diredp-maplist, not maplist, in recursive call.
1268;; diredp-next-line: Added bobp test for negative ARG.
1269;; Emacs 20 line-move returns nil, so use (progn ... t).
1270;; Soft-require autofit-frame.el.
1271;; 2013/07/18 dadams
1272;; diredp-next-line: Protect visible-p with fboundp for Emacs 20.
1273;; 2013/07/17 dadams
1274;; Added: diredp-menu-bar-encryption-menu, diredp-menu-bar-images-menu,
1275;; diredp-menu-bar-immediate-encryption-menu,
1276;; diredp-(decrypt|verify|sign|encrypt)-this-file.
1277;; Added diredp-(decrypt|verify|sign|encrypt)-this-file to *-immediate-encryption-menu.
1278;; Moved encryption and image-dired items to the new Multiple submenus from Multiple menu.
1279;; 2013/07/15 dadams
1280;; Added: diredp-async-shell-command-this-file, diredp-do-async-shell-command-recursive.
1281;; Added them to menus. Bind diredp-do-async-shell-command-recursive to M-+ &.
1282;; diredp-menu-bar-mark-menu, diredp-dired-plus-description: Added dired-mark-omitted.
1283;; diredp-menu-bar-subdir-menu: Added dired-omit-mode, dired-hide-details-mode.
1284;; diredp-menu-bar-regexp-menu: Added image-dired-mark-tagged-files.
1285;; diredp-menu-bar-subdir-menu: Added dired-hide-details-mode.
1286;; diredp-shell-command-this-file: Corrected: provide file list to dired-do-shell-command.
1287;; 2013/07/13 dadams
1288;; diredp-font-lock-keywords-1:
1289;; Ensure diredp-dir-priv is not used for directory header of d:/... (Windows drive name).
1290;; dired-insert-directory:
1291;; Update wrt Emacs 24.4: Do dired-insert-set-properties last; use saved CONTENT-POINT.
1292;; dired-insert-set-properties: Updated for Emacs 24.4, for dired-hide-details-mode.
1293;; Add frame-fitting to dired-hide-details-mode-hook.
1294;; dired-mouse-find-file(-other-window): Error msg if click off a file name.
1295;; 2013/07/12 dadams
1296;; Added: diredp-wrap-around-flag, diredp-(next|previous)-(subdir|(dir)line).
1297;; Renamed dired-up-directory to diredp-up-directory.
1298;; Replaced vanilla commands by these new commands everywhere.
1299;; 2013/07/11 dadams
1300;; Added: diredp-up-directory-reuse-dir-buffer.
1301;; diredp-make-find-file-keys(-not)-reuse-dirs: Added diredp-up-directory-reuse-dir-buffer.
1302;; 2013/02/06 dadams
1303;; dired-mark-pop-up: goto point-min, so show start of file list. Thx to Michael Heerdegen.
1304;; 2013/01/28 dadams
1305;; Added redefinition of dired-do-run-mail. Fixes Emacs bug #13561.
1306;; 2012/12/18 dadams
1307;; diredp-ediff: Better default for FILE2. Thx to Michael Heerdegen.
1308;; Require subr-21.el for Emacs 20.
1309;; 2012/11/17 dadams
1310;; Added: derived-mode-p (for Emacs < 22), diredp-ensure-mode.
1311;; Use diredp-ensure-mode everywhere for mode, so compatible with Sunrise Commander etc.
1312;; 2012/11/01 dadams
1313;; Do not require ediff.el. It is required in diredp-ediff itself.
1314;; 2012/10/06 dadams
1315;; Added: minibuffer-with-setup-hook for code byte-compiled using Emacs < 22.
1316;; 2012/09/28 dadams
1317;; Moved dired-*w32* bindings after normal mouse bindings, so they override them.
1318;; 2012/09/05 dadams
1319;; diredp-(rename|copy|(rel)symlink|hardlink)-this-file: Bind use-file-dialog to nil.
1320;; 2012/08/26 dadams
1321;; Set font-lock-defaults to a 3-element list, so it works with font-menus(-da).el.
1322;; 2012/08/25 dadams
1323;; Added: redefinition of dired-pop-to-buffer (fix for bug #12281).
1324;; dired-mark-pop-up: If buffer is shown in a separate frame, do not show menu bar.
1325;; 2012/07/10 dadams
1326;; Removed unneeded substitute-key-definition for (next|previous)-line.
1327;; 2012/07/09 dadams
1328;; Added redefinition of dired-mark-files-regexp: Push REGEXP onto regexp-search-ring.
1329;; 2012/06/21 dadams
1330;; diredp-nb-marked-in-mode-name:
1331;; Add marker numbers regardless of name match.
1332;; Use text property dired+-mode-name to tell whether mode-name was already changed.
1333;; 2012/06/20 dadams
1334;; Added: diredp-nb-marked-in-mode-name, diredp-mode-line-(flagged|marked). Added to hooks.
1335;; Thx to Michael Heerdegen.
1336;; 2012/06/14 dadams
1337;; dired-mark-pop-up: Wrap save-excursion around window/frame deletion.
1338;; dired-do-redisplay: Updated wrt Emacs 23: bind, (then run) dired-after-readin-hook.
1339;; diredp-y-or-n-files-p: Corrected construction of prompt wrt final SPC.
1340;; 2012/06/13 dadams
1341;; dired-buffers-for-dir: Updated wrt Emacs 23:
1342;; If dired-directory is a list then expand FILE in DIR & check whether in cdr of list.
1343;; diredp-get-files-for-dir, diredp-files-within-1, diredp-insert-as-subdir:
1344;; Expand dir name before passing it to dired-buffers-for-dir.
1345;; 2012/06/05 dadams
1346;; MS Windows: Just do not define commands that are inappropriate for Windows (instead of
1347;; defining them to raise an error or making them invisible in menus).
1348;; 2012/06/02 dadams
1349;; Added: diredp-do-(print|encrypt|decrypt|sign|verify)-recursive. Menus. Keys.
1350;; diredp-do-move-recursive: Corrected to use dired-rename-file, not dired-copy-file.
1351;; 2012/05/30 dadams
1352;; diredp-insert-as-subdir: Added optional arg IN-DIRED-NOW-P. Pick up markings & switches
1353;; from sole Dired buffer for CHILD if not in Dired now.
1354;; 2012/05/29 dadams
1355;; Added: diredp-do-(chxxx|chgrp|chown|touch)-recursive, diredp-touch-this-file,
1356;; diredp-menu-bar-(immediate|operate)-bookmarks-menu. Added to menus. Bound to keys.
1357;; Factored bookmark stuff into Bookmark(s) submenus.
1358;; diredp-menu-bar-immediate-menu: Added dired-kill-subdir, [goto-subdir].
1359;; diredp-dired-this-subdir, dired-maybe-insert-subdir: Corrected :visible/enable.
1360;; diredp-dired-inserted-subdirs: Do dired-(remember-marks|mark-rememberd) in this-buff.
1361;; diredp-mouse-3-menu:
1362;; Do not use save-excursion, because some commands move point on purpose. Just return to
1363;; original point unless command intends to MOVEP.
1364;; Added to menu dired-maybe-insert-subdir (two entries), dired-kill-subdir.
1365;; Use *-this-file*, not *-do-*: copy|symlink|shell-command|grep|load (don't use :keys).
1366;; 2012/05/26 dadams
1367;; diredp-dired-inserted-subdirs, diredp-insert-as-subdir:
1368;; Preserve markings and switches in target buffer.
1369;; dired-mark-pop-up: Use unwind-protect. Bury buffer too.
1370;; diredp-do-chmod-recursive: Use only 5 args if < Emacs 23.
1371;; 2012/05/25 dadams
1372;; Added: diredp-insert-as-subdir, diredp-ancestor-dirs, diredp-maplist,
1373;; diredp-do-redisplay-recursive, diredp-do-chmod-recursive.
1374;; Bound diredp-do-chmod-recursive. to M-+ M and added to menu.
1375;; diredp-get-files: Added optional arg DONT-ASKP.
1376;; diredp-y-or-n-files-p: Kill list buffer if it was never shown.
1377;; dired-mark-pop-up: ignore error when delete frame/window.
1378;; 2012/05/22 dadams
1379;; diredp-get-files(-for-dir): Added optional arg INCLUDE-DIRS-P.
1380;; Added: diredp-insert-subdirs(-recursive), diredp(-this)-dired-inserted-subdir(s).
1381;; Added to menus. Bound diredp-insert-subdirs* to (M-+) M-i.
1382;; Bound diredp-capitalize(-recursive) to (M-+) %c.
1383;; Added diredp-dired-union-other-window to Dirs menu.
1384;; Updated diredp-dired-plus-description.
1385;; 2012/05/19 dadams
1386;; Added: diredp-image-dired-*-recursive, diredp-*link-recursive,
1387;; diredp-do-isearch(-regexp)-recursive, diredp-do-query-replace-regexp-recursive,
1388;; diredp-do-search-recursive, diredp-(capitalize|(up|down)case)-recursive,
1389;; diredp-create-files-non-directory-recursive.
1390;; Bound on M-+ prefix key. Added to menus.
1391;; diredp-get-files, diredp-y-or-n-files-p, diredp-list-files, diredp-list-marked-recursive:
1392;; Added optional arg PREDICATE.
1393;; diredp-do-create-files-recursive: Removed MARKER-CHAR arg. Hard-code to keep markings.
1394;; diredp-do-(copy|move)-recursive: Use arg IGNORE-MARKS-P (forgot to use it).
1395;; Removed MARKER-CHAR arg in call to d-d-c-f-r.
1396;; Added missing autoload cookies.
1397;; 2012/05/06 dadsms
1398;; diredp-y-or-n-files-p: Do not kill buffer *Files* - just bury it.
1399;; 2012/05/05 dadams
1400;; Added: diredp-do-bookmark-recursive, diredp-do-bookmark-in-bookmark-file-recursive,
1401;; diredp-set-bookmark-file-bookmark-for-marked-recursive.
1402;; Bound to M-+ M-b, M-+ C-M-B (aka C-M-S-b), M-+ C-M-b, respectively. Added to menus.
1403;; diredp-bookmark: Added optional arg FILE.
1404;; diredp-do-bookmark-in-bookmark-file: Added optional arg FILES.
1405;; diredp-dired-plus-description: Updated.
1406;; diredp-get-confirmation-recursive: Raise error if not in Dired.
1407;; diredp-do-bookmark-recursive, diredp-marked-recursive(-other-window),
1408;; diredp-multiple-w32-browser-recursive:
1409;; Use diredp-get-confirmation-recursive.
1410;; 2012/05/04 dadams
1411;; Added: dired-mark-unmarked-files for Emacs < 24.
1412;; diredp-do-create-files-recursive: Corrected for Emacs < 24.
1413;; diredp-do-create-files-recursive, diredp-(un)mark-files-tagged-regexp,
1414;; diredp(-mouse)-do-(un)tag, diredp(-mouse)-do-remove-all-tags,
1415;; diredp(-mouse)-do-paste-(add|replace)-tags, diredp(-mouse)-do-set-tag-value,
1416;; diredp(-mouse)-do-bookmark(-in-bookmark-file), diredp-find-a-file-read-args,
1417;; diredp-mouse-do-shell-command:
1418;; Use lexical-let(*), to get closures for free vars in lambdas.
1419;; 2012/04/28 dadams
1420;; Added:
1421;; diredp-copy-filename-as-kill-recursive, diredp-do-copy-recursive,
1422;; diredp-do-find-marked-files-recursive, diredp-do-grep-recursive,
1423;; diredp-do-move-recursive, diredp-do-shell-command-recursive,
1424;; diredp-list-marked-recursive, diredp-marked-recursive(-other-window),
1425;; diredp-multiple-w32-browser-recursive, diredp-do-create-files-recursive,
1426;; diredp-get-confirmation-recursive, diredp-list-files, diredp-y-or-n-files-p,
1427;; diredp-menu-bar-recursive-marked-menu.
1428;; diredp-get-files: Use diredp-y-or-n-files-p, not y-or-n-p.
1429;; Commented out dired-readin-insert - see comment.
1430;; Moved bookmark menu items to submenu Bookmarks.
1431;; Added keys (with M-+ prefix) and menu items for new (*-recursive) commands.
1432;; Reordered w32-browser stuff in menus.
1433;; diredp-do-grep: Combined defs for diff Emacs versions - do version test at runtime.
1434;; 2012/04/25 dadams
1435;; dired-insert-directory: Updated per Emacs 24.
1436;; 2012/04/23 dadams
1437;; Added (moved here from Icicles, and renamed prefix):
1438;; diredp-re-no-dot, diredp-get-files, diredp-get-files-for-dir, diredp-files-within,
1439;; diredp-files-within-dirs-done.
1440;; 2012/04/05 dadams
1441;; Added redefinition of dired-mark-pop-up, to fix Emacs bug #7533. If they ever fix it
1442;; then remove this hack.
1443;; 2012/03/13 dadams
1444;; diredp-dired(-for)-files(-other-window):
1445;; Bind: icicle-sort-comparer, icicle-all-candidates-list-alt-action-fn.
1446;; Use icicle-(un)bind-file-candidate-keys.
1447;; diredp-dired-files-interactive-spec: Updated doc strings accordingly.
1448;; 2012/03/07 dadams
1449;; Added: dired-switches-escape-p.
1450;; dired-get-filename: Updated wrt Emacs 24:
1451;; whitespace quoting for bug #10469, filename quoting per Emacs 23.3+,
1452;; MS Windows conversion of \ to / per Emacs 23.3+.
1453;; dired-goto-file: Escape whitespace, per Emacs 24 (for bug #10469).
1454;; 2012/03/02 dadams
1455;; Require cl.el at compile time even for Emacs 22+, for case macro.
1456;; 2012/02/28 dadams
1457;; Do not bother to soft-require mkhtml.el anymore.
1458;; 2012/02/18 dadams
1459;; Swapped keys for dired-w32(-browser|explore), so the former is M-RET, as in Bookmark+.
1460;; 2012/01/10 dadams
1461;; diredp-font-lock-keywords-1: Corrected for date/time when locale is used, not iso.
1462;; 2011/12/19 dadams
1463;; dired-insert-set-properties, dired-mark-sexp, diredp-(un)mark-region-files,
1464;; diredp-flag-region-files-for-deletion, diredp-mouse-3-menu:
1465;; Use line-(beginning|end)-position.
1466;; 2011/12/16 dadams
1467;; diredp-menu-bar-mark-menu: Removed Revert item.
1468;; diredp-menu-bar-subdir-menu: Add image-dired-dired-toggle-marked-thumbs.
1469;; diredp-mouse-3-menu:
1470;; Use commands bound to keys, so the keys show up in the menu. Prefer *-this-file.
1471;; Correct the mark/unmark/flag menu-item visibility. Added Capitalize.
1472;; 2011/12/09 dadams
1473;; diredp-w32-drives: Use dolist, not mapcar.
1474;; diredp-mouse-3-menu: Use easymenu to build the menu. Conditionalize some items.
1475;; Bind down-mouse-3, not mouse-3, to diredp-mouse-3-menu. (bind mouse-3 to ignore).
1476;; Added eval-when-compile for easymenu.el.
1477;; 2011/12//02 dadams
1478;; Added diredp-internal-do-deletions.
1479;; dired(-mouse)-do(-flagged)-delete, : Use diredp-internal-do-deletions, for trash.
1480;; 2011/11/29 dadams
1481;; diredp-read-bookmark-file-args: Corrected use of list of default file names: > Emacs 23.1.
1482;; 2011/10/31 dadams
1483;; dired-mode-hook: Call font-lock-refresh-defaults - see Emacs 24 bugs #6662 and #9919.
1484;; 2011/10/24 dadams
1485;; Protect dired-show-file-type with fboundp.
1486;; 2011/09/03 dadams
1487;; diredp-do-grep-1: Map shell-quote-argument over file names. Thx to Joe Bloggs.
1488;; 2011/08/07 dadams
1489;; diredp-bookmark (need to keep in sync with bmkp-make-record-for-target-file):
1490;; Instead of image-bookmark-make-record, use explicit function that includes file, type.
1491;; 2011/07/25 dadams
1492;; Changed featurep to eval-after-load, for bookmark+-1.el and w32-browser.el.
1493;; 2011/07/01 dadams
1494;; Fixed typo: dired-toggle-find-file-reuse-dir -> ...diredp.... Thx to pasja on Emacs Wiki.
1495;; 2011/06/18 dadams
1496;; Added: diredp-describe-mode, diredp-dired-plus-help(-link), diredp-help-button,
1497;; diredp-dired-plus-description(+links), diredp-send-bug-report.
1498;; Bound diredp-describe-mode to whatever describe-mode is bound to.
1499;; All menus, :enable with mark-active: Added transient-mark-mode and mark != point.
1500;; toggle-diredp-find-file-reuse-dir: Swapped which one is the alias.
1501;; diredp-w32-list-mapped-drives: Display *Shell Command Output* at end.
1502;; diredp-mouse-(describe-file|3-menu|mark/unmark|(find|view)-file(-other-window)):
1503;; save-excursion set-buffer -> with-current-buffer.
1504;; 2011/06/08 dadams
1505;; Added: diredp-dired-for-files(-other-window).
1506;; 2011/06/07 dadams
1507;; Bound dired-show-file-type to _, since y is diredp-relsymlink-this-file.
1508;; 2011/04/25 dadams
1509;; Added (from files+.el): dired(-mouse)-describe-file. Bound to C-h (C-)RET, added to menus.
1510;; 2011/04/23 dadams
1511;; Added, bound (T c, T M-w, T 0, T v, T p, T C-y, T q), and added to menus:
1512;; diredp-copy-tags-this-file, diredp-mouse-copy-tags,
1513;; diredp(-mouse)(-do)-remove-all-tags(-this-file),
1514;; diredp(-mouse)(-do)-set-tag-value(-this-file),
1515;; diredp(-mouse)(-do)-paste-(add|replace)-tags(-this-file).
1516;; diredp-mark-files-tagged-(all/none|some/not-all): Bound free var presentp.
1517;; dired-map-over-marks: Corrected: Bind NEWARG and use that, not ARG.
1518;; dired-get-marked-files: let* -> let.
1519;; dired-do-redisplay, diredp-mouse-diff: when/if -> and.
1520;; dired-readin-insert, dired-get-filename: if -> unless/when.
1521;; diredp-mouse-find-file-reuse-dir-buffer: with-current-buffer, not save...
1522;; diredp-mouse-mark/unmark: Removed unused bol/eol vars.
1523;; 2011/04/19 dadams
1524;; Added: diredp-(un)mark-files-tagged-((not-)all|none|some|regexp|all/none|some/not-all),
1525;; dired-mark-if. Added Tagged submenu for Mark menu.
1526;; Put tags commands on prefix key T, as in Bookmark+. Removed C-(M-)+/- tags-cmd bindings.
1527;; diredp-untag-this-file: Added prefix-arg behavior.
1528;; 2011/04/18 dadams
1529;; Added: diredp-prompt-for-bookmark-prefix-flag.
1530;; Use it in diredp(-mouse)-do-(un)tag, diredp-read-bookmark-file-args,
1531;; diredp(-mouse)-do-bookmark, diredp-(bookmark|(un)tag)-this-file.
1532;; diredp-(bookmark|(un)tag)-this-file, diredp(-do)-bookmark, diredp-(un)tag,
1533;; diredp-do-bookmark-in-bookmark-file, diredp-set-bookmark-file-bookmark-for-marked:
1534;; Made PREFIX arg optional.
1535;; 2011/04/17 dadams
1536;; Added: diredp-(bookmark|(un)tag)-this-file, diredp(-mouse)(-do)-(un)tag.
1537;; diredp-mouse-3-menu: Added: diredp-mouse-do-(un)tag.
1538;; diredp-menu-bar-immediate-menu: Added diredp-(un)tag-this-file, diredp-bookmark-this-file.
1539;; diredp-menu-bar-operate-menu: Added diredp-do-(un)tag.
1540;; Bound diredp-do-tag to C-+, diredp-tag-this-file to C-M-+, diredp-do-untag to C--,
1541;; diredp-untag-this-file to C-M--, diredp-bookmark-this-file to C-B.
1542;; diredp-bookmark: Use bmkp-autofile-set, not bmkp-file-target-set, so get autofile.
1543;; diredp-read-bookmark-file-args, diredp(-mouse)-do-bookmark:
1544;; Default for prefix is now an empty string, not the directory.
1545;; diredp-mouse-do-bookmark: Removed optional second arg.
1546;; Corrected typo: direp-read-bookmark-file-args -> diredp-read-bookmark-file-args.
1547;; 2011/03/25 dadams
1548;; diredp-bookmark: Fixed typo: bmkp-file-indirect-set -> bmkp-file-target-set.
1549;; 2011/02/11 dadams
1550;; diredp-deletion, diredp-deletion-file-name, diredp-executable-tag:
1551;; Made default the same for dark background as for light.
1552;; diredp-ignored-file-name: Made default a bit darker for dark background.
1553;; 2011/02/03 dadams
1554;; All deffaces: Provided default values for dark-background screens too.
1555;; 2011/01/12 dadams
1556;; dired-do-flagged-delete: Removed sit-for added on 1/02.
1557;; 2011/01/04 dadams
1558;; defsubst -> defun everywhere.
1559;; Removed autoload cookies from non def* sexps, defvar, and non-interactive functions.
1560;; Added some missing autoload cookies for defcustom and commands.
1561;; 2011/01/02 dadams
1562;; Added: diredp-this-file-(un)marked-p, diredp-toggle-marks-in-region.
1563;; diredp-(un)mark-region-files, diredp-flag-region-files-for-deletion:
1564;; Act only on marked/unmarked files (opposite). Fix 2nd arg to dired-mark-if.
1565;; diredp-mouse-3-menu:
1566;; If region is active and mouse3.el was loaded, then use its popup.
1567;; Fix Toggle Marked/Unmarked:
1568;; Use diredp-toggle-marks-in-region, so widen, show details and use bol/eol.
1569;; dired-do-flagged-delete: Added sit-for.
1570;; 2010/11/28 dadams
1571;; diredp-mouse-3-menu: Added Toggle Marked/Unmarked for region menu.
1572;; 2010/10/20 dadams
1573;; Moved Emacs 20 tweak to recognize k in file sizes to var dired-move-to-filename-regexp.
1574;; Added diredp-loaded-p.
1575;; 2010/10/19 dadams
1576;; diredp-font-lock-keywords-1:
1577;; Handle decimal pt in file size. Thx to Michael Heerdegen.
1578;; Enable Emacs 20/21 to handle -h option (decimal point size).
1579;; Renamed: face diredp-inode+size to diredp-number.
1580;; 2010/10/01 dadams
1581;; dired-goto-file: Avoid infloop from looking for dir line. Thx to not-use.dilines.net.
1582;; 2010/09/29 dadams
1583;; Added: diredp-dired-union(-1|-other-window|-interactive-spec).
1584;; dired-goto-file: fix for Emacs bug #7126.
1585;; 2010/09/27 dadams
1586;; Renamed diredp-dired-interactive-spec to diredp-dired-files-interactive-spec.
1587;; diredp-dired-files-interactive-spec: Respect file-list arg: kill existing Dired buffer.
1588;; Fix use of prefix arg for switches.
1589;; 2010/09/26 dadams
1590;; Added: dired-insert-directory: Compute WILDCARD arg for individual files.
1591;; Added: dired-readin-insert: Use t as WILDCARD arg to dired-insert-directory.
1592;; Added: diredp-dired-files(-other-window), diredp-dired-interactive-spec.
1593;; 2010/08/27 dadams
1594;; Use diredp-font-lock-keywords-1 properly as a second level of fontification.
1595;; Added: diredp-w32-drives(-mode(-map)), dired-up-directory.
1596;; 2010/08/07 dadams
1597;; dired-map-over-marks: Removed loop that used dired-between-files.
1598;; diredp-get-file-or-dir-name: test against subdir/..? also.
1599;; dired-do-find-marked-files: Pass original ARG to dired-get-marked-files.
1600;; 2010/08/05 dadams
1601;; diredp-bookmark:
1602;; Handle image files (and sound files, if Bookmark+ is used).
1603;; Use bmkp-file-indirect-set if available.
1604;; Use error-message-string to get failure msg.
1605;; 2010/07/11 dadams
1606;; Added: diredp-set-bookmark-file-bookmark-for-marked (C-M-b), diredp-mouse-do-bookmark,
1607;; diredp-do-bookmark-in-bookmark-file (C-M-B, aka C-M-S-b), diredp-read-bookmark-file-args.
1608;; Added them to the operate menu. Added diredp-do-bookmark to mouse-3 menu.
1609;; 2010/07/07 dadams
1610;; dired-do-*: Updated doc strings for prefix arg treatment from dired-map-over-marks-check.
1611;; Added missing autoload cookies.
1612;; 2010/05/29 dadams
1613;; diredp-bookmark: Use relative file name in bookmark name.
1614;; Removed defvar of directory-listing-before-filename-regexp.
1615;; 2010/05/28 dadams
1616;; Changed menu item for dired-create-directory to New Directory. Moved it before Up Dir.
1617;; 2010/03/19 dadams
1618;; diredp-font-lock-keywords-1: Handle date+time wrt regexp changes for Emacs 23.2.
1619;; 2010/01/31 dadams
1620;; diredp-bookmark:
1621;; Don't use bookmark-set or find-file-noselect - inline the needed bookmark-store code.
1622;; Call bookmark-maybe-load-default-file. Use rudimentary bookmark-make-record-function.
1623;; 2010/01/21 dadams
1624;; Renamed:
1625;; diredp-subst-find-alternate-for-find to diredp-make-find-file-keys-reuse-dirs
1626;; diredp-subst-find-for-find-alternate to diredp-make-find-file-keys-not-reuse-dirs.
1627;; diredp-make-find-file-keys(-not)-reuse-dirs: Handle also dired(-mouse)-w32-browser.
1628;; 2010/01/10 dadams
1629;; Added: face diredp-inode+size. Use in diredp-font-lock-keywords-1.
1630;; diredp-font-lock-keywords-1: Allow decimal point in file size. Thx to Regis.
1631;; 2010/01/05 dadams
1632;; dired-insert-set-properties:
1633;; Add text property dired-filename to the file name (for Emacs 23).
1634;; 2009/10/23 dadams
1635;; diredp-font-lock-keywords-1: Override `l' and `t' matches in headings with default face.
1636;; 2009/10/13 dadams
1637;; Added: diredp(-do)-bookmark. Added to Multiple menu, and bound to M-b.
1638;; 2009/10/11 dadams
1639;; diredp-menu-bar-immediate-menu:
1640;; Added items: image display items, dired-maybe-insert-subdir.
1641;; Test dired-do-relsymlink, not diredp-relsymlink-this-file.
1642;; diredp-menu-bar-operate-menu:
1643;; Added items: epa encryption items, image items, isearch items.
1644;; diredp-menu-bar-subdir-menu:
1645;; Added items: revert, isearch file names, dired-compare-directories.
1646;; Removed macro menu-item-any-version - use menu-item everywhere (works for Emacs 20+).
1647;; Added wdired-change-to-wdired-mode to subdir menu even for Emacs 20, if defined.
1648;; 2009/07/09 dadams
1649;; dired-goto-file: Make sure we have a string before calling directory-file-name.
1650;; 2009/05/08 dadams
1651;; dired-find-file (Emacs 20): Raise error if dired-get-filename returns nil.
1652;; 2009/04/26 dadams
1653;; dired-insert-set-properties, diredp-(un)mark-region-files,
1654;; diredp-flag-region-files-for-deletion, diredp-mouse-3-menu, diredp-mouse-mark/unmark:
1655;; Bind inhibit-field-text-motion to t, to ensure real eol.
1656;; 2008/12/17 dadams
1657;; diredp-font-lock-keywords-1: Don't do diredp-deletion, diredp-flag-mark for empty lines.
1658;; 2008/09/22 dadams
1659;; Added: diredp-fileset, diredp-get-file-or-dir-name, and redefinitions of
1660;; dired-map-over-marks, dired-find-file, and dired-mouse-find-file-other-window.
1661;; Added vanilla code to pick up macro dired-map-over-marks:
1662;; dired-get-marked-files, dired-do-delete, dired-map-over-marks-check,
1663;; dired-do-redisplay, image-dired-dired-insert-marked-thumbs.
1664;; diredp-find-file-other-frame, diredp-mouse-(find|view)-file:
1665;; Added nil t args to dired-get-filename calls.
1666;; diredp-do-grep(-1): Use new dired-get-marked-files instead of ad-hoc treatment of C-u.
1667;; 2008/09/21 dadams
1668;; diredp-marked(-other-window): Don't treat zero prefix arg as numerical (no empty Dired).
1669;; Added dired-find-file redefinition for Emacs 20.
1670;; 2008/09/11 dadams
1671;; diredp-do-grep: Plain C-u means grep all files in Dired buffer.
1672;; diredp-do-grep-1: Treat 'all value of FILES arg.
1673;; Added: diredp-all-files.
1674;; 2008/09/09 dadams
1675;; Added: diredp-marked(-other-window). Added to menus. Bound *-other-window to C-M-*.
1676;; 2008/09/07 dadams
1677;; Added: diredp(-mouse)-do-grep(-1), diredp-grep-this-file.
1678;; Bound diredp-do-grep to M-g. Added grep commands to menus.
1679;; 2008/07/18 dadams
1680;; Soft-require w32-browser.el. Bind its commands in Dired map and menus.
1681;; 2008/03/08 dadams
1682;; dired-maybe-insert-subdir: Fit one-window frame after inserting subdir.
1683;; 2008/03/07 dadams
1684;; Added: redefinitions of dired-maybe-insert-subdir, dired-goto-file, dired-get-filename.
1685;; Added: diredp-this-subdir.
1686;; 2007/11/27 dadams
1687;; diredp-mouse(-backup)-diff: If available, use icicle-read-string-completing.
1688;; 2007/09/23 dadams
1689;; Removed second arg to undefine-killer-commands.
1690;; 2007/07/27 dadams
1691;; diredp-font-lock-keywords-1: Allow also for bz2 compressed files - Thx to Andreas Eder.
1692;; 2006/09/03 dadams
1693;; diredp-font-lock-keywords-1: Corrected file size and inode number. Thx to Peter Barabas.
1694;; 2006/08/20 dadams
1695;; Added: diredp-find-a-file*.
1696;; 2006/06/18 dadams
1697;; diredp-font-lock-keywords-1: Highlight file name (also) of flagged files.
1698;; Use dired-del-marker instead of literal D.
1699;; Added: diredp-deletion-file-name.
1700;; 2006/03/31 dadams
1701;; No longer use display-in-minibuffer.
1702;; 2006/01/07 dadams
1703;; Added: link for sending bug report.
1704;; 2006/01/06 dadams
1705;; Added defgroup Dired-Plus and used it. Added :link.
1706;; 2006/01/04 dadams
1707;; Added defvar of directory-listing-before-filename-regexp, for Emacs 22 compatibility.
1708;; 2005/12/29 dadams
1709;; Added: diredp-mouse-mark/unmark-mark-region-files.
1710;; 2005/12/26 dadams
1711;; Updated groups.
1712;; 2005/12/05 dadams
1713;; diredp-ignored-file-name: Made it slightly darker.
1714;; 2005/11/05 dadams
1715;; Renamed all stuff defined here to have diredp- prefix.
1716;; diredp-relsymlink-this-file: Protected with fboundp.
1717;; Changed to soft require: dired-x.el.
1718;; Removed comment to require this inside eval-after-load.
1719;; 2005/11/03 dadams
1720;; Added: dired-display-msg. Replace blue-foreground-face with it.
1721;; Alias dired-do-toggle to dired-toggle-marks, if defined.
1722;; 2005/11/02 dadams
1723;; Added: dired-get-file-for-visit, dired(-mouse)-find-alternate-file*,
1724;; togglep-dired-find-file-reuse-dir, dired+-subst-find-*.
1725;; Use defface for all faces. Renamed without "-face". No longer require def-face-const.
1726;; dired-simultaneous-find-file: Minor bug fix (typo).
1727;; 2005/07/10 dadams
1728;; dired-unmark-all-files-no-query -> dired-unmark-all-marks
1729;; (thanks to Sivaram Neelakantan for bug report).
1730;; 2005/05/25 dadams
1731;; string-to-int -> string-to-number everywhere.
1732;; 2005/05/17 dadams
1733;; Updated to work with Emacs 22.x.
1734;; 2005/02/16 dadams
1735;; Added dired-mark/unmark-extension. Replaced dired-mark-extension with it everywhere.
1736;; 2005/01/08 dadams
1737;; Bind [S-mouse-1], instead of [S-down-mouse-1], to dired-mouse-mark-region-files.
1738;; 2004/11/20 dadams
1739;; dired-mark-sexp: Search for literal month names only for versions before Emacs 20.
1740;; Refined to deal with Emacs 21 < 21.3.50 (soon to be 22.x)
1741;; 2004/11/14 dadams
1742;; Bound dired-no-confirm to non-nil for dired-mouse-*.
1743;; Updated for Emacs 21 and improved highlighting:
1744;; Spaces OK in file and directory names. Highlight date/time and size.
1745;; 2004/10/17 dadams
1746;; Require cl only for Emacs 20, and only when compile.
1747;; 2004/10/01 dadams
1748;; Updated to work with Emacs 21 also.
1749;; 2004/04/02 dadams
1750;; dired-font-lock-keywords-1: Prefer using dired-omit-extensions
1751;; to completion-ignored-extensions, if available.
1752;; 2004/03/22 dadams
1753;; Added dired-mouse-mark-region-files and dired-mouse-mark/unmark.
1754;; 2000/09/27 dadams
1755;; 1. dired-font-lock-keywords-1: fixed for spaces in dir names.
1756;; 2. Added: dired-buffers-for-dir.
1757;; 1999/09/06 dadams
1758;; Added S-*-mouse-2 bindings (same as C-*-mouse-2).
1759;; 1999/08/26 dadams
1760;; 1. Added *-face vars and dired-font-lock-keywords-1.
1761;; 2. Added possibility to use dired-font-lock-keywords-1 via hook.
1762;; 1999/08/26 dadams
1763;; Changed key binding of dired-mouse-find-file from down-mouse-2 to mouse-2.
1764;; 1999/08/25 dadams
1765;; Changed (C-)(M-)mouse-2 bindings.
1766;; 1999/08/25 dadams
1767;; 1. Added cmds & menu bar and key bindings: (dired-)find-file-other-frame.
1768;; 2. Changed binding for dired-display-file.
1769;; 1999/03/26 dadams
1770;; 1. Get rid of Edit menu-bar menu.
1771;; 2. dired-mouse-3-menu: Changed popup titles and item names.
1772;;
1773;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1774;;
1775;; This program is free software; you can redistribute it and/or modify
1776;; it under the terms of the GNU General Public License as published by
1777;; the Free Software Foundation; either version 2, or (at your option)
1778;; any later version.
1779
1780;; This program is distributed in the hope that it will be useful,
1781;; but WITHOUT ANY WARRANTY; without even the implied warranty of
1782;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1783;; GNU General Public License for more details.
1784
1785;; You should have received a copy of the GNU General Public License
1786;; along with this program; see the file COPYING. If not, write to
1787;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
1788;; Floor, Boston, MA 02110-1301, USA.
1789;;
1790;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1791;;
1792;;; Code:
1793
1794(eval-when-compile (require 'cl)) ;; case (plus, for Emacs 20: dolist, pop, push)
1795(eval-when-compile (require 'easymenu)) ;; easy-menu-create-menu
1796
1797(require 'dired) ;; dired-revert
1798(require 'dired-aux) ;; dired-bunch-files, dired-do-chxxx, dired-do-create-files,
1799 ;; dired-mark-read-string, dired-read-shell-command,
1800 ;; dired-run-shell-command, dired-shell-stuff-it
1801(require 'dired-x nil t) ;; (no error if not found) dired-do-relsymlink
1802(require 'autofit-frame nil t) ;; (no error if not found) fit-frame-if-one-window
1803(require 'bookmark+ nil t) ;; (no error if not found)
1804 ;; bmkp-autofile-add-tags, bmkp-autofile-remove-tags, bmkp-autofile-set, bmkp-copied-tags,
1805 ;; bmkp-current-bookmark-file, bmkp-describe-bookmark, bmkp-empty-file, bmkp-get-autofile-bookmark,
1806 ;; bmkp-get-bookmark-in-alist, bmkp-get-tags, bmkp-read-tag-completing,
1807 ;; bmkp-read-tags-completing, bmkp-refresh/rebuild-menu-list, bmkp-remove-all-tags,
1808 ;; bmkp-same-file-p, bmkp-set-bookmark-file-bookmark, bmkp-set-sequence-bookmark,
1809 ;; bmkp-set-tag-value, bmkp-some, bmkp-switch-bookmark-file, bmkp-tag-name
1810
1811;; For now at least, `highlight.el' is needed only if you use `bookmark+.el'.
1812(when (featurep 'bookmark+) (require 'highlight nil t)) ;; (no error if not found):
1813 ;; hlt-highlight-region
1814
1815(if (> emacs-major-version 21) (require 'help-fns+ nil t) (require 'help+20 nil t)) ;; (no error if not found):
1816 ;; describe-file
1817
1818(require 'misc-fns nil t) ;; (no error if not found): undefine-killer-commands
1819(require 'image-file nil t) ;; (no error if not found): image-file-name-regexp
1820(require 'image-dired nil t) ;; (no error if not found):
1821 ;; image-dired-create-thumb, image-dired-create-thumbnail-buffer,
1822 ;; image-dired-dired-after-readin-hook, image-dired-delete-tag, image-dired-dired-comment-files,
1823 ;; image-dired-dired-display-external, image-dired-dired-display-image,
1824 ;; image-dired-display-thumbs, image-dired-get-comment, image-dired-get-exif-file-name,
1825 ;; image-dired-get-thumbnail-image, image-dired-insert-thumbnail, image-dired-line-up,
1826 ;; image-dired-line-up-dynamic, image-dired-line-up-interactive, image-dired-line-up-method,
1827 ;; image-dired-list-tags, image-dired-main-image-directory, image-dired-mark-tagged-files,
1828 ;; image-dired-read-comment, image-dired-remove-tag, image-dired-save-information-from-widgets,
1829 ;; image-dired-tag-files, image-dired-thumb-height, image-dired-thumbnail-buffer,
1830 ;; image-dired-thumb-name, image-dired-thumb-size, image-dired-thumb-width,
1831 ;; image-dired-widget-list, image-dired-write-comments, image-dired-write-tags
1832(when (memq system-type '(windows-nt ms-dos))
1833 ;; (no error if not found):
1834 (require 'w32-browser nil t));; dired-w32explore, dired-w32-browser, dired-mouse-w32-browser,
1835 ;; dired-multiple-w32-browser
1836(when (< emacs-major-version 21) (require 'subr-21)) ;; replace-regexp-in-string
1837
1838;; Provide macro for code byte-compiled using Emacs < 22.
1839(eval-when-compile
1840 (when (< emacs-major-version 22)
1841 (defmacro minibuffer-with-setup-hook (fun &rest body)
1842 "Temporarily add FUN to `minibuffer-setup-hook' while executing BODY.
1843BODY should use the minibuffer at most once.
1844Recursive uses of the minibuffer are unaffected (FUN is not
1845called additional times).
1846
1847This macro actually adds an auxiliary function that calls FUN,
1848rather than FUN itself, to `minibuffer-setup-hook'."
1849 ;; (declare (indent 1) (debug t))
1850 (let ((hook (make-symbol "setup-hook")))
1851 `(let (,hook)
1852 (setq ,hook (lambda ()
1853 ;; Clear out this hook so it does not interfere
1854 ;; with any recursive minibuffer usage.
1855 (remove-hook 'minibuffer-setup-hook ,hook)
1856 (funcall ,fun)))
1857 (unwind-protect
1858 (progn (add-hook 'minibuffer-setup-hook ,hook) ,@body)
1859 (remove-hook 'minibuffer-setup-hook ,hook)))))))
1860
1861(defmacro diredp-user-error (&rest args)
1862 `(if (fboundp 'user-error) (user-error ,@args) (error ,@args)))
1863
1864;; Define these for Emacs 20 and 21.
1865(unless (fboundp 'dired-get-file-for-visit) ; Emacs 22+
1866 (defun dired-get-file-for-visit () ; Not bound
1867 "Get the current line's file name, with an error if file does not exist."
1868 (interactive)
1869 (let ((raw (dired-get-filename nil t)) ; Pass t for second arg so no error for `.' and `..'.
1870 file-name)
1871 (unless raw (error "No file on this line"))
1872 (setq file-name (file-name-sans-versions raw t))
1873 (if (file-exists-p file-name)
1874 file-name
1875 (if (file-symlink-p file-name)
1876 (error "File is a symlink to a nonexistent target")
1877 (error "File no longer exists; type `g' to update Dired buffer")))))
1878
1879 (defun dired-find-alternate-file () ; Not bound
1880 "In Dired, visit this file or directory instead of the Dired buffer."
1881 (interactive)
1882 (set-buffer-modified-p nil)
1883 (find-alternate-file (dired-get-file-for-visit))))
1884
1885;;;;;;;;;;;;;;;;;;;;;;;
1886
1887
1888(provide 'dired+)
1889(require 'dired+) ; Ensure loaded before compile this.
1890
1891;; Quiet the byte-compiler.
1892(defvar bmkp-copied-tags) ; In `bookmark+-1.el'
1893(defvar bmkp-current-bookmark-file) ; In `bookmark+-1.el'
1894(defvar bookmark-default-file) ; In `bookmark.el'
1895(defvar compilation-current-error) ; In `compile.el'
1896(defvar delete-by-moving-to-trash) ; Built-in, Emacs 23+
1897(defvar dired-always-read-filesystem) ; In `dired.el', Emacs 26+
1898(defvar dired-auto-revert-buffer) ; In `dired.el', Emacs 23+
1899(defvar dired-details-state) ; In `dired-details+.el'
1900(defvar dired-keep-marker-hardlink) ; In `dired-x.el'
1901(defvar dired-recursive-deletes) ; In `dired.el', Emacs 22+
1902(defvar dired-shrink-to-fit) ; In `dired.el'
1903(defvar dired-switches-alist) ; In `dired.el'
1904(defvar dired-subdir-switches) ; In `dired.el'
1905(defvar dired-touch-program) ; Emacs 22+
1906(defvar dired-use-ls-dired) ; Emacs 22+
1907(defvar diredp-count-.-and-..-flag) ; Here, Emacs 22+
1908(defvar diredp-hide-details-initially-flag) ; Here, Emacs 24.4+
1909(defvar diredp-hide-details-last-state) ; Here, Emacs 24.4+
1910(defvar diredp-hide-details-propagate-flag) ; Here, Emacs 24.4+
1911(defvar diredp-hide-details-toggled) ; Here, Emacs 24.4+
1912(defvar diredp-highlight-autofiles-mode) ; Here, Emacs 22+
1913(defvar diredp-menu-bar-encryption-menu) ; Here, Emacs 23+
1914(defvar diredp-menu-bar-images-recursive-menu) ; Here (old name)
1915(defvar diredp-menu-bar-regexp-recursive-menu) ; Here (old name)
1916(defvar diredp-menu-bar-subdir-menu) ; Here (old name)
1917(defvar diredp-single-bookmarks-menu) ; Here, if Bookmark+ is available
1918(defvar filesets-data) ; In `filesets.el'
1919(defvar grep-use-null-device) ; In `grep.el'
1920(defvar header-line-format) ; Emacs 22+
1921(defvar icicle-file-sort) ; In `icicles-opt.el'
1922(defvar icicle-file-sort-first-time-p) ; In `icicles-var.el'
1923(defvar icicle-files-ido-like-flag) ; In `icicles-opt.el'
1924(defvar icicle-ignored-directories) ; In `icicles-opt.el'
1925(defvar icicle-sort-comparer) ; In `icicles-opt.el'
1926(defvar image-dired-display-image-buffer) ; In `image-dired.el'
1927(defvar image-dired-line-up-method) ; In `image-dired.el'
1928(defvar image-dired-main-image-directory) ; In `image-dired.el'
1929(defvar image-dired-thumbnail-buffer) ; In `image-dired.el'
1930(defvar image-dired-thumb-height) ; In `image-dired.el'
1931(defvar image-dired-thumb-width) ; In `image-dired.el'
1932(defvar image-dired-widget-list) ; In `image-dired.el'
1933(defvar ls-lisp-use-insert-directory-program) ; In `ls-lisp.el'
1934(defvar minibuffer-default-add-function) ; In `simple.el', Emacs 23+
1935(defvar mouse3-dired-function) ; In `mouse3.el'
1936(defvar read-file-name-completion-ignore-case) ; In `minibuffer.el', Emacs 23+. In C code, Emacs 22.
1937(defvar recentf-list) ; In `recentf.el'
1938(defvar switch-to-buffer-preserve-window-point) ; In `window.el', Emacs 24+
1939(defvar tooltip-mode) ; In `tooltip.el'
1940(defvar vc-directory-exclusion-list) ; In `vc'
1941(defvar w32-browser-wait-time) ; In `w32-browser.el'
1942
1943;;;;;;;;;;;;;;;;;;;;;;;
1944
1945(defgroup Dired-Plus nil
1946 "Various enhancements to Dired."
1947 :prefix "diredp-" :group 'dired
1948 :link `(url-link :tag "Send Bug Report"
1949 ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\
1950dired+.el bug: \
1951&body=Describe bug here, starting with `emacs -q'. \
1952Don't forget to mention your Emacs and library versions."))
1953 :link '(url-link :tag "Other Libraries by Drew"
1954 "https://www.emacswiki.org/emacs/DrewsElispLibraries")
1955 :link '(url-link :tag "Download"
1956 "https://www.emacswiki.org/emacs/download/dired%2b.el")
1957 :link '(url-link :tag "Description"
1958 "https://www.emacswiki.org/emacs/DiredPlus")
1959 :link '(emacs-commentary-link :tag "Commentary" "dired+"))
1960
1961;;; Variables
1962
1963;; `dired-do-toggle' was renamed to `dired-toggle-marks' after Emacs 20.
1964(unless (fboundp 'dired-toggle-marks) (defalias 'dired-toggle-marks 'dired-do-toggle))
1965
1966;;; This is duplicated in `diff.el' and `vc.el'.
1967;;;###autoload
1968(defcustom diff-switches "-c"
1969 "*A string or list of strings specifying switches to be passed to diff."
1970 :type '(choice string (repeat string))
1971 :group 'dired :group 'diff)
1972
1973;;;###autoload
1974(defcustom diredp-auto-focus-frame-for-thumbnail-tooltip-flag nil
1975 "*Non-nil means automatically focus the frame for a thumbnail tooltip.
1976If nil then you will not see a thumbnail image tooltip when you
1977mouseover an image-file name in Dired, unless you first give the frame
1978the input focus (e.g., by clicking its title bar).
1979
1980This option has no effect if `diredp-image-preview-in-tooltip' is nil.
1981It also has no effect for Emacs versions prior to Emacs 22."
1982 :type 'boolean :group 'Dired-Plus)
1983
1984;;;###autoload
1985(defcustom diredp-bind-problematic-terminal-keys t
1986 "*Non-nil means bind some keys that might not work in a text-only terminal.
1987This applies to keys that use modifiers Meta and Shift together.
1988If you use Emacs in text-only terminal and your terminal does not
1989support the use of such keys then customize this option to nil."
1990 :type 'boolean :group 'Dired-Plus)
1991
1992;;;###autoload
1993(defcustom diredp-compressed-extensions '(".tar" ".taz" ".tgz" ".arj" ".lzh"
1994 ".lzma" ".xz" ".zip" ".z" ".Z" ".gz" ".bz2")
1995 "*List of compressed-file extensions, for highlighting."
1996 :type '(repeat string) :group 'Dired-Plus)
1997
1998(when (> emacs-major-version 21) ; Emacs 22+
1999 (defcustom diredp-count-.-and-..-flag nil
2000 "Non-nil means count `.' and `..' when counting files for mode-line."
2001 :type 'boolean :group 'Dired-Plus))
2002
2003;;;###autoload
2004(defcustom diredp-dwim-any-frame-flag pop-up-frames
2005 "*Non-nil means the target directory can be in a window in another frame.
2006Only visible frames are considered.
2007This is used by ``dired-dwim-target-directory'.
2008This option has no effect for Emacs versions before Emacs 22."
2009 :type 'boolean :group 'Dired-Plus)
2010
2011(when (fboundp 'dired-hide-details-mode) ; Emacs 24.4+
2012 (defcustom diredp-hide-details-initially-flag t
2013 "*Non-nil means hide details in Dired from the outset."
2014 :type 'boolean :group 'Dired-Plus
2015 :set (lambda (sym defs)
2016 (custom-set-default sym defs)
2017 (setq diredp-hide-details-last-state diredp-hide-details-initially-flag)))
2018
2019 (defcustom diredp-hide-details-propagate-flag t
2020 "*Non-nil means display the next Dired buffer the same way as the last.
2021The last `dired-hide-details-mode' value set is used by the next Dired
2022buffer created."
2023 :type 'boolean :group 'Dired-Plus))
2024
2025;; Emacs 20 only.
2026;;;###autoload
2027(unless (fboundp 'define-minor-mode)
2028 (defcustom diredp-highlight-autofiles-mode t
2029 "*Non-nil means highlight names of files that are autofile bookmarks.
2030Autofiles that have tags are highlighted using face
2031`diredp-tagged-autofile-name'. Those with no tags are highlighted
2032using face `diredp-autofile-name'.
2033
2034Setting this option directly does not take effect; use either
2035\\[customize] or command `diredp-highlight-autofiles-mode'.
2036
2037NOTE: When `dired+.el' is loaded (for the first time per Emacs
2038session), the highlighting is turned ON, regardless of the option
2039value. To prevent this and have the highlighting OFF by default, you
2040must do one of the following:
2041
2042 * Put (diredp-highlight-autofiles-mode -1) in your init file, AFTER
2043 it loads `dired+.el'.
2044
2045 * Customize the option to `nil', AND ensure that your `custom-file'
2046 (or the `custom-saved-variables' part of your init file) is
2047 evaluated before `dired+.el' is loaded.
2048
2049This option has no effect unless you use libraries `Bookmark and
2050`highlight.el'."
2051 :set (lambda (symbol value) (diredp-highlight-autofiles-mode (if value 1 -1)))
2052 :initialize 'custom-initialize-default
2053 :type 'boolean :group 'Dired-Plus :require 'dired+))
2054
2055;;;###autoload
2056(defcustom diredp-ignore-compressed-flag t
2057 "*Non-nil means to font-lock names of compressed files as ignored files.
2058This applies to filenames whose extensions are in
2059`diredp-compressed-extensions'. If nil they are highlighted using
2060face `diredp-compressed-file-name'."
2061 :type 'boolean :group 'Dired-Plus)
2062
2063;;;###autoload
2064(defcustom diredp-image-preview-in-tooltip (or (and (boundp 'image-dired-thumb-size) image-dired-thumb-size)
2065 100)
2066 "*Whether and what kind of image preview to show in a tooltip.
2067The possible values are:
2068
2069 `nil' : do not show a tooltip preview
2070 integer N>0 : show a thumbnail preview of that size
2071 `full' : show a full-size preview of the image
2072
2073To enable tooltip image preview you must turn on `tooltip-mode' and
2074load library `image-dired.el'. See also option
2075`diredp-auto-focus-frame-for-thumbnail-tooltip-flag'.
2076
2077This option has no effect for Emacs versions prior to Emacs 22."
2078 :type '(choice
2079 (restricted-sexp :tag "Show a thumnail image of size"
2080 :match-alternatives ((lambda (x) (and (wholenump x) (not (zerop x))))))
2081 (const :tag "Show a full-size image preview" full)
2082 (const :tag "OFF: Do not show an image preview" nil))
2083 :group 'Dired-Plus)
2084
2085;;;###autoload
2086(defcustom diredp-image-show-this-file-use-frame-flag t
2087 "Non-nil means `diredp-image-show-this-file' uses another frame.
2088If nil then it uses another window. Using another frame means you
2089have more control over the image size when you use a prefix arg.
2090
2091If it uses another window then the prefix arg controls only the
2092minimum window height, not necessarily the image scale (height).
2093
2094\(If the buffer displaying the image is already considered a
2095special-display buffer by your Emacs setup, then a nil value of this
2096option has no effect.)"
2097 :type 'boolean :group 'Dired-Plus)
2098
2099;;;###autoload
2100(defcustom diredp-max-frames 200
2101 "*Max number of frames, for commands that find files in separate frames.
2102These commands are `dired-do-find-marked-files' and
2103`diredp-do-find-marked-files-recursive'. See their descriptions for
2104the circumstances in which they show the files in separate frames."
2105 :type '(restricted-sexp :match-alternatives ((lambda (x) (and (wholenump x) (not (zerop x))))))
2106 :group 'Dired-Plus)
2107
2108;;;###autoload
2109(defcustom diredp-prompt-for-bookmark-prefix-flag nil
2110 "*Non-nil means prompt for a prefix string for bookmark names."
2111 :type 'boolean :group 'Dired-Plus)
2112
2113;;;###autoload
2114(defcustom diredp-visit-ignore-regexps ()
2115 "Regexps matching file names for `diredp-visit-(next|previous)' to skip.
2116A file or directory name matching one of these regexps is skipped,
2117along with those with an extension in `diredp-visit-ignore-extensions'."
2118 :type '(repeat regexp) :group 'Dired-Plus)
2119
2120;;;###autoload
2121(defcustom diredp-visit-ignore-extensions '("elc")
2122 "Extensions of file names for `diredp-visit-(next|previous)' to skip.
2123A file name with one of these extensions is skipped, along with those
2124matching a regexp in `diredp-visit-ignore-regexps'."
2125 :type '(repeat string) :group 'Dired-Plus)
2126
2127;;;###autoload
2128(defcustom diredp-w32-local-drives '(("C:" "Local disk"))
2129 "*Local MS Windows drives that you want to use for `diredp-w32-drives'.
2130Each entry is a list (DRIVE DESCRIPTION), where DRIVE is the drive
2131name and DESCRIPTION describes DRIVE."
2132 :type '(alist
2133 :key-type (string :tag "Drive name")
2134 :value-type (group (string :tag "Drive description")))
2135 :group 'Dired-Plus)
2136
2137;;;###autoload
2138(defcustom diredp-wrap-around-flag t
2139 "*Non-nil means Dired \"next\" commands wrap around to buffer beginning."
2140 :type 'boolean :group 'Dired-Plus)
2141
2142(when (fboundp 'dired-hide-details-mode) ; Emacs 24.4+
2143 (defvar diredp-hide-details-last-state diredp-hide-details-initially-flag
2144 "Last `dired-hide-details-mode' value.
2145Initialized to the value of option `diredp-hide-details-initially-flag'.")
2146
2147 (defvar diredp-hide-details-toggled nil
2148 "Non-nil means you have already toggled hiding details in this buffer.")
2149 (make-variable-buffer-local 'diredp-hide-details-toggled))
2150
2151;; Same value as the default value of `icicle-re-no-dot'.
2152(defvar diredp-re-no-dot "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*"
2153 "Regexp that matches anything except `.' and `..'.")
2154
2155(defvar diredp-w32-drives-mode-map (let ((map (make-sparse-keymap)))
2156 (define-key map "q" 'bury-buffer)
2157 (define-key map "\r" 'widget-button-press)
2158 (define-key map [mouse-2] 'widget-button-click)
2159 map)
2160 "Keymap for `diredp-w32-drives-mode'.")
2161
2162;;; $$$$$$ Starting with Emacs 22, *-move-to* is defvaraliased to *-listing-before*.
2163;;; But `files+.el' defines *-listing-before*, so we define it here too.
2164;;; (unless (> emacs-major-version 21)
2165;;; (defvar directory-listing-before-filename-regexp dired-move-to-filename-regexp
2166;;; "Regular expression to match up to the file name in a directory listing.
2167;;; The default value is designed to recognize dates and times
2168;;; regardless of the language."))
2169
2170;;; Macros
2171
2172
2173;; Unlike `dired-mark-if':
2174;;
2175;; 1. Value returned and message indicate both the number matched and the number changed.
2176;; 2. Added optional arg PLURAL, for irregular plurals (e.g. "directories").
2177;;
2178(defmacro diredp-mark-if (predicate singular &optional plural)
2179 "Mark files for PREDICATE, according to `dired-marker-char'.
2180PREDICATE is evaluated on each line, with point at beginning of line.
2181SINGULAR is a singular noun phrase for the type of files being marked.
2182Optional arg PLURAL is a plural noun phrase for the type of files
2183 being marked.
2184If PLURAL is nil then SINGULAR should end with a noun that can be
2185pluralized by adding `s'.
2186
2187Return nil if no files matched PREDICATE.
2188Otherwise return a cons (CHANGED . MATCHED), where:
2189 CHANGED is the number of markings that were changed by the operation.
2190 MATCHED is the number of files that matched PREDICATE."
2191 `(let ((inhibit-read-only t)
2192 changed matched)
2193 (save-excursion
2194 (setq matched 0
2195 changed 0)
2196 (when ,singular (message "%s %s%s..."
2197 (cond ((eq dired-marker-char ?\040) "Unmarking")
2198 ((eq dired-del-marker dired-marker-char) "Flagging")
2199 (t "Marking"))
2200 (or ,plural (concat ,singular "s"))
2201 (if (eq dired-del-marker dired-marker-char) " for deletion" "")))
2202 (goto-char (point-min))
2203 (while (not (eobp))
2204 (when ,predicate
2205 (setq matched (1+ matched))
2206 (unless (diredp-looking-at-p (char-to-string dired-marker-char))
2207 (delete-char 1) (insert dired-marker-char) (setq changed (1+ changed))))
2208 (forward-line 1))
2209 (when ,singular (message "%s %s%s%s newly %s%s"
2210 matched
2211 (if (= matched 1) ,singular (or ,plural (concat ,singular "s")))
2212 (if (not (= matched changed)) " matched, " "")
2213 (if (not (= matched changed)) changed "")
2214 (if (eq dired-marker-char ?\040) "un" "")
2215 (if (eq dired-marker-char dired-del-marker) "flagged" "marked"))))
2216 (and (> matched 0) (cons changed matched))))
2217
2218
2219;; Just a helper function for `dired-map-over-marks'.
2220(defun diredp-get-file-or-dir-name (arg)
2221 "Return name of next file or directory or nil if none.
2222Argument ARG:
2223 `all-files-no-dirs' or nil means skip directories.
2224 `all-files-no-dots' means skip `.' and `..'."
2225 (let ((fname nil))
2226 (while (and (not fname) (not (eobp)))
2227 (setq fname (dired-get-filename t t))
2228 (when (and fname (or (not arg) (eq arg 'all-files-no-dirs)) (file-directory-p fname))
2229 (setq fname nil))
2230 (when (and fname (eq arg 'all-files-no-dots) (or (member fname '("." ".."))
2231 (diredp-string-match-p "/\\.\\.?$" fname)))
2232 (setq fname nil))
2233 (forward-line 1))
2234 (forward-line -1)
2235 fname))
2236
2237
2238;; REPLACE ORIGINAL in `dired.el'.
2239;;
2240;; Treat multiple `C-u' specially.
2241;;
2242(defmacro dired-map-over-marks (body arg &optional show-progress
2243 distinguish-one-marked)
2244 "Eval BODY with point on each marked line. Return a list of BODY's results.
2245If no marked file could be found, execute BODY on the current line.
2246ARG, if non-nil, specifies the files to use instead of the marked files.
2247 If ARG is an integer, use the next ARG files (previous -ARG, if < 0).
2248 In that case, point is dragged along. This is so that commands on
2249 the next ARG (instead of the marked) files can be easily chained.
2250 If ARG is a cons with element 16, 64, or 256, corresponding to
2251 `C-u C-u', `C-u C-u C-u', or `C-u C-u C-u C-u', then use all files
2252 in the Dired buffer, where:
2253 16 includes NO directories (including `.' and `..')
2254 64 includes directories EXCEPT `.' and `..'
2255 256 includes ALL directories (including `.' and `..')
2256 If ARG is otherwise non-nil, use the current file.
2257If optional third arg SHOW-PROGRESS evaluates to non-nil,
2258 redisplay the Dired buffer after each file is processed.
2259
2260No guarantee is made about the position on the marked line. BODY must
2261ensure this itself, if it depends on this.
2262
2263Search starts at the beginning of the buffer, thus the car of the list
2264corresponds to the line nearest the end of the buffer. This is also
2265true for (positive and negative) integer values of ARG.
2266
2267BODY should not be too long, because it is expanded four times.
2268
2269If DISTINGUISH-ONE-MARKED is non-nil, then return (t FILENAME) instead
2270 of (FILENAME), if only one file is marked."
2271 ;; WARNING: BODY must not add new lines before point - this may cause an
2272 ;; endless loop. This warning should not apply any longer, sk 2-Sep-1991 14:10.
2273 `(prog1
2274 (let ((inhibit-read-only t)
2275 (newarg ,arg)
2276 multi-C-u case-fold-search found results)
2277 (when (and (consp newarg) (> (prefix-numeric-value newarg) 4))
2278 (setq newarg (case (prefix-numeric-value newarg)
2279 (16 'all-files-no-dirs) ; `C-u C-u'
2280 (64 'all-files-no-dots) ; `C-u C-u C-u'
2281 (256 'all-files) ; `C-u C-u C-u C-u'
2282 (t 'all-files-no-dirs))
2283 multi-C-u t))
2284 (if (and newarg (not multi-C-u))
2285 (if (integerp newarg)
2286 (progn ; No `save-excursion', want to move point.
2287 (dired-repeat-over-lines newarg #'(lambda ()
2288 (when ,show-progress (sit-for 0))
2289 (setq results (cons ,body results))))
2290 (if (< newarg 0) (nreverse results) results))
2291 ;; Non-nil, non-integer ARG means use current file:
2292 (list ,body))
2293 (let ((regexp (dired-marker-regexp))
2294 next-position)
2295 (save-excursion
2296 (goto-char (point-min))
2297 ;; Remember position of next marked file before BODY can insert lines before the
2298 ;; just found file, confusing us by finding the same marked file again and again...
2299 (setq next-position (and (if multi-C-u
2300 (diredp-get-file-or-dir-name newarg)
2301 (re-search-forward regexp nil t))
2302 (point-marker))
2303 found (not (null next-position)))
2304 (while next-position
2305 (goto-char next-position)
2306 (when ,show-progress (sit-for 0))
2307 (setq results (cons ,body results))
2308 ;; move after last match
2309 (goto-char next-position)
2310 (forward-line 1)
2311 (set-marker next-position nil)
2312 (setq next-position (and (if multi-C-u
2313 (diredp-get-file-or-dir-name newarg)
2314 (re-search-forward regexp nil t))
2315 (point-marker)))))
2316 (when (and ,distinguish-one-marked (= (length results) 1))
2317 (setq results (cons t results)))
2318 (if found results (list ,body)))))
2319 ;; `save-excursion' loses, again
2320 (dired-move-to-filename)))
2321
2322;; Same as `icicle-with-help-window' in `icicles-mac.el'
2323;; and `bmkp-with-help-window' in `bookmark+-mac.el'.
2324(defmacro diredp-with-help-window (buffer &rest body)
2325 "`with-help-window', if available; else `with-output-to-temp-buffer'."
2326 (if (fboundp 'with-help-window)
2327 `(with-help-window ,buffer ,@body)
2328 `(with-output-to-temp-buffer ,buffer ,@body)))
2329
2330(put 'diredp-with-help-window 'common-lisp-indent-function '(4 &body))
2331
2332;;; Utility functions
2333
2334;; Same as `imenup-delete-if-not'.
2335;;
2336(defun diredp-delete-if-not (predicate xs)
2337 "Remove all elements of list XS that do not satisfy PREDICATE.
2338This operation is destructive, reusing conses of XS whenever possible."
2339 (while (and xs (not (funcall predicate (car xs))))
2340 (setq xs (cdr xs)))
2341 (let ((cl-p xs))
2342 (while (cdr cl-p)
2343 (if (not (funcall predicate (cadr cl-p))) (setcdr cl-p (cddr cl-p)) (setq cl-p (cdr cl-p)))))
2344 xs)
2345
2346;; Same as `tap-string-match-p' in `thingatpt+.el'.
2347(if (fboundp 'string-match-p)
2348 (defalias 'diredp-string-match-p 'string-match-p) ; Emacs 23+
2349 (defun diredp-string-match-p (regexp string &optional start)
2350 "Like `string-match', but this saves and restores the match data."
2351 (save-match-data (string-match regexp string start))))
2352
2353(if (fboundp 'looking-at-p)
2354 (defalias 'diredp-looking-at-p 'looking-at-p) ; Emacs 23+
2355 (defun diredp-looking-at-p (regexp)
2356 "Like `looking-at', but this saves and restores the match data."
2357 (save-match-data (looking-at regexp))))
2358
2359;; `dired-read-regexp' does not accept DEFAULT and HISTORY for older Emacsen, so use this.
2360(defun diredp-read-regexp (prompt &optional default history)
2361 "Read a regexp.
2362HISTORY defaults to `dired-regexp-history'."
2363 (setq history (or history 'dired-regexp-history))
2364 (if (fboundp 'read-regexp)
2365 (read-regexp prompt default history)
2366 (read-from-minibuffer prompt nil nil nil history default)))
2367
2368(if (fboundp 'delete-dups)
2369 (defalias 'diredp-delete-dups 'delete-dups)
2370 (defun diredp-delete-dups (list)
2371 "Destructively remove `equal' duplicates from LIST.
2372Store the result in LIST and return it. LIST must be a proper list.
2373Of several `equal' occurrences of an element in LIST, the first
2374one is kept."
2375 (let ((tail list))
2376 (while tail
2377 (setcdr tail (delete (car tail) (cdr tail)))
2378 (setq tail (cdr tail))))
2379 list))
2380
2381(defun diredp-nonempty-region-p ()
2382 "Return non-nil if region is active and non-empty."
2383 (and transient-mark-mode mark-active (mark) (> (region-end) (region-beginning))))
2384
2385(defun diredp-get-image-filename (&optional localp no-error-if-not-filep)
2386 "Return the image-file name on this line, or nil if no image file.
2387If not in Dired (or a mode derived from Dired), then test the entire
2388text of the current line as the file name.
2389
2390The optional args are the same as for `dired-get-filename'. They are
2391ignored if not in a Dired mode.
2392
2393\(Prior to Emacs 22, this function just returns nil.)"
2394 (let ((file (if (derived-mode-p 'dired-mode)
2395 (dired-get-filename localp no-error-if-not-filep)
2396 ;; Make it work also for `diredp-list-files' listings.
2397 (buffer-substring-no-properties (line-beginning-position) (line-end-position)))))
2398 (and file
2399 (fboundp 'image-file-name-regexp) ; Emacs 22+, `image-file.el'.
2400 (diredp-string-match-p (image-file-name-regexp) file)
2401 file)))
2402
2403(defun diredp-root-directory-p (file)
2404 "Return non-nil if FILE is a root directory."
2405 (if (fboundp 'ange-ftp-root-dir-p)
2406 (ange-ftp-root-dir-p (file-name-as-directory file))
2407 ;; This is essentially `ange-ftp-root-dir-p' applied to `file-name-as-directory'.
2408 ;; If `ange-ftp-root-dir-p' changes, update this code.
2409 (or (and (eq system-type 'windows-nt) (diredp-string-match-p "\\`[a-zA-Z]:[/\\]\\'"
2410 (file-name-as-directory file)))
2411 (string= "/" file))))
2412
2413(defun diredp-parent-dir (file &optional relativep)
2414 "Return the parent directory of FILE, or nil if none.
2415Optional arg RELATIVEP non-nil means return a relative name, that is,
2416just the parent component."
2417 (let ((parent (file-name-directory (directory-file-name (expand-file-name file))))
2418 relparent)
2419 (when relativep (setq relparent (file-name-nondirectory (directory-file-name parent))))
2420 (and (not (equal parent file)) (or relparent parent))))
2421
2422(unless (fboundp 'derived-mode-p) ; Emacs 20, 21.
2423 (defun derived-mode-p (&rest modes)
2424 "Non-nil if the current major mode is derived from one of MODES.
2425Uses the `derived-mode-parent' property of the symbol to trace backwards."
2426 (let ((parent major-mode))
2427 (while (and (not (memq parent modes)) (setq parent (get parent 'derived-mode-parent))))
2428 parent)))
2429
2430(defun diredp-ensure-mode ()
2431 "Raise an error if not in Dired or a mode derived from it."
2432 (unless (derived-mode-p 'dired-mode)
2433 (error "You must be in Dired or a mode derived from it to use this command")))
2434
2435(defun diredp-ensure-bookmark+ ()
2436 (unless (require 'bookmark+ nil t) (error "This command requires library `bookmark+.el'")))
2437
2438
2439(unless (fboundp 'dired-nondirectory-p) ; Emacs 20, 21.
2440 (defun dired-nondirectory-p (file)
2441 "Return non-nil if FILE is not a directory."
2442 (not (file-directory-p file))))
2443
2444
2445;;; Some of the redefinitions that follow are essentially unaltered vanilla Emacs code to be
2446;;; reloaded, to use the new definition of `dired-map-over-marks' here.
2447
2448
2449;; REPLACE ORIGINAL in `dired.el'.
2450;;
2451;; 1. Pass non-nil second arg to `dired-get-filename' so we can include `.' and `..'.
2452;; 2. Doc string is updated to reflect the new ARG behavior.
2453;; 3. Allow, unlike vanilla Emacs, use of FILTER and DISTINGUISH-ONE-MARKED together.
2454;;
2455(defun dired-get-marked-files (&optional localp arg filter distinguish-one-marked error-if-none-p)
2456 "Return names of the marked files and directories as a list of strings.
2457The list is in the same order as the buffer, that is, the car is the
2458 first marked file.
2459Values returned are normally absolute file names.
2460Optional arg LOCALP as in `dired-get-filename'.
2461Optional second argument ARG specifies files to use instead of marked.
2462 Usually ARG comes from the command's prefix arg.
2463 If ARG is an integer, use the next ARG files (previous -ARG, if < 0).
2464 If ARG is a cons with element 16, 64, or 256, corresponding to
2465 `C-u C-u', `C-u C-u C-u', or `C-u C-u C-u C-u', then use all files
2466 in the Dired buffer, where:
2467 16 includes NO directories (including `.' and `..')
2468 64 includes directories EXCEPT `.' and `..'
2469 256 includes ALL directories (including `.' and `..')
2470 If ARG is otherwise non-nil, use the current file.
2471Optional third argument FILTER, if non-nil, is a function to select
2472 some of the files: those for which (funcall FILTER FILENAME) is
2473 non-nil.
2474If DISTINGUISH-ONE-MARKED is non-nil, then return (t FILENAME) instead
2475 of (FILENAME) if only one file is marked (after any filtering by
2476 FILTER).
2477If ERROR-IF-NONE-P is non-nil, signal an error if the list of files is
2478 empty. If ERROR-IF-NONE-P is a string then it is the error message.
2479
2480Note that the Dired+ version of this function differs from the vanilla
2481version in these respects:
2482
2483* There are more possibilities for argument ARG (prefix argument).
2484* Directories `.' and `..' can be included as marked.
2485* You can use arguments FILTER and DISTINGUISH-ONE-MARKED together."
2486 (let ((all (delq nil (save-excursion (dired-map-over-marks (dired-get-filename localp 'NO-ERROR-IF-NOT-FILEP)
2487 arg
2488 nil
2489 distinguish-one-marked))))
2490 result)
2491 (if (and distinguish-one-marked (eq (car all) t))
2492 (if (not filter)
2493 all
2494 (and (funcall filter (cadr all)) (list t (cadr all))))
2495 (dolist (file all)
2496 (when (or (not filter) (funcall filter file)) (push file result)))
2497 (when (and (null result) error-if-none-p)
2498 (diredp-user-error (if (stringp error-if-none-p) error-if-none-p "No files specified")))
2499 (if (and distinguish-one-marked (= 1 (length result)))
2500 (cons t result)
2501 result))))
2502
2503
2504;; REPLACE ORIGINAL in `dired-aux.el'.
2505;;
2506(defun dired-map-over-marks-check (fun arg op-symbol &optional show-progress)
2507 "Map FUN over marked lines and display failures.
2508FUN takes zero args. It returns non-nil (the offending object, e.g.
2509the short form of the filename) for a failure and probably logs a
2510detailed error explanation using function `dired-log'.
2511
2512ARG is as in `dired-map-over-marks'.
2513
2514OP-SYMBOL is a symbol describing the operation performed (e.g.
2515`compress'). It is used with `dired-mark-pop-up' to prompt the user
2516\(e.g. with `Compress * [2 files]? ') and to display errors (e.g.
2517`Failed to compress 1 of 2 files - type W to see why (\"foo\")')
2518
2519SHOW-PROGRESS if non-nil means redisplay Dired after each file."
2520 (and (dired-mark-confirm op-symbol arg)
2521 (let* ((total-list (dired-map-over-marks (funcall fun) arg show-progress)) ; Return vals.
2522 (total (length total-list))
2523 (failures (delq nil total-list))
2524 (count (length failures))
2525 (string (if (eq op-symbol 'compress)
2526 "Compress or uncompress"
2527 (capitalize (symbol-name op-symbol)))))
2528 (if (not failures)
2529 (message "%s: %d file%s." string total (dired-plural-s total))
2530 ;; end this bunch of errors:
2531 (dired-log-summary (format "Failed to %s %d of %d file%s"
2532 (downcase string) count total (dired-plural-s total))
2533 failures)))))
2534
2535
2536;; REPLACE ORIGINAL in `dired-aux.el'.
2537;;
2538(when (boundp 'dired-subdir-switches) ; Emacs 22+
2539 (defun dired-do-redisplay (&optional arg test-for-subdir) ; Bound to `l'
2540 "Redisplay all marked (or next ARG) files.
2541If on a subdir line, redisplay that subdirectory. In that case,
2542a prefix arg lets you edit the `ls' switches used for the new listing.
2543
2544Dired remembers switches specified with a prefix arg, so that reverting
2545the buffer will not reset them. However, using `dired-undo' to re-insert
2546or delete subdirectories can bypass this machinery. Hence, you sometimes
2547may have to reset some subdirectory switches after a `dired-undo'.
2548You can reset all subdirectory switches to the default using
2549\\<dired-mode-map>\\[dired-reset-subdir-switches].
2550See Info node `(emacs)Subdir switches' for more details."
2551 ;; Moves point if the next ARG files are redisplayed.
2552 (interactive "P\np")
2553 (if (and test-for-subdir (dired-get-subdir))
2554 (let* ((dir (dired-get-subdir))
2555 (switches (cdr (assoc-string dir dired-switches-alist))))
2556 (dired-insert-subdir dir (and arg (read-string "Switches for listing: "
2557 (or switches
2558 dired-subdir-switches
2559 dired-actual-switches)))))
2560 (message "Redisplaying...")
2561 ;; `message' is much faster than making `dired-map-over-marks' show progress
2562 (dired-uncache (if (consp dired-directory) (car dired-directory) dired-directory))
2563 (dired-map-over-marks (let ((fname (dired-get-filename))
2564 ;; Postpone readin hook map over all marked files (Bug#6810).
2565 (dired-after-readin-hook nil))
2566 (message "Redisplaying... `%s'" fname)
2567 (dired-update-file-line fname))
2568 arg)
2569 (run-hooks 'dired-after-readin-hook)
2570 (dired-move-to-filename)
2571 (message "Redisplaying...done"))))
2572
2573
2574;; REPLACE ORIGINAL in `dired-aux.el'.
2575;;
2576(unless (boundp 'dired-subdir-switches) ; Emacs 20, 21
2577 (defun dired-do-redisplay (&optional arg test-for-subdir) ; Bound to `l'
2578 "Redisplay all marked (or next ARG) files.
2579If on a subdir line, redisplay that subdirectory. In that case,
2580a prefix arg lets you edit the `ls' switches used for the new listing."
2581 ;; Moves point if the next ARG files are redisplayed.
2582 (interactive "P\np")
2583 (if (and test-for-subdir (dired-get-subdir))
2584 (dired-insert-subdir (dired-get-subdir)
2585 (and arg (read-string "Switches for listing: " dired-actual-switches)))
2586 (message "Redisplaying...")
2587 ;; `message' is much faster than making dired-map-over-marks show progress
2588 (dired-uncache (if (consp dired-directory) (car dired-directory) dired-directory))
2589 (dired-map-over-marks (let ((fname (dired-get-filename)))
2590 (message "Redisplaying... `%s'" fname)
2591 (dired-update-file-line fname))
2592 arg)
2593 (dired-move-to-filename)
2594 (message "Redisplaying...done"))))
2595
2596
2597;; REPLACE ORIGINAL in `dired.el'.
2598;;
2599(when (fboundp 'get-window-with-predicate) ; Emacs 22+
2600 (defun dired-dwim-target-directory ()
2601 "Guess a target directory to use for Dired.
2602If there is a Dired buffer displayed in another window, use its
2603current subdir, else use current subdir of this Dired buffer."
2604 (let ((this-dir (and (eq major-mode 'dired-mode) (dired-current-directory))))
2605 ;; Non-dired buffer may want to profit from this function, e.g. `vm-uudecode'.
2606 (if dired-dwim-target
2607 (let* ((other-win (get-window-with-predicate (lambda (window)
2608 (with-current-buffer (window-buffer window)
2609 (eq major-mode 'dired-mode)))
2610 nil
2611 (and diredp-dwim-any-frame-flag 'visible)))
2612 (other-dir (and other-win (with-current-buffer (window-buffer other-win)
2613 (and (eq major-mode 'dired-mode) (dired-current-directory))))))
2614 (or other-dir this-dir))
2615 this-dir))))
2616
2617
2618;; REPLACE ORIGINAL in `dired.el'.
2619;;
2620;; 1. Added behavior for non-positive prefix arg:
2621;; * Construct a cons DIRNAME arg.
2622;; * Read a Dired buffer name (not a directory) for its car.
2623;; * If READ-EXTRA-FILES-P is non-nil then read any number of file and dir names, to be included as its cdr.
2624;; * If chosen Dired buffer exists and is an ordinary listing then start out with its `directory-files'.
2625;;
2626;; 2. If you use Icicles then this is a multi-command - see doc for `dired' defadvice.
2627;;
2628(defun dired-read-dir-and-switches (string &optional read-extra-files-p dired-buffer)
2629 "Read arguments for `dired' commands.
2630STRING is added to the prompt after \"Dired \". If not \"\", it should
2631end with a space.
2632
2633With a non-negative prefix arg, read the `ls' switches.
2634With a non-negative prefix arg or none, read the directory to Dired.
2635
2636With a non-positive prefix arg:
2637* If DIRED-BUFFER is non-nil, it is the name of the Dired buffer to
2638 use. Otherwise, read it (it is not necessarily a directory name).
2639 If in Dired now, the current buffer name is the default.
2640* If READ-EXTRA-FILES-P is non-nil then read any number of directory
2641 or file names, to make up the Dired arbitrary-files listing. You
2642 can use file-name wildcards (i.e., `*' for globbing), to include the
2643 matching files and directories. Use `C-g' when done entering the
2644 files and directories to list.
2645
2646Return a list of arguments for `dired': (DIRNAME SWITCHES). DIRNAME
2647here has the same form as `dired-directory'. When a non-positive
2648prefix arg is used, DIRNAME is a cons of the buffer name and the list
2649of file names.
2650
2651If you use Icicles then reading uses Icicles completion, with
2652additional multi-command keys. See `dired' (defadvice doc)."
2653 (let* ((switchs (and current-prefix-arg
2654 (natnump (prefix-numeric-value current-prefix-arg))
2655 (read-string "Dired listing switches: "
2656 dired-listing-switches)))
2657 (icicle-candidate-action-fn
2658 (lambda (cand)
2659 (dired-other-window cand (and current-prefix-arg (read-string "Dired listing switches: "
2660 dired-listing-switches)))
2661 (select-window (minibuffer-window))
2662 (select-frame-set-input-focus (selected-frame))))
2663;;; $$$$$$ Alternative: Could choose no-op for non-dir candidate.
2664;;; (icicle-candidate-action-fn
2665;;; (lambda (cand)
2666;;; (cond ((file-directory-p cand)
2667;;; (dired-other-window cand (and current-prefix-arg (read-string "Dired listing switches: "
2668;;; dired-listing-switches)))
2669;;; (select-window (minibuffer-window))
2670;;; (select-frame-set-input-focus (selected-frame)))
2671;;; (t
2672;;; (message "Not a directory: `%s'" cand) (sit-for 2)))))
2673 (icicle-all-candidates-list-alt-action-fn ; M-|'
2674 (lambda (files)
2675 (let ((enable-recursive-minibuffers t))
2676 (dired-other-window (cons (read-string (format "Dired %s(buffer name): " string)) files)))))
2677 (icicle-sort-comparer (or (and (boundp 'icicle-file-sort) ; If not reading files
2678 icicle-file-sort) ; then dirs first.
2679 (and (> (prefix-numeric-value current-prefix-arg) 0)
2680 'icicle-dirs-first-p)
2681 (and (boundp 'icicle-sort-comparer)
2682 icicle-sort-comparer)))
2683
2684 ;; The rest of the bindings are from `icicle-file-bindings', in `icicles-mac.el'.
2685 (completion-ignore-case
2686 (or (and (boundp 'read-file-name-completion-ignore-case) read-file-name-completion-ignore-case)
2687 completion-ignore-case))
2688 (icicle-show-Completions-initially-flag (and (boundp 'icicle-show-Completions-initially-flag)
2689 (or icicle-show-Completions-initially-flag
2690 icicle-files-ido-like-flag)))
2691 (icicle-top-level-when-sole-completion-flag (and (boundp 'icicle-top-level-when-sole-completion-flag)
2692 (or icicle-top-level-when-sole-completion-flag
2693 icicle-files-ido-like-flag)))
2694 (icicle-default-value (and (boundp 'icicle-default-value)
2695 (if (and icicle-files-ido-like-flag
2696 icicle-default-value)
2697 icicle-files-ido-like-flag
2698 ;; Get default via `M-n', but do not insert it.
2699 (and (memq icicle-default-value '(t nil))
2700 icicle-default-value))))
2701 (icicle-must-match-regexp (and (boundp 'icicle-file-match-regexp)
2702 icicle-file-match-regexp))
2703 (icicle-must-not-match-regexp (and (boundp 'icicle-file-no-match-regexp)
2704 icicle-file-no-match-regexp))
2705 (icicle-must-pass-after-match-predicate (and (boundp 'icicle-file-predicate)
2706 icicle-file-predicate))
2707 (icicle-require-match-flag (and (boundp 'icicle-file-require-match-flag)
2708 icicle-file-require-match-flag))
2709 (icicle-file-completing-p t)
2710 (icicle-extra-candidates (and (boundp 'icicle-file-extras) icicle-file-extras))
2711 (icicle-transform-function 'icicle-remove-dups-if-extras)
2712 ;; Put `icicle-file-sort' first. If already in the list, move it, else add it, to beginning.
2713 (icicle--temp-orders (and (boundp 'icicle-sort-orders-alist)
2714 (copy-sequence icicle-sort-orders-alist)))
2715 (icicle-candidate-help-fn (lambda (cand)
2716 (icicle-describe-file cand current-prefix-arg t)))
2717 (icicle-candidate-alt-action-fn (and (boundp 'icicle-candidate-alt-action-fn)
2718 (or icicle-candidate-alt-action-fn
2719 (icicle-alt-act-fn-for-type "file"))))
2720 (icicle-delete-candidate-object 'icicle-delete-file-or-directory)
2721 (icicle-sort-orders-alist
2722 (and (boundp 'icicle-sort-orders-alist)
2723 (progn (when (and icicle-file-sort-first-time-p icicle-file-sort)
2724 (setq icicle-sort-comparer icicle-file-sort
2725 icicle-file-sort-first-time-p nil))
2726 (if icicle-file-sort
2727 (let ((already-there (rassq icicle-file-sort icicle--temp-orders)))
2728 (if already-there
2729 (cons already-there (setq icicle--temp-orders (delete already-there
2730 icicle--temp-orders)))
2731 (cons `("by `icicle-file-sort'" ,@icicle-file-sort) icicle--temp-orders)))
2732 icicle--temp-orders)))))
2733 (when (fboundp 'icicle-bind-file-candidate-keys) (icicle-bind-file-candidate-keys))
2734 (unwind-protect
2735 (list
2736 (if (> (prefix-numeric-value current-prefix-arg) 0)
2737 ;; If a dialog box is about to be used, call `read-directory-name' so the dialog
2738 ;; code knows we want directories. Some dialog boxes can only select directories
2739 ;; or files when popped up, not both. If no dialog box is used, call `read-file-name'
2740 ;; because the user may want completion of file names for use in a wildcard pattern.
2741 (funcall (if (and (fboundp 'read-directory-name) (next-read-file-uses-dialog-p))
2742 #'read-directory-name
2743 #'read-file-name)
2744 (format "Dired %s(directory): " string) nil default-directory nil)
2745 (dolist (db dired-buffers) ; Remove any killed buffers from `dired-buffers' (even if DIRED-BUFFER).
2746 (unless (buffer-name (cdr db)) (setq dired-buffers (delq db dired-buffers))))
2747 (let* ((dbufs (and (not dired-buffer)
2748 (mapcar (lambda (db) (list (buffer-name (cdr db)))) dired-buffers)))
2749 (dirbuf (or dired-buffer
2750 (completing-read (format "Dired %s(buffer name): " string) dbufs nil nil nil nil
2751 (and (derived-mode-p 'dired-mode) (buffer-name)))))
2752 (files (and (diredp-existing-dired-buffer-p dirbuf)
2753 (with-current-buffer (get-buffer dirbuf)
2754 (and (not (consp dired-directory))
2755 (directory-files dired-directory 'FULL diredp-re-no-dot)))))
2756 file)
2757 (when read-extra-files-p
2758 (while (condition-case nil ; Use lax completion, to allow wildcards.
2759 (setq file (read-file-name "File or dir (C-g when done): "))
2760 (quit nil))
2761 ;; Do not allow root dir (`/' or a Windows drive letter, e.g. `d:/').
2762 (if (diredp-root-directory-p file)
2763 (progn (message "Cannot choose root directory") (sit-for 1))
2764 (push file files))))
2765 (cons dirbuf files)))
2766 switchs)
2767 (when (fboundp 'icicle-unbind-file-candidate-keys) (icicle-unbind-file-candidate-keys)))))
2768
2769
2770;;; $$$$$$$$ An alternative implementation - different behavior.
2771;;;
2772;;; ;; REPLACE ORIGINAL in `dired.el'.
2773;;; ;;
2774;;; ;; Non-positive prefix arg means construct cons DIRNAME arg: Read Dired name and files/dirs.
2775;;; ;;
2776;;; (defun dired-read-dir-and-switches (string)
2777;;; "Read arguments for `dired'.
2778;;; With a non-negative prefix arg, prompt first for `ls' switches.
2779;;; With a non-positive prefix arg, read the Dired buffer name and then
2780;;; read any number of dir or file names, to make up the Dired listing.
2781
2782;;; STRING is appended to the prompt, unless prefix arg is non-positive.
2783;;; If non-empty, STRING should begin with a SPC."
2784;;; (let ((switches (and current-prefix-arg
2785;;; (>= (prefix-numeric-value current-prefix-arg) 0)
2786;;; (read-string "Dired listing switches: " dired-listing-switches)))
2787;;; (formt (format "Dired %s(directory): " string))
2788;;; (entries ())
2789;;; (curr-entry ""))
2790;;; (when (and current-prefix-arg (<= (prefix-numeric-value current-prefix-arg) 0))
2791;;; (push (completing-read "Dired buffer name: " dired-buffers) entries)
2792;;; (setq curr-entry (read-file-name (format "Dir or file: ") nil "" 'MUST-MATCH))
2793;;; (while (not (equal "" curr-entry))
2794;;; (push curr-entry entries)
2795;;; (setq curr-entry (read-file-name (format "Dir or file: ") nil "" 'MUST-MATCH)))
2796;;; (unless (cadr entries) (push default-directory entries)))
2797;;; (list (or (nreverse entries) (if (and (fboundp 'next-read-file-uses-dialog-p)
2798;;; (next-read-file-uses-dialog-p))
2799;;; (read-directory-name formt nil default-directory nil)
2800;;; (read-file-name formt nil default-directory nil)))
2801;;; switches)))
2802
2803
2804;; ADVISE ORIGINAL in `dired.el'.
2805;;
2806;; Add to doc string, to document non-positive prefix arg.
2807;;
2808(defadvice dired (before diredp-doc-cons-arg activate)
2809 "Interactively, a prefix argument changes the behavior as follows:
2810
2811* If >= 0, you are first prompted for the `ls' switches to use.
2812
2813* If <= 0, you are prompted first for the name of the Dired buffer.
2814 Then you are prompted repeatedly for the names of the directories
2815 or files to list in the buffer. You can use file-name wildcards
2816 (i.e., `*' for globbing), to include the matching files and
2817 directories. Use `C-g' to end.
2818
2819 In other words, instead of listing a single directory, the Dired
2820 buffer can list any number of directories and file names, which can
2821 even belong to different directory trees.
2822
2823The rest of this description applies only if you use Icicles.
2824
2825In Icicle mode this is a multi-command: You can cycle among file-name
2826completion candidates and act individually on those that name
2827directories. The action is to open Dired for the directory. While
2828cycling, these keys are active:
2829
2830\\<minibuffer-local-completion-map>\
2831`C-mouse-2', `C-return' - Act on current completion candidate only
2832`C-down', `C-wheel-down' - Move to next completion candidate and act
2833`C-up', `C-wheel-up' - Move to previous completion candidate and act
2834`C-next' - Move to next apropos-completion candidate and act
2835`C-prior' - Move to previous apropos-completion candidate and act
2836`C-end' - Move to next prefix-completion candidate and act
2837`C-home' - Move to previous prefix-completion candidate and act
2838`\\[icicle-all-candidates-action]' - Act on *all* candidates, successively (careful!)
2839`\\[icicle-all-candidates-list-alt-action]' - Open Dired on all candidates
2840
2841When candidate action and cycling are combined (e.g. `C-next'), user
2842option `icicle-act-before-cycle-flag' determines which occurs first.
2843
2844With prefix `C-M-' instead of `C-', the same keys (`C-M-mouse-2',
2845`C-M-RET', `C-M-down', and so on) provide help about candidates.
2846
2847Use `mouse-2', `RET', or `S-RET' to finally choose a candidate, or
2848`C-g' to quit.
2849
2850These keys are also bound in the minibuffer during completion (`*'
2851means the key requires library `Bookmark+'):
2852
2853 S-delete - Delete candidate file or (empty) dir
2854 C-c + - Create a new directory
2855 C-backspace - Go up one directory level
2856 * C-x C-t * - Narrow to files with all of the tags you specify
2857 * C-x C-t + - Narrow to files with some of the tags you specify
2858 * C-x C-t % * - Narrow to files with all tags matching a regexp
2859 * C-x C-t % + - Narrow to files with some tags matching a regexp
2860 * C-x a + - Add tags to the current-candidate file
2861 * C-x a - - Remove tags from the current-candidate file
2862 * C-x m - Access file bookmarks (not just autofiles)"
2863 (interactive (dired-read-dir-and-switches "" 'READ-EXTRA-FILES-P)))
2864
2865
2866;; ADVISE ORIGINAL in `dired.el'.
2867;;
2868;; Add to doc string, to document non-positive prefix arg.
2869;;
2870(defadvice dired-other-window (before diredp-doc-cons-arg activate)
2871 "Interactively, a prefix argument changes the behavior.
2872A non-positive prefix arg lets you choose an explicit set of files and
2873directories to list. See the advice for `dired' for more information."
2874 (interactive (dired-read-dir-and-switches "" 'READ-EXTRA-FILES-P)))
2875
2876
2877;; ADVISE ORIGINAL in `dired.el'.
2878;;
2879;; Add to doc string, to document non-positive prefix arg.
2880;;
2881(defadvice dired-other-frame (before diredp-doc-cons-arg activate)
2882 "Interactively, a prefix argument changes the behavior.
2883A non-positive prefix arg lets you choose an explicit set of files and
2884directories to list. See the advice for `dired' for more information."
2885 (interactive (dired-read-dir-and-switches "" 'READ-EXTRA-FILES-P)))
2886
2887
2888;; REPLACE ORIGINAL in `dired.el'.
2889;;
2890;; Made compatible with Emacs 20, 21, which do not have [:alnum].
2891;; Also, this is defined here because it is used elsewhere in the file.
2892;;
2893(defun dired-switches-escape-p (switches)
2894 "Return non-nil if the string SWITCHES contains `-b' or `--escape'."
2895 (if (fboundp 'dired-switches-check) ; Emacs 24.4+ - see Emacs bug #17218.
2896 (dired-switches-check switches "escape" "b")
2897 ;; Do not match things like "--block-size" that happen to contain "b".
2898 (if (> emacs-major-version 21) ; SWITCHES must be a string here, not nil.
2899 (diredp-string-match-p "\\(\\`\\| \\)-[[:alnum:]]*b\\|--escape\\>" switches)
2900 (diredp-string-match-p "\\(\\`\\| \\)-\\(\w\\|[0-9]\\)*b\\|--escape\\>" switches))))
2901
2902
2903;; From `dired.el'
2904
2905(when (and (> emacs-major-version 22) (featurep 'ls-lisp+))
2906
2907;;; 2012/04/26: Commented this out.
2908;;; Might need it again when update `ls-lisp+.el' to fix other things.
2909;;;
2910;;; ;; Use t as WILDCARD arg to `dired-insert-directory'.
2911;;; ;;
2912;;; (defun dired-readin-insert ()
2913;;; ;; Insert listing for the specified dir (and maybe file list)
2914;;; ;; already in dired-directory, assuming a clean buffer.
2915;;; (let (dir file-list)
2916;;; (if (consp dired-directory)
2917;;; (setq dir (car dired-directory)
2918;;; file-list (cdr dired-directory))
2919;;; (setq dir dired-directory
2920;;; file-list ()))
2921;;; (setq dir (expand-file-name dir))
2922;;; (if (and (equal "" (file-name-nondirectory dir)) (not file-list))
2923;;; ;; If we are reading a whole single directory...
2924;;; (dired-insert-directory dir dired-actual-switches nil nil t)
2925;;; (unless (file-readable-p (directory-file-name (file-name-directory dir)))
2926;;; (error "Directory `%s' inaccessible or nonexistent" dir))
2927;;; ;; Else treat it as a wildcard spec.
2928;;; (dired-insert-directory dir dired-actual-switches file-list t t))))
2929
2930
2931 ;; REPLACE ORIGINAL in `dired.el'.
2932 ;;
2933 ;; Compute WILDCARD arg for `insert-directory' for individual file (don't just use nil).
2934 ;;
2935 (defun dired-insert-directory (dir switches &optional file-list wildcard hdr)
2936 "Insert a directory listing of DIR, Dired style.
2937Use SWITCHES to make the listings.
2938If FILE-LIST is non-nil, list only those files.
2939Otherwise, if WILDCARD is non-nil, expand wildcards;
2940 in that case, DIR should be a file name that uses wildcards.
2941In other cases, DIR should be a directory name or a directory filename.
2942If HDR is non-nil, insert a header line with the directory name."
2943 (let ((opoint (point))
2944 (process-environment (copy-sequence process-environment))
2945 end)
2946 (when (and
2947 ;; Do not try to invoke `ls' if on DOS/Windows, where `ls-lisp' is used, unless
2948 ;; the user really wants to use `ls', as indicated by
2949 ;; `ls-lisp-use-insert-directory-program'.
2950 (or (not (featurep 'ls-lisp)) ls-lisp-use-insert-directory-program)
2951 (or (if (eq dired-use-ls-dired 'unspecified)
2952 ;; Check if "ls --dired" gives exit code 0. Put it in `dired-use-ls-dired'.
2953 (or (setq dired-use-ls-dired (eq 0 (call-process insert-directory-program
2954 nil nil nil "--dired")))
2955 (progn (message "Command `ls' does not support switch `--dired' - see \
2956`dired-use-ls-dired'.")
2957 nil))
2958 dired-use-ls-dired)
2959 (file-remote-p dir)))
2960 (setq switches (concat "--dired " switches)))
2961 ;; We used to specify the C locale here, to force English month names. This should not be
2962 ;; necessary any more with the new value of `directory-listing-before-filename-regexp'.
2963 (if file-list
2964 (dolist (f file-list)
2965 (let ((beg (point)))
2966 ;; Compute wildcard arg for this file.
2967 (insert-directory f switches (diredp-string-match-p "[[?*]" f) nil)
2968 ;; Re-align fields, if necessary.
2969 (dired-align-file beg (point))))
2970 (insert-directory dir switches wildcard (not wildcard)))
2971 ;; Quote certain characters, unless `ls' quoted them for us.
2972 (unless (dired-switches-escape-p dired-actual-switches)
2973 (save-excursion
2974 (setq end (point-marker))
2975 (goto-char opoint)
2976 (while (search-forward "\\" end t)
2977 (replace-match (apply #'propertize "\\\\" (text-properties-at (match-beginning 0)))
2978 nil t))
2979 (goto-char opoint)
2980 (while (search-forward "\^m" end t)
2981 (replace-match (apply #'propertize "\\015" (text-properties-at (match-beginning 0)))
2982 nil t))
2983 (set-marker end nil))
2984 ;; Comment in original, from some Emacs Dev developer:
2985 ;;
2986 ;; Replace any newlines in DIR with literal "\n" for the sake of the header line. To
2987 ;; disambiguate a literal "\n" in the actual dirname, we also replace "\" with "\\".
2988 ;; I think this should always be done, irrespective of the value of
2989 ;; dired-actual-switches, because:
2990 ;; i) Dired does not work with an unescaped newline in the directory name used in the
2991 ;; header (bug=10469#28), and
2992 ;; ii) "\" is always replaced with "\\" in the listing, so doing it in the header as
2993 ;; well makes things consistent.
2994 ;; But at present it is done only if "-b" is in ls-switches, because newlines in dirnames
2995 ;; are uncommon, and people may have gotten used to seeing unescaped "\" in the headers.
2996 ;; Note: adjust `dired-build-subdir-alist' if you change this.
2997 (setq dir (replace-regexp-in-string "\\\\" "\\\\" dir nil t)
2998 dir (replace-regexp-in-string "\n" "\\n" dir nil t)))
2999 ;; If we used `--dired' and it worked, the lines are already indented. Else indent them.
3000 (unless (save-excursion (goto-char opoint) (diredp-looking-at-p " "))
3001 (let ((indent-tabs-mode nil)) (indent-rigidly opoint (point) 2)))
3002 ;; Insert text at the beginning to standardize things.
3003 (let ((content-point opoint))
3004 (save-excursion
3005 (goto-char opoint)
3006 (when (and (or hdr wildcard) (not (and (looking-at "^ \\(.*\\):$")
3007 (file-name-absolute-p (match-string 1)))))
3008 ;; `dired-build-subdir-alist' will replace the name by its expansion, so it does not
3009 ;; matter whether what we insert here is fully expanded, but it should be absolute.
3010 (insert " " (directory-file-name (file-name-directory dir)) ":\n")
3011 (setq content-point (point)))
3012 (when wildcard
3013 ;; Insert "wildcard" line where "total" line would be for a full dir.
3014 (insert " wildcard " (file-name-nondirectory dir) "\n")))
3015 (dired-insert-set-properties content-point (point))))))
3016
3017
3018;;; Image stuff.
3019
3020(defun diredp-image-dired-required-msg ()
3021 "Raise an error if `image-dired.el' is not loaded."
3022 (unless (require 'image-dired nil t) (error "This command requires library `image-dired.el'")))
3023
3024;; See `image-dired-create-thumb'.
3025;; Define this even if `image-dired.el' is not loaded.
3026;; Do NOT raise an error if not loaded, because this is used in `diredp-mouseover-help'.
3027;;;###autoload
3028(defun diredp-image-dired-create-thumb (file &optional arg)
3029 "Create thumbnail image file for FILE (default: file on current line).
3030With a prefix arg, replace any existing thumbnail for FILE.
3031With a numeric prefix arg (not a cons), use it as the thumbnail size.
3032Return the name of the thumbnail image file, or nil if none."
3033 (interactive (list (if (derived-mode-p 'dired-mode)
3034 (dired-get-filename nil 'NO-ERROR)
3035 ;; Make it work also for `diredp-list-files' listings.
3036 (buffer-substring-no-properties (line-beginning-position) (line-end-position)))
3037 current-prefix-arg))
3038 (and (fboundp 'image-dired-thumb-name) ; No-op (return nil) if `image-dired.el' not loaded.
3039 (let ((thumb-name (image-dired-thumb-name file)))
3040 (when arg (clear-image-cache))
3041 (when (or arg (not (file-exists-p thumb-name)))
3042 (let ((image-dired-thumb-width (or (and arg (atom arg) arg) image-dired-thumb-width))
3043 (image-dired-thumb-height (or (and arg (atom arg) arg) image-dired-thumb-height)))
3044 (unless (zerop (image-dired-create-thumb file thumb-name))
3045 (error "Thumbnail image file could not be created"))))
3046 (and (file-exists-p thumb-name) thumb-name))))
3047
3048
3049;; REPLACE ORIGINAL in `image-dired.el' (Emacs 22-23).
3050;;
3051;; 1. Raise an error if `image-dired.el' is not available.
3052;; 2. Repro it here so it picks up `Dired+' version of `dired-map-over-marks'.
3053;;
3054;;;###autoload
3055(defun image-dired-dired-insert-marked-thumbs () ; Bound to `C-t C-t' (Emacs 22-23)
3056 "Insert thumbnails before file names of marked files in the Dired buffer."
3057 (interactive (progn (diredp-image-dired-required-msg) ()))
3058 (dired-map-over-marks
3059 (let* ((image-pos (dired-move-to-filename))
3060 (image-file (dired-get-filename))
3061 (thumb-file (image-dired-get-thumbnail-image image-file))
3062 overlay)
3063 ;; If image is not already added, then add it.
3064 (unless (delq nil (mapcar (lambda (o) (overlay-get o 'put-image))
3065 ;; Can't use (overlays-at (point)), BUG?
3066 (overlays-in (point) (1+ (point)))))
3067 (put-image thumb-file image-pos)
3068 (setq overlay (car (delq nil (mapcar (lambda (ov) (and (overlay-get ov 'put-image) ov))
3069 (overlays-in (point) (1+ (point)))))))
3070 (overlay-put overlay 'image-file image-file)
3071 (overlay-put overlay 'thumb-file thumb-file)))
3072 nil)
3073 (add-hook 'dired-after-readin-hook 'image-dired-dired-after-readin-hook nil t))
3074
3075
3076;; REPLACE ORIGINAL in `image-dired.el' (Emacs 24+).
3077;;
3078;; 1. Raise an error if `image-dired.el' is not available.
3079;; 2. Repro it here so it picks up `Dired+' version of `dired-map-over-marks'.
3080;;
3081;;;###autoload
3082(defun image-dired-dired-toggle-marked-thumbs (&optional arg) ; Bound to `C-t C-t' (Emacs 24+)
3083 "Toggle thumbnails in front of file names in Dired.
3084If no files are marked, insert or hide thumbnails on the current line.
3085With a numeric prefix arg N, ignore marked files and act on the next N
3086files (previous -N files, if N < 0)."
3087 (interactive (progn (diredp-image-dired-required-msg) (list current-prefix-arg)))
3088 (dired-map-over-marks
3089 (let* ((image-pos (dired-move-to-filename))
3090 (image-file (diredp-get-image-filename nil 'NO-ERROR))
3091 thumb-file overlay)
3092 (when image-file
3093 (setq thumb-file (image-dired-get-thumbnail-image image-file))
3094 ;; If image is not already added, then add it.
3095 (let* ((cur-ovs (overlays-in (point) (1+ (point))))
3096 (thumb-ov (car (diredp-remove-if-not (lambda (ov) (overlay-get ov 'thumb-file))
3097 cur-ovs))))
3098 (if thumb-ov
3099 (delete-overlay thumb-ov)
3100 (put-image thumb-file image-pos)
3101 (setq overlay (car (delq nil (mapcar (lambda (ov) (and (overlay-get ov 'put-image) ov))
3102 (overlays-in (point) (1+ (point)))))))
3103 (overlay-put overlay 'image-file image-file)
3104 (overlay-put overlay 'thumb-file thumb-file)))))
3105 arg
3106 'SHOW-PROGRESS)
3107 (add-hook 'dired-after-readin-hook 'image-dired-dired-after-readin-hook nil t))
3108
3109;; Corresponds to `image-dired-dired-comment-files'.
3110;;;###autoload
3111(defun diredp-image-dired-comment-file ()
3112 "Add comment to this image file."
3113 (interactive (progn (diredp-image-dired-required-msg) ()))
3114 (image-dired-write-comments (cons (dired-get-filename) (image-dired-read-comment))))
3115
3116;; Corresponds to `image-dired-tag-files'.
3117;;;###autoload
3118(defun diredp-image-dired-tag-file ()
3119 "Tag this image file with an `image-dired' tag."
3120 (interactive (progn (diredp-image-dired-required-msg) ()))
3121 (image-dired-write-tags (cons (dired-get-filename)
3122 (read-string "Tags to add (use `;' to separate): "))))
3123
3124;; Corresponds to `image-dired-delete-tag'.
3125;;;###autoload
3126(defun diredp-image-dired-delete-tag ()
3127 "Remove an `image-dired' tag from this image file."
3128 (interactive (progn (diredp-image-dired-required-msg) ()))
3129 (image-dired-remove-tag (list (dired-get-filename)) (read-string "Tag to remove: ")))
3130
3131;; Corresponds to `image-dired-display-thumbs'.
3132;;;###autoload
3133(defun diredp-image-dired-display-thumb (&optional append)
3134 "Pop to thumbnail of this image file, in `image-dired-thumbnail-buffer'.
3135If a thumbnail image does not yet exist for this file, create it.
3136With a prefix arg, append the thumbnail to the thumbnails buffer,
3137instead of clearing the buffer first."
3138 (interactive (progn (diredp-image-dired-required-msg) (list current-prefix-arg)))
3139 (let* ((dired-buf (current-buffer))
3140 (curr-file (dired-get-filename))
3141 (thumb-name (image-dired-thumb-name curr-file)))
3142 (with-current-buffer (image-dired-create-thumbnail-buffer)
3143 (let ((inhibit-read-only t))
3144 (if (not append) (erase-buffer) (goto-char (point-max)))
3145 (if (and (not (file-exists-p thumb-name))
3146 (not (zerop (image-dired-create-thumb curr-file thumb-name))))
3147 (message "Cannot create thumbnail image for file `%s'" curr-file)
3148 (image-dired-insert-thumbnail thumb-name curr-file dired-buf)))
3149 (cond ((eq 'dynamic image-dired-line-up-method) (image-dired-line-up-dynamic))
3150 ((eq 'fixed image-dired-line-up-method) (image-dired-line-up))
3151 ((eq 'interactive image-dired-line-up-method) (image-dired-line-up-interactive))
3152 ((eq 'none image-dired-line-up-method) nil)
3153 (t (image-dired-line-up-dynamic))))
3154 (pop-to-buffer image-dired-thumbnail-buffer)))
3155
3156;; Corresponds to `image-dired-copy-with-exif-file-name'.
3157;;;###autoload
3158(defun diredp-image-dired-copy-with-exif-name ()
3159 "Copy this image file to your main image directory.
3160Uses `image-dired-get-exif-file-name' to name the new file."
3161 (interactive (progn (diredp-image-dired-required-msg) ()))
3162 (let* ((curr-file (dired-get-filename))
3163 (new-name (format "%s/%s" (file-name-as-directory
3164 (expand-file-name image-dired-main-image-directory))
3165 (image-dired-get-exif-file-name curr-file))))
3166 (message "Copying `%s' to `%s'..." curr-file new-name)
3167 (copy-file curr-file new-name)
3168 (message "Copying `%s' to `%s'...done" curr-file new-name)))
3169
3170;; Corresponds to `image-dired-dired-edit-comment-and-tags'.
3171;;;###autoload
3172(defun diredp-image-dired-edit-comment-and-tags ()
3173 "Edit comment and tags for this image file."
3174 (interactive (progn (diredp-image-dired-required-msg) ()))
3175 (setq image-dired-widget-list ())
3176 (let ((file (dired-get-filename)))
3177 (switch-to-buffer "*Image-Dired Edit Meta Data*")
3178 (kill-all-local-variables)
3179 (make-local-variable 'widget-example-repeat)
3180 (let ((inhibit-read-only t))
3181 (erase-buffer)
3182 (remove-overlays)
3183 (widget-insert
3184 "\nEdit comment and tags for the image. Separate multiple tags
3185with a comma (`,'). Move forward among fields using `TAB' or `RET'.
3186Move backward using `S-TAB'. Click `Save' to save your edits or
3187`Cancel' to abandon them.\n\n")
3188 (let* ((thumb-file (image-dired-thumb-name file))
3189 (img (create-image thumb-file))
3190 comment-widget tag-widget)
3191 (insert-image img)
3192 (widget-insert "\n\nComment: ")
3193 (setq comment-widget (widget-create 'editable-field :size 60 :format "%v "
3194 :value (or (image-dired-get-comment file) "")))
3195 (widget-insert "\nTags: ")
3196 (setq tag-widget (widget-create 'editable-field :size 60 :format "%v "
3197 :value (or (mapconcat #'identity (image-dired-list-tags file) ",") "")))
3198 ;; Save info in widgets to use when the user saves the form.
3199 (setq image-dired-widget-list (append image-dired-widget-list
3200 (list (list file comment-widget tag-widget))))
3201 (widget-insert "\n\n")))
3202 (widget-insert "\n")
3203 (widget-create 'push-button :notify (lambda (&rest _ignore)
3204 (image-dired-save-information-from-widgets)
3205 (bury-buffer)
3206 (message "Done"))
3207 "Save")
3208 (widget-insert " ")
3209 (widget-create 'push-button :notify (lambda (&rest _ignore)
3210 (bury-buffer)
3211 (message "Operation canceled"))
3212 "Cancel")
3213 (widget-insert "\n")
3214 (use-local-map widget-keymap)
3215 (widget-setup)
3216 (widget-forward 1))) ; Jump to the first widget.
3217
3218;;;###autoload
3219(defun diredp-do-display-images (&optional arg)
3220 "Display the marked image files.
3221A prefix argument ARG specifies files to use instead of those marked.
3222 An integer means use the next ARG files (previous -ARG, if < 0).
3223 `C-u': Use the current file (whether or not any files are marked).
3224 More than one `C-u' means use all files in the Dired buffer, as if
3225 they were all marked."
3226 (interactive (progn (unless (require 'image-file nil t)
3227 (error "This command requires library `image-file.el'"))
3228 (diredp-ensure-mode)
3229 (list current-prefix-arg)))
3230 (dired-map-over-marks-check #'diredp-display-image arg 'display\ image
3231 (diredp-fewer-than-2-files-p arg)))
3232
3233(defun diredp-display-image ()
3234 (let ((file (dired-get-filename 'LOCAL 'NO-ERROR))
3235 (failure nil))
3236 (save-excursion
3237 (if (let ((inhibit-changing-match-data t))
3238 (and file (diredp-string-match-p (image-file-name-regexp) file)))
3239 (condition-case err
3240 (let ((find-file-run-dired nil)) (find-file-other-window file))
3241 (error (setq failure (error-message-string err))))
3242 (dired-log (format "Not an image file: `%s'" file))
3243 (setq failure t)))
3244 (and failure ; Return nil for success.
3245 (prog1 file ; Return file name for failure.
3246 (unless (eq t failure) (dired-log "Cannot display image file `%s':\n%s\n" file failure) t)))))
3247
3248;;;###autoload
3249(defun diredp-image-show-this-file (&optional arg)
3250 "Show the image file named on this line in another frame or window.
3251Option `diredp-image-show-this-file-use-frame-flag' which is used.
3252
3253With a prefix arg, shrink the image to fit a frame that many lines
3254high or a window at least that many lines high.
3255Otherwise, show the image full size.
3256Note:
3257 * To show the image full size, you can also use `\\<dired-mode-map>\\[dired-find-file]'.
3258 * To show the image in another window, at whatever scale fits there,
3259 you can use `\\[image-dired-dired-display-image]'."
3260 (interactive (progn (diredp-image-dired-required-msg) (list current-prefix-arg)))
3261 (image-dired-create-display-image-buffer)
3262 (let ((fit-frame-inhibit-fitting-flag t) ; In `fit-frame.el'.
3263 (img-file (diredp-get-image-filename)))
3264 (if img-file
3265 (with-current-buffer image-dired-display-image-buffer
3266 (let* ((window-min-height (if arg
3267 (prefix-numeric-value arg)
3268 (ceiling (cdr (image-size (create-image img-file))))))
3269 (special-display-frame-alist (if diredp-image-show-this-file-use-frame-flag
3270 (cons `(height . ,window-min-height)
3271 special-display-frame-alist)
3272 special-display-frame-alist))
3273 (special-display-buffer-names (if diredp-image-show-this-file-use-frame-flag
3274 (cons image-dired-display-image-buffer
3275 special-display-buffer-names)
3276 special-display-buffer-names)))
3277 (display-buffer image-dired-display-image-buffer)
3278 (image-dired-display-image img-file (not arg))))
3279 (message "No image file here")))) ; An error is handled by `diredp-get-image-filename'.
3280
3281;;; Face Definitions
3282
3283(defface diredp-autofile-name
3284 '((((background dark)) (:background "#111313F03181")) ; Very dark blue
3285 (t (:background "#EEECEC0FCE7E"))) ; Very pale goldenrod
3286 "*Face used in Dired for names of files that are autofile bookmarks."
3287 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3288(defvar diredp-autofile-name 'diredp-autofile-name)
3289
3290(defface diredp-compressed-file-name
3291 '((((background dark)) (:foreground "Blue"))
3292 (t (:foreground "Brown")))
3293 "*Face used for compressed file names."
3294 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3295(defvar diredp-compressed-file-name 'diredp-compressed-file-name)
3296
3297(defface diredp-compressed-file-suffix
3298 '((((background dark)) (:foreground "Blue"))
3299 (t (:foreground "Yellow")))
3300 "*Face used for compressed file suffixes in Dired buffers.
3301This means the `.' plus the file extension. Example: `.zip'."
3302 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3303(defvar diredp-compressed-file-suffix 'diredp-compressed-file-suffix)
3304
3305(defface diredp-date-time
3306 '((((background dark)) (:foreground "#74749A9AF7F7")) ; ~ med blue
3307 (t (:foreground "DarkGoldenrod4")))
3308 "*Face used for date and time in Dired buffers."
3309 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3310(defvar diredp-date-time 'diredp-date-time)
3311
3312(defface diredp-deletion
3313 '((t (:foreground "Yellow" :background "Red")))
3314 "*Face used for deletion flags (D) in Dired buffers."
3315 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3316(defvar diredp-deletion 'diredp-deletion)
3317
3318(defface diredp-deletion-file-name
3319 '((t (:foreground "Red")))
3320 "*Face used for names of deleted files in Dired buffers."
3321 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3322(defvar diredp-deletion-file-name 'diredp-deletion-file-name)
3323
3324(defface diredp-dir-heading
3325 '((((background dark)) (:foreground "Yellow" :background "#00003F3F3434")) ; ~ dark green
3326 (t (:foreground "Blue" :background "Pink")))
3327 "*Face used for directory headings in Dired buffers."
3328 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3329(defvar diredp-dir-heading 'diredp-dir-heading)
3330
3331(defface diredp-dir-name
3332 '((((background dark))
3333 (:foreground "#7474FFFFFFFF" :background "#2C2C2C2C2C2C")) ; ~ cyan, dark gray
3334 (t (:foreground "DarkRed" :background "LightGray")))
3335 "*Face used for directory names."
3336 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3337(defvar diredp-dir-name 'diredp-dir-name)
3338
3339(defface diredp-dir-priv
3340 '((((background dark))
3341 (:foreground "#7474FFFFFFFF" :background "#2C2C2C2C2C2C")) ; ~ cyan, dark gray
3342 (t (:foreground "DarkRed" :background "LightGray")))
3343 "*Face used for directory privilege indicator (d) in Dired buffers."
3344 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3345(defvar diredp-dir-priv 'diredp-dir-priv)
3346
3347(defface diredp-exec-priv
3348 '((((background dark)) (:background "#4F4F3B3B2121")) ; ~ dark brown
3349 (t (:background "LightSteelBlue")))
3350 "*Face used for execute privilege indicator (x) in Dired buffers."
3351 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3352(defvar diredp-exec-priv 'diredp-exec-priv)
3353
3354;; For this to show up, you need `F' among the options in `dired-listing-switches'.
3355;; For example, I use "-alF" for `dired-listing-switches'.
3356(defface diredp-executable-tag
3357 '((t (:foreground "Red")))
3358 "*Face used for executable tag (*) on file names in Dired buffers."
3359 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3360(defvar diredp-executable-tag 'diredp-executable-tag)
3361
3362(defface diredp-file-name
3363 '((((background dark)) (:foreground "Yellow"))
3364 (t (:foreground "Blue")))
3365 "*Face used for file names (without suffixes) in Dired buffers.
3366This means the base name. It does not include the `.'."
3367 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3368(defvar diredp-file-name 'diredp-file-name)
3369
3370(defface diredp-file-suffix
3371 '((((background dark)) (:foreground "#7474FFFF7474")) ; ~ light green
3372 (t (:foreground "DarkMagenta")))
3373 "*Face used for file suffixes in Dired buffers.
3374This means the `.' plus the file extension. Example: `.elc'."
3375 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3376(defvar diredp-file-suffix 'diredp-file-suffix)
3377
3378(defface diredp-flag-mark
3379 '((((background dark)) (:foreground "Blue" :background "#7575D4D41D1D")) ; ~ olive green
3380 (t (:foreground "Yellow" :background "Blueviolet")))
3381 "*Face used for flags and marks (except D) in Dired buffers."
3382 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3383(defvar diredp-flag-mark 'diredp-flag-mark)
3384
3385(defface diredp-flag-mark-line
3386 '((((background dark)) (:background "#787831311414")) ; ~ dark red brown
3387 (t (:background "Skyblue")))
3388 "*Face used for flagged and marked lines in Dired buffers."
3389 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3390(defvar diredp-flag-mark-line 'diredp-flag-mark-line)
3391
3392(defface diredp-ignored-file-name
3393 '(;; (((background dark)) (:foreground "#FFFF921F921F")) ; ~ salmon
3394 ;; (((background dark)) (:foreground "#A71F5F645F64")) ; ~ dark salmon
3395 (((background dark)) (:foreground "#C29D6F156F15")) ; ~ salmon
3396 (t (:foreground "#00006DE06DE0"))) ; ~ dark cyan
3397 "*Face used for ignored file names in Dired buffers."
3398 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3399(defvar diredp-ignored-file-name 'diredp-ignored-file-name)
3400
3401(defface diredp-link-priv
3402 '((((background dark)) (:foreground "#00007373FFFF")) ; ~ blue
3403 (t (:foreground "DarkOrange")))
3404 "*Face used for link privilege indicator (l) in Dired buffers."
3405 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3406(defvar diredp-link-priv 'diredp-link-priv)
3407
3408(when (> emacs-major-version 21)
3409 (defface diredp-mode-line-marked
3410 '((t (:foreground "DarkViolet")))
3411 "*Face for marked number in mode-line `mode-name' for Dired buffers."
3412 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3413
3414 (defface diredp-mode-line-flagged
3415 '((t (:foreground "Red")))
3416 "*Face for flagged number in mode-line `mode-name' for Dired buffers."
3417 :group 'Dired-Plus :group 'font-lock-highlighting-faces))
3418
3419(defface diredp-no-priv
3420 '((((background dark)) (:background "#2C2C2C2C2C2C")) ; ~ dark gray
3421 (t (:background "LightGray")))
3422 "*Face used for no privilege indicator (-) in Dired buffers."
3423 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3424(defvar diredp-no-priv 'diredp-no-priv)
3425
3426(defface diredp-number
3427 '((((background dark)) (:foreground "#FFFFFFFF7474")) ; ~ light yellow
3428 (t (:foreground "DarkBlue")))
3429 "*Face used for numerical fields in Dired buffers.
3430In particular, inode number, number of hard links, and file size."
3431 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3432(defvar diredp-number 'diredp-number)
3433
3434(defface diredp-other-priv
3435 '((((background dark)) (:background "#111117175555")) ; ~ dark blue
3436 (t (:background "PaleGoldenrod")))
3437 "*Face used for l,s,S,t,T privilege indicators in Dired buffers."
3438 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3439(defvar diredp-other-priv 'diredp-other-priv)
3440
3441(defface diredp-rare-priv
3442 '((((background dark)) (:foreground "Green" :background "#FFFF00008080")) ; ~ hot pink
3443 (t (:foreground "Magenta" :background "SpringGreen")))
3444 "*Face used for rare privilege indicators (b,c,s,m,p,S) in Dired buffers."
3445 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3446(defvar diredp-rare-priv 'diredp-rare-priv)
3447
3448(defface diredp-read-priv
3449 '((((background dark)) (:background "#999932325555")) ; ~ burgundy / dark magenta
3450 (t (:background "MediumAquamarine")))
3451 "*Face used for read privilege indicator (w) in Dired buffers."
3452 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3453(defvar diredp-read-priv 'diredp-read-priv)
3454
3455(defface diredp-symlink
3456 '((((background dark)) (:foreground "#00007373FFFF")) ; ~ blue
3457 (t (:foreground "DarkOrange")))
3458 "*Face used for symbolic links in Dired buffers."
3459 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3460(defvar diredp-symlink 'diredp-symlink)
3461
3462(defface diredp-tagged-autofile-name
3463 '((((background dark)) (:background "#328C0411328C")) ; Very dark magenta
3464 (t (:background "#CD73FBEECD73"))) ; Very pale green
3465 "*Face used in Dired for names of files that are autofile bookmarks."
3466 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3467(defvar diredp-tagged-autofile-name 'diredp-tagged-autofile-name)
3468
3469(defface diredp-write-priv
3470 '((((background dark)) (:background "#25258F8F2929")) ; ~ dark green
3471 (t (:background "Orchid")))
3472 "*Face used for write privilege indicator (w) in Dired buffers."
3473 :group 'Dired-Plus :group 'font-lock-highlighting-faces)
3474(defvar diredp-write-priv 'diredp-write-priv)
3475
3476;; Fix Emacs 20 recognition of fields up through file name when size is expressed using `k' etc.
3477(when (and (< emacs-major-version 21) (not (boundp 'diredp-loaded-p))
3478 dired-move-to-filename-regexp ; These last two checks are just in case.
3479 (eq (aref dired-move-to-filename-regexp 7) ?\ ))
3480 (setq dired-move-to-filename-regexp (concat "[0-9][BkKMGTPEZY]?"
3481 (substring dired-move-to-filename-regexp 7))))
3482
3483;;; Define second level of fontifying.
3484(defvar diredp-font-lock-keywords-1
3485 (list
3486 '("^ \\(.+:\\)$" 1 diredp-dir-heading) ; Directory headers
3487 '("^ wildcard.*$" 0 'default) ; Override others, e.g. `l' for `diredp-other-priv'.
3488 '("^ (No match).*$" 0 'default) ; Override others, e.g. `t' for `diredp-other-priv'.
3489 '("[^ .]\\(\\.[^. /]+\\)$" 1 diredp-file-suffix) ; Suffix, including `.'.
3490 '("\\([^ ]+\\) -> .+$" 1 diredp-symlink) ; Symbolic links
3491
3492 ;; 1) Date/time and 2) filename w/o suffix.
3493 ;; This is a bear, and it is fragile - Emacs can change `dired-move-to-filename-regexp'.
3494 (if (or (not (fboundp 'version<)) (version< emacs-version "23.2"))
3495 (list dired-move-to-filename-regexp
3496 (list 1 'diredp-date-time t t) ; Date/time
3497 (list (concat "\\(.+\\)\\(" (concat (funcall #'regexp-opt diredp-compressed-extensions)
3498 "\\)[*]?$")) ; Compressed-file name
3499 nil nil (list 0 diredp-compressed-file-name 'keep t)))
3500 `(,dired-move-to-filename-regexp
3501 (7 diredp-date-time t t) ; Date/time, locale (western or eastern)
3502 (2 diredp-date-time t t) ; Date/time, ISO
3503 (,(concat "\\(.+\\)\\(" (concat (funcall #'regexp-opt diredp-compressed-extensions)
3504 "\\)[*]?$"))
3505 nil nil (0 diredp-compressed-file-name keep t)))) ; Compressed-file suffix
3506 (if (or (not (fboundp 'version<)) (version< emacs-version "23.2"))
3507 (list dired-move-to-filename-regexp
3508 (list 1 'diredp-date-time t t) ; Date/time
3509 (list "\\(.+\\)$" nil nil (list 0 diredp-file-name 'keep t))) ; Filename
3510 `(,dired-move-to-filename-regexp
3511 (7 diredp-date-time t t) ; Date/time, locale (western or eastern)
3512 (2 diredp-date-time t t) ; Date/time, ISO
3513 ("\\(.+\\)$" nil nil (0 diredp-file-name keep t)))) ; Filename (not a compressed file)
3514
3515 ;; Files to ignore
3516 (list (concat "^ \\(.*\\("
3517 (mapconcat #'regexp-quote (or (and (boundp 'dired-omit-extensions) dired-omit-extensions)
3518 completion-ignored-extensions)
3519 "[*]?\\|")
3520 (and diredp-ignore-compressed-flag
3521 (concat "\\|" (mapconcat #'regexp-quote diredp-compressed-extensions "[*]?\\|")))
3522 "[*]?\\)\\)$") ; Allow for executable flag (*).
3523 1 diredp-ignored-file-name t)
3524
3525 ;; Compressed-file (suffix)
3526 (list (concat "\\(" (concat (funcall #'regexp-opt diredp-compressed-extensions) "\\)[*]?$"))
3527 1 diredp-compressed-file-suffix t)
3528 '("\\([*]\\)$" 1 diredp-executable-tag t) ; Executable (*)
3529
3530 ;; Inode, hard-links, & file size (. and , are for the decimal point, depending on locale)
3531 ;; See comment for `directory-listing-before-filename-regexp' in `files.el' or `files+.el'.
3532 '("\\(\\([0-9]+\\([.,][0-9]+\\)?\\)[BkKMGTPEZY]?[ /]?\\)" 1 diredp-number)
3533
3534 ;; Directory names - exclude d:/..., Windows drive letter in a dir heading.
3535 (list (concat dired-re-maybe-mark dired-re-inode-size "\\(d\\)[^:]")
3536 '(1 diredp-dir-priv t) '(".+" (dired-move-to-filename) nil (0 diredp-dir-name t)))
3537
3538 (list (concat dired-re-maybe-mark dired-re-inode-size "[-dl]........\\(x\\)") ; o x
3539 '(1 diredp-exec-priv))
3540 (list (concat dired-re-maybe-mark dired-re-inode-size "[-dl]........\\([lsStT]\\)") ; o misc
3541 '(1 diredp-other-priv))
3542 (list (concat dired-re-maybe-mark dired-re-inode-size "[-dl].......\\(w\\).") ; o w
3543 '(1 diredp-write-priv))
3544 (list (concat dired-re-maybe-mark dired-re-inode-size "[-dl]......\\(r\\)..") ; o r
3545 '(1 diredp-read-priv))
3546 (list (concat dired-re-maybe-mark dired-re-inode-size "[-dl].....\\(x\\)...") ; g x
3547 '(1 diredp-exec-priv))
3548 (list (concat dired-re-maybe-mark dired-re-inode-size "[-dl].....\\([lsStT]\\)...") ; g misc
3549 '(1 diredp-other-priv))
3550 (list (concat dired-re-maybe-mark dired-re-inode-size "[-dl]....\\(w\\)....") ; g w
3551 '(1 diredp-write-priv))
3552 (list (concat dired-re-maybe-mark dired-re-inode-size "[-dl]...\\(r\\).....") ; g r
3553 '(1 diredp-read-priv))
3554 (list (concat dired-re-maybe-mark dired-re-inode-size "[-dl]..\\(x\\)...") ; u x
3555 '(1 diredp-exec-priv))
3556 (list (concat dired-re-maybe-mark dired-re-inode-size "[-dl]..\\([lsStT]\\)...") ; u misc
3557 '(1 diredp-other-priv))
3558 (list (concat dired-re-maybe-mark dired-re-inode-size "[-dl].\\(w\\)....") ; u w
3559 '(1 diredp-write-priv))
3560 (list (concat dired-re-maybe-mark dired-re-inode-size "[-dl]\\(r\\).....") ; u r
3561 '(1 diredp-read-priv))
3562
3563 (list (concat dired-re-maybe-mark dired-re-inode-size "[-dl]........\\([-rwxlsStT]\\)") ; o -
3564 '(1 diredp-no-priv keep))
3565 (list (concat dired-re-maybe-mark dired-re-inode-size "[-dl].......\\([-rwxlsStT]\\).") ; g -
3566 '(1 diredp-no-priv keep))
3567 (list (concat dired-re-maybe-mark dired-re-inode-size "[-dl]......\\([-rwxlsStT]\\)..") ; u -
3568 '(1 diredp-no-priv keep))
3569 (list (concat dired-re-maybe-mark dired-re-inode-size "[-dl].....\\([-rwxlsStT]\\)...") ; o -
3570 '(1 diredp-no-priv keep))
3571 (list (concat dired-re-maybe-mark dired-re-inode-size "[-dl]....\\([-rwxlsStT]\\)....") ; g -
3572 '(1 diredp-no-priv keep))
3573 (list (concat dired-re-maybe-mark dired-re-inode-size "[-dl]...\\([-rwxlsStT]\\).....") ; u -
3574 '(1 diredp-no-priv keep))
3575 (list (concat dired-re-maybe-mark dired-re-inode-size "[-dl]..\\([-rwxlsStT]\\)......") ; o -
3576 '(1 diredp-no-priv keep))
3577 (list (concat dired-re-maybe-mark dired-re-inode-size "[-dl].\\([-rwxlsStT]\\).......") ; g -
3578 '(1 diredp-no-priv keep))
3579 (list (concat dired-re-maybe-mark dired-re-inode-size "[-dl]\\([-rwxlsStT]\\)........") ; u -
3580 '(1 diredp-no-priv keep))
3581
3582 (list (concat dired-re-maybe-mark dired-re-inode-size "\\([bcsmpS]\\)") ; (rare)
3583 '(1 diredp-rare-priv keep))
3584 (list (concat dired-re-maybe-mark dired-re-inode-size "\\(l\\)[-rwxlsStT]") ; l
3585 '(1 diredp-rare-priv keep))
3586
3587 (list (concat "^\\([^\n " (char-to-string dired-del-marker) "].*$\\)")
3588 1 diredp-flag-mark-line t) ; Flag/mark lines
3589 (list (concat "^\\([^\n " (char-to-string dired-del-marker) "]\\)") ; Flags, marks (except D)
3590 1 diredp-flag-mark t)
3591
3592 (list (concat "^\\([" (char-to-string dired-del-marker) "].*$\\)") ; Deletion-flagged lines
3593 1 diredp-deletion-file-name t)
3594 (list (concat "^\\([" (char-to-string dired-del-marker) "]\\)") ; Deletion flags (D)
3595 1 diredp-deletion t)
3596
3597 ) "2nd level of Dired highlighting. See `font-lock-maximum-decoration'.")
3598
3599
3600(defun diredp--set-up-font-locking ()
3601 "Add this to `dired-mode-hook' to provide for second-level fontifying."
3602 (set (make-local-variable 'font-lock-defaults)
3603 ;; Two levels. Use 3-element list, since it is standard to have one more
3604 ;; than the number of levels. This is necessary for it to work with
3605 ;; `font(-lock)-menus.el'.
3606 '((dired-font-lock-keywords
3607 dired-font-lock-keywords
3608 diredp-font-lock-keywords-1)
3609 t nil nil beginning-of-line))
3610 ;; Refresh `font-lock-keywords' from `font-lock-defaults'
3611 (when (fboundp 'font-lock-refresh-defaults) (font-lock-refresh-defaults)))
3612
3613;;; Provide for the second level of fontifying.
3614(add-hook 'dired-mode-hook 'diredp--set-up-font-locking)
3615
3616;; Ensure that Dired buffers are refontified when you use `g' or otherwise read in the file list.
3617(defun diredp-refontify-buffer ()
3618 "Turn `font-lock-mode' off, then on."
3619 (setq font-lock-mode nil)
3620 (font-lock-mode))
3621(add-hook 'dired-after-readin-hook 'diredp-refontify-buffer)
3622
3623;;; Function Definitions
3624
3625;;; $$$$$$$$
3626;;; (defun diredp-dired-files (arg &optional switches) ; Not bound
3627;;; "Like `dired', but non-positive prefix arg prompts for files to list.
3628;;; This is like `dired' unless you use a non-positive prefix arg.
3629;;; In that case, you are prompted for names of files and directories to
3630;;; list, and then you are prompted for the name of the Dired buffer that
3631;;; lists them. Use `C-g' when you are done entering file names to list.
3632
3633;;; In all cases, when inputting a file or directory name you can use
3634;;; shell wildcards.
3635
3636;;; If you use Icicles, then in Icicle mode the following keys are bound
3637;;; in the minibuffer during completion (`*' means the key requires
3638;;; library `Bookmark+'):
3639
3640;;; M-| - Open Dired on the file names matching your input
3641;;; C-c + - Create a new directory
3642;;; *C-x a + - Add tags to the current-candidate file
3643;;; *C-x a - - Remove tags from the current-candidate file
3644;;; *C-x m - Access file bookmarks (not just autofiles)"
3645;;; (interactive (diredp-dired-files-interactive-spec ""))
3646;;; (when (consp arg)
3647;;; (let ((buf (dired-find-buffer-nocreate (car arg)))) ; Respect file list.
3648;;; (when buf (kill-buffer buf))))
3649;;; (switch-to-buffer (dired-noselect arg switches)))
3650
3651;;; (defun diredp-dired-files-other-window (arg &optional switches) ; Not bound
3652;;; "Same as `diredp-dired-files' except uses another window."
3653;;; (interactive (diredp-dired-files-interactive-spec "in other window "))
3654;;; (when (consp arg)
3655;;; (let ((buf (dired-find-buffer-nocreate (car arg)))) ; Respect file list.
3656;;; (when buf (kill-buffer buf))))
3657;;; (dired-other-window arg switches))
3658
3659;;;###autoload
3660(defun diredp-dired-for-files (arg &optional switches) ; Bound to `C-x D F'
3661 "Dired file names that you enter, in a Dired buffer that you name.
3662You are prompted for the name of the Dired buffer to use.
3663You are then prompted for names of files and directories to list,
3664 which can be located anywhere.
3665Use `C-g' when you are done.
3666
3667With a prefix arg you are first prompted for the `ls' switches to use.
3668
3669See also `dired' (including the advice)."
3670 (interactive (let ((current-prefix-arg (if current-prefix-arg 0 -1)))
3671 (dired-read-dir-and-switches "" 'READ-EXTRA-FILES-P)))
3672 (dired arg switches))
3673
3674;;;###autoload
3675(defun diredp-dired-for-files-other-window (arg &optional switches) ; Bound to `C-x 4 D F'
3676 "Same as `diredp-dired-for-files', except uses another window."
3677 (interactive (let ((current-prefix-arg (if current-prefix-arg 0 -1)))
3678 (dired-read-dir-and-switches "in other window " 'READ-EXTRA-FILES-P)))
3679 (dired-other-window arg switches))
3680
3681;;;###autoload
3682(defun diredp-dired-recent-dirs (buffer &optional arg) ; Bound to `C-x D R'
3683 "Open Dired in BUFFER, showing recently used directories.
3684You are prompted for BUFFER.
3685
3686No prefix arg or a plain prefix arg (`C-u', `C-u C-u', etc.) means
3687list all of the recently used directories.
3688
3689With a prefix arg:
3690* If 0, `-', or plain (`C-u') then you are prompted for the `ls'
3691 switches to use.
3692* If not plain (`C-u') then:
3693 * If >= 0 then the directories to include are read, one by one.
3694 * If < 0 then the directories to exclude are read, one by one.
3695
3696When entering directories to include or exclude, use `C-g' to end."
3697 (interactive (list (completing-read "Dired buffer name: " dired-buffers) current-prefix-arg))
3698 (unless (require 'recentf nil t) (error "This command requires library `recentf.el'"))
3699 (let ((switches (and (or (zerop (prefix-numeric-value arg)) (consp arg))
3700 (read-string "Dired listing switches: " dired-listing-switches))))
3701 (dired (cons (generate-new-buffer-name buffer) (diredp-recent-dirs arg)) switches)))
3702
3703;;;###autoload
3704(defun diredp-dired-recent-dirs-other-window (buffer &optional arg) ; Bound to `C-x 4 D R'
3705 "Same as `diredp-dired-recent-dirs', but use other window."
3706 (interactive (list (completing-read "Dired buffer name: " dired-buffers) current-prefix-arg))
3707 (unless (require 'recentf nil t) (error "This command requires library `recentf.el'"))
3708 (let ((switches (and (or (zerop (prefix-numeric-value arg)) (consp arg) (eq '- arg))
3709 (read-string "Dired listing switches: " dired-listing-switches))))
3710 (dired-other-window (cons (generate-new-buffer-name buffer) (diredp-recent-dirs arg)) switches)))
3711
3712(defun diredp-recent-dirs (arg)
3713 "Return a list of recently used directories.
3714ARG is as for `diredp-dired-recent-dirs'."
3715 (let ((recent-dirs (diredp-remove-if #'diredp-root-directory-p
3716 (diredp-delete-dups
3717 (mapcar (lambda (f/d)
3718 (if (file-directory-p f/d) f/d (file-name-directory f/d)))
3719 recentf-list)))))
3720 (if (and arg (atom arg))
3721 (diredp-read-include/exclude 'Dir recent-dirs (not (natnump (prefix-numeric-value arg))))
3722 recent-dirs)))
3723
3724(defun diredp-read-include/exclude (thing things &optional exclude)
3725 "Read which THINGs to include (or to EXCLUDE, if non-nil) from list THINGS.
3726The things are read one by one. `C-g' stops reading.
3727
3728THING is a string or symbol naming the type of thing to read, e.g.,
3729`File' or `Directory'. It is used only in the prompt, which is THING
3730followed by \" to exclude\" or \" to include\" and a reminder about `C-g'.
3731
3732A new list is returned - list THINGS is not modified."
3733 (let* ((thgs (if exclude (copy-sequence things) ()))
3734 (prompt (format "%s to %s (C-g when done): " thing (if exclude 'EXCLUDE 'INCLUDE)))
3735 (completion-ignore-case (or (and (boundp 'read-file-name-completion-ignore-case)
3736 (memq thing '(Dir Directory File "Dir" "Directory" "File")) ; Hack
3737 read-file-name-completion-ignore-case)
3738 completion-ignore-case))
3739 thing)
3740 (while (condition-case nil
3741 (setq thing (completing-read prompt (mapcar #'list things) nil t))
3742 (quit nil))
3743 (if exclude (delete thing thgs)
3744 (push thing thgs)))
3745 thgs))
3746
3747;;; $$$$$$$$
3748;;; (defun diredp-dired-files-interactive-spec (str)
3749;;; "`interactive' spec for `diredp-dired-files' commands.
3750;;; STR is a string appended to the prompt.
3751;;; With non-negative prefix arg, read switches.
3752;;; With non-positive prefix arg, read files and dirs to list and then the
3753;;; Dired buffer name. User uses `C-g' when done reading files and dirs.
3754
3755;;; If you use Icicles, then in Icicle mode the following keys are bound
3756;;; in the minibuffer during completion (`*' means the key requires
3757;;; library `Bookmark+'):
3758
3759;;; M-| - Open Dired on the file names matching your input
3760;;; C-c + - Create a new directory
3761;;; *C-x a + - Add tags to the current-candidate file
3762;;; *C-x a - - Remove tags from the current-candidate file
3763;;; *C-x m - Access file bookmarks (not just autofiles)"
3764;;; (list
3765;;; (unwind-protect
3766;;; (let ((icicle-sort-comparer (or (and (boundp 'icicle-file-sort) ;; If not reading files
3767;;; icicle-file-sort) ;; then dirs first.
3768;;; (and (> (prefix-numeric-value current-prefix-arg) 0)
3769;;; 'icicle-dirs-first-p)
3770;;; icicle-sort-comparer))
3771;;; (icicle-all-candidates-list-alt-action-fn ; M-|'
3772;;; (lambda (files)
3773;;; (let ((enable-recursive-minibuffers t))
3774;;; (dired-other-window (cons (read-string "Dired buffer name: ") files))))))
3775;;; (when (fboundp 'icicle-bind-file-candidate-keys) (icicle-bind-file-candidate-keys))
3776;;; (if (> (prefix-numeric-value current-prefix-arg) 0)
3777;;; ;; If a dialog box is about to be used, call `read-directory-name' so the dialog
3778;;; ;; code knows we want directories. Some dialog boxes can only select directories
3779;;; ;; or files when popped up, not both.
3780;;; (if (and (fboundp 'read-directory-name) (next-read-file-uses-dialog-p))
3781;;; (read-directory-name (format "Dired %s(directory): " str) nil
3782;;; default-directory nil)
3783;;; (read-file-name (format "Dired %s(directory): " str) nil default-directory nil))
3784;;; (let ((insert-default-directory nil)
3785;;; (files ())
3786;;; file)
3787;;; (while (condition-case nil ; Use lax completion, to allow wildcards.
3788;;; (setq file (read-file-name "File or dir (C-g when done): "))
3789;;; (quit nil))
3790;;; (push file files))
3791;;; (cons (read-string "Dired buffer name: " nil nil default-directory) files))))
3792;;; (when (fboundp 'icicle-unbind-file-candidate-keys)
3793;;; (icicle-unbind-file-candidate-keys)))
3794;;; (and current-prefix-arg (natnump (prefix-numeric-value current-prefix-arg))
3795;;; (read-string "Dired listing switches: " dired-listing-switches))))
3796
3797;;;###autoload
3798(defun diredp-dired-union (dired-name dirbufs &optional switches extra) ; Bound to `C-x D U'
3799 "Create a Dired buffer that is the union of some existing Dired buffers.
3800With a non-negative prefix arg, you are prompted for `ls' switches.
3801With a non-positive prefix arg, you are prompted for file and dir
3802names to add to the listing - see below.
3803
3804You are prompted for the name of the Dired union buffer. Completion
3805against names of existing Dired buffers is available, but you can
3806enter any other name to create a new Dired buffer of that name.
3807
3808If the union buffer name you choose names an existing Dired buffer,
3809then what happens depends on whether that buffer is an ordinary Dired
3810directory listing or a list of arbitrary file names. That is, it
3811depends on whether `dired-directory' is a directory name or a cons of
3812a Dired buffer name plus file names.
3813
3814* If the buffer is an ordinary Dired listing, then it is converted to
3815 an explicit list of absolute file names, just as if these had been
3816 chosen individually. The existing buffer and window are replaced by
3817 new ones that show the explicit listing. (This replacement is
3818 necessary because the list of files contained in an ordinary Dired
3819 listing cannot be modified.)
3820
3821* If the buffer lists arbitrary file names explicitly, then it is
3822 updated to include also the files from any Dired buffers and any
3823 additional files that you specify.
3824
3825If the union buffer name you choose does not name an existing Dired
3826buffer, then its `default-directory' is the same as the
3827`default-directory' before invoking the command.
3828
3829If you use a non-positive prefix arg, then you can next choose
3830additional file and directory names to add to the listing. Use `C-g'
3831when done choosing them.
3832
3833Any directory names you choose this way are included as single entries
3834in the listing - the directory contents are not included (these
3835directories are not unioned). To instead include the contents of a
3836directory chosen this way, use a glob pattern: `/*' after the
3837directory name.
3838
3839You are then prompted for the Dired buffers to union. Use `C-g' when
3840done choosing them. These Dired listings to union are included in the
3841order that you chose them, and each entry is listed only once in the
3842new Dired buffer.
3843
3844The new Dired listing respects the markings, subdirectory insertions,
3845and hidden subdirectories of the selected Dired listings. However, in
3846case of conflict between marked or unmarked status for the same entry,
3847the entry is marked. Similarly, in case of conflict over an included
3848subdirectory between it being hidden or shown, it is hidden, but its
3849contained files are also listed.
3850
3851See also command `diredp-add-to-dired-buffer'.
3852
3853From Lisp:
3854 DIRED-NAME is the name of the resulting Dired union buffer.
3855 DIRBUFS is a list of the names of Dired buffers to union.
3856 SWITCHES is a string of `ls' switches.
3857 EXTRA is a list of files & directories to be included in the listing."
3858 (interactive (diredp-dired-union-interactive-spec "UNION "
3859 nil
3860 (and current-prefix-arg
3861 (<= (prefix-numeric-value current-prefix-arg) 0))))
3862 (diredp-dired-union-1 dired-name dirbufs switches extra))
3863
3864;;;###autoload
3865(defun diredp-dired-union-other-window (dired-name dirbufs &optional switches extra) ; Bound to `C-x 4 D U'
3866 "Same as `diredp-dired-union', except use other window."
3867 (interactive (diredp-dired-union-interactive-spec "UNION "
3868 nil
3869 (and current-prefix-arg
3870 (<= (prefix-numeric-value current-prefix-arg) 0))))
3871 (diredp-dired-union-1 dired-name dirbufs switches extra 'OTHERWIN))
3872
3873;;;###autoload
3874(defun diredp-add-to-dired-buffer (dired-name to-add &optional switches) ; Bound to `C-x D A'
3875 "Add individual file and directory names to a Dired buffer.
3876You are prompted for the buffer name.
3877With a prefix arg, you are also prompted for the `ls' switches.
3878
3879The buffer must either not exist yet or must list arbitrary file and
3880directory names. That is, it cannot be an ordinary Dired directory
3881listing - those cannot be modified.
3882
3883Any directory names you choose this way are included as single entries
3884in the listing - the directory contents are not included (these
3885directories are not unioned). To instead include the contents of a
3886directory chosen this way, use a glob pattern: `/*' after the
3887directory name.
3888
3889See also command `diredp-dired-union'.
3890
3891From Lisp:
3892 DIRED-NAME is the name of the Dired buffer to modify.
3893 TO-ADD is the list of files and dirs to add to it.
3894 SWITCHES is the string of `ls' switches."
3895 ;; Bind `current-prefix-arg' to force reading file/dir names.
3896 ;; Read `ls' switches too, if user used prefix arg.
3897 (interactive
3898 (let* ((current-prefix-arg (if current-prefix-arg 0 -1))
3899 (all (diredp-dired-union-interactive-spec "add files/dirs "
3900 'NO-DIRED-BUFS
3901 'READ-EXTRA-FILES-P)))
3902 (list (nth 0 all) (nth 3 all) (nth 2 all))))
3903 (diredp-dired-union-1 dired-name () switches to-add))
3904
3905;;;###autoload
3906(defun diredp-add-to-dired-buffer-other-window (dired-name to-add &optional switches) ; Bound to `C-x 4 D A'
3907 "Same as `diredp-add-to-dired-buffer', except use other window."
3908 ;; Bind `current-prefix-arg' to force reading file/dir names.
3909 ;; Read `ls' switches too, if user used prefix arg.
3910 (interactive
3911 (let* ((current-prefix-arg (if current-prefix-arg 0 -1))
3912 (all (diredp-dired-union-interactive-spec "add files/dirs "
3913 'NO-DIRED-BUFS
3914 'READ-EXTRA-FILES-P)))
3915 (list (nth 0 all) (nth 3 all) (nth 2 all))))
3916 (diredp-dired-union-1 dired-name () switches to-add 'OTHERWIN))
3917
3918;;;###autoload
3919(defun diredp-add-to-this-dired-buffer (dired-name to-add &optional switches) ; Not bound by default
3920 "Same as `diredp-add-to-dired-buffer' for this Dired buffer."
3921 ;; Bind `current-prefix-arg' to force reading file/dir names.
3922 ;; Read `ls' switches too, if user used prefix arg.
3923 (interactive
3924 (progn (unless (derived-mode-p 'dired-mode) (error "Not in a Dired buffer"))
3925 (let* ((current-prefix-arg (if current-prefix-arg 0 -1))
3926 (all (diredp-dired-union-interactive-spec "add files/dirs here "
3927 'NO-DIRED-BUFS
3928 'READ-EXTRA-FILES-P
3929 (buffer-name))))
3930 (list (nth 0 all) (nth 3 all) (nth 2 all)))))
3931 (diredp-dired-union-1 dired-name () switches to-add))
3932
3933;; $$$$$ Maybe I should set `dired-sort-inhibit' to t for now (?),
3934;; since there is an Emacs bug (at least on Windows) that prevents
3935;; sorting from working for a Dired buffer with an explicit file list.
3936(defun diredp-dired-union-1 (dired-name dirbufs switches extra &optional otherwin)
3937 "Helper for `diredp-dired-union' and `diredp-add-to-dired-buffer'.
3938Non-nil optional OTHERWIN means use other window for the Dired buffer.
3939See `diredp-dired-union' for the other argument descriptions."
3940 (let ((dbuf (get-buffer dired-name))
3941 (files extra)
3942 (marked ())
3943 (subdirs ())
3944 (hidden-dirs ())
3945 hid-here files-here)
3946 (dolist (buf (reverse dirbufs))
3947 (with-current-buffer buf
3948 (unwind-protect
3949 (progn (setq hid-here (save-excursion (dired-remember-hidden))
3950 files-here (if (consp dired-directory)
3951 (reverse (cdr dired-directory)) ; Reverse bc will push.
3952 ()))
3953 (unless files-here
3954 (save-excursion ; This bit is more or less from `dired-toggle-marks'.
3955 (goto-char (point-min))
3956 (while (not (eobp))
3957 (or (diredp-looking-at-p dired-re-dot)
3958 (push (dired-get-filename nil 'NO-ERROR-P) files-here))
3959 (forward-line 1)))
3960 (setq files-here (delq nil files-here)))
3961 (dolist (hid-here hid-here) (push hid-here hidden-dirs))
3962 (dolist (sub (cdr (reverse dired-subdir-alist)))
3963 (push (list (car sub)) subdirs))
3964 (dolist (mkd (dired-remember-marks (point-min) (point-max))) ; This unhides.
3965 (push (car mkd) marked))
3966 (dolist (file files-here)
3967 (when (or (not (file-name-absolute-p file)) (not (member file files)))
3968 (push file files))))
3969 (save-excursion ; Hide subdirs that were hidden.
3970 (dolist (dir hid-here) (when (dired-goto-subdir dir) (dired-hide-subdir 1)))))))
3971 ;; For an existing Dired buffer having this name whose `dired-directory' is a cons:
3972 ;; 1. Include the files and dirs already listed there.
3973 ;; 2. Kill the current buffer and delete its window. A new buffer of the same name is created and shown.
3974 (when dbuf
3975 (with-current-buffer dbuf
3976 (when (consp dired-directory) (setq files (diredp-set-union (cdr dired-directory) files)))
3977 (let ((win (get-buffer-window dbuf 0))) (when win (delete-window win)))
3978 (kill-buffer dbuf)))
3979 (setq dbuf (dired-other-window (cons dired-name files) switches))
3980 (with-current-buffer dbuf
3981 (let ((inhibit-read-only t))
3982 (dired-insert-old-subdirs subdirs)
3983 (dired-mark-remembered ; Don't really need `expand-file-name' - already abs.
3984 (mapcar (lambda (mf) (cons (expand-file-name mf dired-directory) 42)) marked))
3985 (save-excursion
3986 (dolist (hdir hidden-dirs) (when (dired-goto-subdir hdir) (dired-hide-subdir 1))))))))
3987
3988(defun diredp-dired-union-interactive-spec (string &optional no-dired-bufs read-extra-files-p dired-buffer)
3989 "Read arguments for `diredp-dired-union' and `diredp-add-to-dired-buffer'.
3990STRING is appended to the prompt for the listing buffer name.
3991Non-nil NO-DIRED-BUFS means do not read Dired buffers to union.
3992Non-nil READ-EXTRA-FILES-P is passed to `dired-read-dir-and-switches',
3993 and means read extra files to add to the listing.
3994Non-nil DIRED-BUFFER is passed to `dired-read-dir-and-switches'.
3995 It is the name of the Dired union buffer."
3996 (let* ((current-prefix-arg -1)
3997 (dir+switches (dired-read-dir-and-switches string read-extra-files-p dired-buffer))
3998 (dirname (car dir+switches))
3999 (switches (cadr dir+switches))
4000 (dirbufs ())
4001 (bufs ())
4002 (extra-files ())
4003 buf)
4004 (when (consp dirname) (setq extra-files (cdr dirname)
4005 dirname (car dirname)))
4006 (unless no-dired-bufs
4007 ;; Remove any killed buffers from `dired-buffers'. Then use all but the target buffer as candidates.
4008 (dolist (db dired-buffers)
4009 (if (buffer-live-p (cdr db))
4010 (unless (equal dirname (buffer-name (cdr db)))
4011 (push (cons (buffer-name (cdr db)) (car db)) dirbufs))
4012 (setq dired-buffers (delq db dired-buffers))))
4013 (while (and dirbufs (condition-case nil
4014 (setq buf (completing-read "Existing Dired buffer to include (C-g when done): "
4015 dirbufs nil t nil 'buffer-name-history
4016 (and dirbufs (car (assoc (buffer-name) dirbufs)))))
4017 (quit nil)))
4018 (push buf bufs)
4019 (setq dirbufs (delete (cons buf (with-current-buffer buf (expand-file-name default-directory)))
4020 dirbufs)))
4021 (setq bufs (nreverse bufs)))
4022 (list dirname bufs switches extra-files)))
4023
4024(when (> emacs-major-version 23) ; `compilation--loc->file-struct'
4025
4026 (defalias 'diredp-grepped-files-other-window 'diredp-compilation-files-other-window)
4027 (defun diredp-compilation-files-other-window (&optional switches)
4028 "Open Dired on the files indicated by compilation (e.g., `grep') hits.
4029Applies to any `compilation-mode'-derived buffer, such as `*grep*'.
4030You are prompted for the name of the new Dired buffer.
4031With a prefix arg you are first prompted for the `ls' switches.
4032
4033\(However, Emacs bug #20739 means that the switches are ignored.)"
4034 (interactive (list (and current-prefix-arg (read-string "Dired listing switches: " dired-listing-switches))))
4035 (unless (compilation-buffer-p (current-buffer)) (error "Not in a buffer derived from `compilation-mode'"))
4036 (let ((files ()))
4037 (save-excursion (goto-char (point-min))
4038 (while (condition-case nil (compilation-next-file 1) (error nil))
4039 (setq compilation-current-error (point))
4040 (push (diredp-file-for-compilation-hit-at-point) files)))
4041 (setq files (nreverse files))
4042 (dired-other-window
4043 (cons (read-string "Dired buffer name: " nil nil (generate-new-buffer-name default-directory)) files)
4044 switches)))
4045
4046 (defun diredp-file-for-compilation-hit-at-point ()
4047 "Return the name of the file for the compilation hit at point.
4048The name is expanded in the directory for the last directory change."
4049 (let* ((msg (compilation-next-error 0))
4050 (loc (compilation--message->loc msg))
4051 (filestruct (compilation--loc->file-struct loc))
4052 (file (caar filestruct))
4053 (dir (cadr (car filestruct))))
4054 (when dir (setq file (expand-file-name file dir)))
4055 file))
4056 )
4057
4058;;;###autoload
4059(defun diredp-fileset (flset-name) ; Bound to `C-x D S'
4060 "Open Dired on the files in fileset FLSET-NAME."
4061 (interactive
4062 (progn (unless (require 'filesets nil t) (error "Feature `filesets' not provided"))
4063 (unless filesets-data (error "`filesets-data' is empty"))
4064 (list (completing-read "Open Dired on fileset: " filesets-data))))
4065 (diredp-fileset-1 flset-name))
4066
4067;;;###autoload
4068(defun diredp-fileset-other-window (flset-name) ; Bound to `C-x 4 D S'
4069 "Open Dired in another window on the files in fileset FLSET-NAME."
4070 (interactive
4071 (progn (unless (require 'filesets nil t) (error "Feature `filesets' not provided"))
4072 (unless filesets-data (error "`filesets-data' is empty"))
4073 (list (completing-read "Open Dired on fileset, in other window: " filesets-data))))
4074 (diredp-fileset-1 flset-name 'OTHER-WINDOW))
4075
4076(defun diredp-fileset-1 (flset-name &optional other-window-p)
4077 "Helper for `diredp-fileset(-other-window)'."
4078 (let ((flset (filesets-get-fileset-from-name flset-name))
4079 (files ())
4080 (mode nil)
4081 (dirfun (if other-window-p #'dired-other-window #'dired)))
4082 (unless (or (setq mode (filesets-entry-mode flset)) ; ("my-fs" (:files "a" "b"))
4083 (setq flset (cons "dummy" flset) ; (:files "a" "b")
4084 mode (filesets-entry-mode flset)))
4085 (error "Bad fileset: %S" flset-name))
4086 (message "Gathering file names...")
4087 (dolist (file (filesets-get-filelist flset mode)) (push file files))
4088 (funcall dirfun (cons (generate-new-buffer-name flset-name)
4089 (nreverse (mapcar (lambda (file)
4090 (if (file-name-absolute-p file)
4091 (expand-file-name file)
4092 file))
4093 files))))))
4094
4095;;;###autoload
4096(defun diredp-dired-this-subdir (&optional tear-off-p msgp)
4097 "Open Dired for the subdir at or above point.
4098If point is not on a subdir line, but is in an inserted subdir
4099listing, then use that subdir.
4100
4101With a prefix arg:
4102 If the subdir is inserted and point is in the inserted listing then
4103 remove that listing and move to the ordinary subdir line. In other
4104 words, when in an inserted listing, a prefix arg tears off the
4105 inserted subdir to its own Dired buffer."
4106 (interactive "P\np")
4107 (diredp-ensure-mode)
4108 (let* ((this-dir default-directory)
4109 (this-subdir (diredp-this-subdir))
4110 (on-dir-line-p (atom this-subdir)))
4111 (unless on-dir-line-p ; Subdir header line or non-directory file.
4112 (setq this-subdir (car this-subdir)))
4113 (unless (string= this-subdir this-dir)
4114 (when tear-off-p
4115 (unless on-dir-line-p
4116 (dired-kill-subdir) ; Tear it off.
4117 (dired-goto-file this-subdir))) ; Move to normal subdir line.
4118 (dired-other-window this-subdir))))
4119
4120;;;###autoload
4121(defun diredp-dired-inserted-subdirs (&optional no-show-p msgp) ; Bound to `C-M-i'
4122 "Open Dired for each of the subdirs inserted in this Dired buffer.
4123A separate Dired buffer is used for each of them.
4124With a prefix arg, create the Dired buffers but do not display them.
4125Markings and current Dired switches are preserved."
4126 (interactive "P\np")
4127 (diredp-ensure-mode)
4128 (let ((this-dir default-directory)
4129 (this-buff (current-buffer))
4130 (this-frame (selected-frame))
4131 marked)
4132 (unwind-protect
4133 (save-selected-window
4134 (dolist (entry dired-subdir-alist)
4135 (unless (string= (car entry) this-dir)
4136 (setq marked
4137 (with-current-buffer this-buff
4138 (dired-remember-marks (dired-get-subdir-min entry)
4139 (dired-get-subdir-max entry))))
4140 (if (not no-show-p)
4141 (dired-other-window (car entry) dired-actual-switches)
4142 (dired-noselect (car entry) dired-actual-switches)
4143 (when msgp (message "Dired buffers created but not shown")))
4144 (set-buffer this-buff)
4145 (let ((inhibit-read-only t))
4146 (dired-mark-remembered marked))
4147 (set-buffer-modified-p nil))))
4148 (select-frame-set-input-focus this-frame))))
4149
4150
4151;;; Actions on marked files and subdirs, recursively.
4152
4153(defun diredp-get-subdirs (&optional ignore-marks-p predicate)
4154 "Return subdirs from this Dired buffer and from marked subdirs, recursively.
4155If optional arg IGNORE-MARKS-P is non-nil then include all
4156subdirectories. Otherwise, include only those that are marked.
4157
4158Non-nil optional arg PREDICATE means include only subdirectory names
4159for which the PREDICATE returns non-nil. PREDICATE must accept a file
4160name as its only required argument."
4161 (diredp-get-files ignore-marks-p
4162 (if predicate
4163 `(lambda (name) (and (file-directory-p name) (funcall ,predicate name)))
4164 #'file-directory-p)
4165 'INCLUDE-DIRS-P 'DONT-ASKP 'ONLY-MARKED-P))
4166
4167(defun diredp-get-files (&optional ignore-marks-p predicate include-dirs-p
4168 dont-askp only-marked-p)
4169 "Return file names from this Dired buffer and subdirectories, recursively.
4170The names are those that are marked in the current Dired buffer, or
4171all files in the directory if none are marked. Marked subdirectories
4172are handled recursively in the same way.
4173
4174If there is some included subdirectory that has a Dired buffer with
4175marked files, then (unless DONT-ASKP is non-nil) this asks you whether
4176to use the marked files in Dired buffers, as opposed to using all of
4177the files in included directories. To this y-or-n question you can
4178hit `l' to see the list of files that will be included (using
4179`diredp-list-files'). In that `l' listing you can mouseover to see
4180image-file previews or use `RET' or `mouse-2' to visit files.
4181
4182\(Directories in `icicle-ignored-directories' are skipped, if you use
4183Icicles. Otherwise, directories in `vc-directory-exclusion-list' are
4184skipped.)
4185
4186Non-nil IGNORE-MARKS-P means ignore all Dired markings: just get all
4187of the files in the current directory (and all of the subdirectories,
4188if INCLUDE-DIRS-P is non-nil).
4189
4190Non-nil PREDICATE means include only file names for which the
4191PREDICATE returns non-nil. PREDICATE must accept a file name as its
4192only required argument.
4193
4194Non-nil INCLUDE-DIRS-P means include marked subdirectory names (but
4195also handle those subdirs recursively, picking up their marked files
4196and subdirs).
4197
4198Non-nil DONT-ASKP means do not ask the user whether to use marked
4199instead of all. Act as if the user was asked and replied `y'.
4200
4201Non-nil optional arg ONLY-MARKED-P means collect only marked files,
4202instead of collecting all files if none are marked. This argument is
4203ignored if IGNORE-MARKS-P is non-nil."
4204;;;;@@@@@@@@@ ;; Set IGNORE-MARKS-P to non-nil if nothing marked here.
4205;;;; (let ((dired-marker-char ?*))
4206;;;; (save-excursion
4207;;;; (goto-char (point-min))
4208;;;; (unless (re-search-forward (dired-marker-regexp) nil t) (setq ignore-marks-p t))))
4209 (let ((askp (list nil))) ; The cons's car will be set to `t' if need to ask user.
4210 (if ignore-marks-p
4211 (diredp-files-within (directory-files default-directory 'FULL diredp-re-no-dot)
4212 () nil include-dirs-p predicate)
4213 ;; Pass FILES and ASKP to `diredp-get-files-for-dir', so we don't have to use them as
4214 ;; free vars there. But that means that they each need to be a cons cell that we can
4215 ;; modify, so we can get back the updated info.
4216 (let ((files (list 'DUMMY))) ; The files picked up will be added to this list.
4217 (diredp-get-files-for-dir default-directory files askp include-dirs-p only-marked-p)
4218 (setq files (cdr files)) ; Remove `DUMMY' from the modifed list.
4219 (if (or dont-askp
4220 (not (car askp))
4221 (diredp-y-or-n-files-p "Use marked (instead of all) in subdir Dired buffers? "
4222 files
4223 predicate))
4224 (if predicate (diredp-remove-if-not predicate files) files)
4225 (setq files ())
4226 (dolist (file (diredp-marked-here))
4227 (if (not (file-directory-p file))
4228 (when (or (not predicate) (funcall predicate file))
4229 (add-to-list 'files file))
4230 (when include-dirs-p (setq files (nconc files (list file))))
4231 (setq files (nconc files (diredp-files-within (directory-files file 'FULL diredp-re-no-dot)
4232 () nil include-dirs-p predicate)))))
4233 (nreverse files))))))
4234
4235(defun diredp-get-files-for-dir (directory accum askp &optional include-dirs-p only-marked-p)
4236 "Return marked file names for DIRECTORY and subdirectories, recursively.
4237Pick up names of all marked files in DIRECTORY if it has a Dired
4238buffer, or all files in DIRECTORY if not. Handle subdirs recursively
4239\(only marked subdirs, if Dired).
4240
4241ACCUM is an accumulator list: the files picked up in this call are
4242nconc'd to it.
4243
4244ASKP is a one-element list, the element indicating whether to ask the
4245user about respecting Dired markings. It is set here to `t' if there
4246is a Dired buffer for DIRECTORY.
4247
4248Non-nil optional arg INCLUDE-DIRS-P means include marked subdirectory
4249names (but also handle those subdirs recursively).
4250
4251Non-nil optional arg ONLY-MARKED-P means collect only marked files,
4252instead of collecting all files if none are marked.
4253
4254If there is more than one Dired buffer for DIRECTORY then raise an
4255error."
4256 (let ((dbufs (dired-buffers-for-dir (expand-file-name directory))))
4257 (dolist (file (if (not dbufs)
4258 (and (not only-marked-p) (directory-files directory 'FULL diredp-re-no-dot))
4259 (when (cadr dbufs) (error "More than one Dired buffer for `%s'" directory))
4260 (unless (equal directory default-directory) (setcar askp t))
4261 (with-current-buffer (car dbufs) (diredp-marked-here only-marked-p 'NO-DOT-DOT))))
4262 (if (not (file-directory-p file))
4263 (setcdr (last accum) (list file))
4264 (when include-dirs-p (setcdr (last accum) (list file)))
4265 (diredp-get-files-for-dir file accum askp include-dirs-p only-marked-p)))))
4266
4267(defun diredp-marked-here (&optional only-marked-p no-dot-dot-p)
4268 "Marked files and subdirs in this Dired buffer, or all if none are marked.
4269Non-nil optional arg ONLY-MARKED-P means return nil if none are
4270marked.
4271Non-nil optional arg NO-DOT-DOT-P means do not include marked `..'."
4272 ;; If no file is marked, exclude `(FILENAME)': the unmarked file at cursor.
4273 ;; If there are no marked files as a result, return all files and subdirs in the dir.
4274 (let* ((dired-marker-char ?*)
4275 (ff (condition-case nil ; Ignore error if on `.' or `..' and no file is marked.
4276 (dired-get-marked-files
4277 nil nil (and no-dot-dot-p
4278 (lambda (mf) (not (diredp-string-match-p "/\\.\\.$" mf))))
4279 'DISTINGUISH-ONE-MARKED)
4280 (error nil))))
4281 (cond ((eq t (car ff)) (cdr ff)) ; Single marked
4282 ((cadr ff) ff) ; Multiple marked
4283 (t (and (not only-marked-p) ; None marked
4284 (directory-files default-directory 'FULL diredp-re-no-dot 'NOSORT))))))
4285
4286(defun diredp-y-or-n-files-p (prompt files &optional predicate)
4287 "PROMPT user with a \"y or n\" question about a list of FILES.
4288Return t if answer is \"y\". Otherwise, return nil.
4289
4290Like `y-or-n-p', but you can also hit `l' to display the list of files
4291that the confirmation is for, in buffer `*Files'. In that `'l'
4292listing you can mouseover to see image-file previews or use `RET' or
4293`mouse-2' to visit files.
4294
4295When finished, buffer `*Files*' is killed if it was never shown, or is
4296hidden and buried otherwise. Thus, if it was shown then it is still
4297available to revisit afterward (even if you quit using `C-g').
4298
4299PREDICATE is passed to `diredp-list-files', to list only file names
4300for which it returns non-nil."
4301 (let ((answer 'recenter))
4302 (cond (noninteractive
4303 (setq prompt (concat prompt
4304 (and (not (eq ?\ (aref prompt (1- (length prompt))))) " ")
4305 "(y or n; l to show file list) "))
4306 (let ((temp-prompt prompt))
4307 (while (not (memq answer '(act skip)))
4308 (let ((str (read-string temp-prompt)))
4309 (cond ((member str '("y" "Y")) (setq answer 'act))
4310 ((member str '("n" "N")) (setq answer 'skip))
4311 (t (setq temp-prompt (concat "Please answer y or n. " prompt))))))))
4312 ((if (not (fboundp 'display-popup-menus-p))
4313 (and window-system (listp last-nonmenu-event) use-dialog-box)
4314 (and (display-popup-menus-p) (listp last-nonmenu-event) use-dialog-box))
4315 (setq answer (x-popup-dialog t `(,prompt ("Yes" . act) ("No" . skip)))))
4316 (t
4317 (let ((list-buf (generate-new-buffer-name "*Files*"))
4318 (list-was-shown nil))
4319 (unwind-protect
4320 (progn
4321 (define-key query-replace-map "l" 'show)
4322 (setq prompt (concat prompt
4323 (and (eq ?\ (aref prompt (1- (length prompt))))
4324 "" " ")
4325 "(y or n; l to show file list) "))
4326 (while (let* ((reprompt-actions '(recenter scroll-up scroll-down
4327 scroll-other-window scroll-other-window-down))
4328 (key (let ((cursor-in-echo-area t))
4329 (when minibuffer-auto-raise
4330 (raise-frame (window-frame (minibuffer-window))))
4331 (if (fboundp 'read-key)
4332 (read-key (propertize
4333 (if (memq answer reprompt-actions)
4334 prompt
4335 (concat "Please answer y or n. " prompt))
4336 'face 'minibuffer-prompt))
4337 (read-char-exclusive
4338 (if (memq answer reprompt-actions)
4339 prompt
4340 (concat "Please answer y or n. " prompt)))))))
4341 (setq answer (lookup-key query-replace-map (vector key) t))
4342 (case answer
4343 ((skip act) nil)
4344 (recenter (recenter) t)
4345 (show (diredp-list-files files nil list-buf predicate)
4346 (setq list-was-shown t)) ; Record showing it.
4347 (help (message "Use `l' to show file list") (sit-for 1))
4348 (scroll-up (condition-case nil (scroll-up-command) (error nil)) t)
4349 (scroll-down (condition-case nil (scroll-down-command) (error nil)) t)
4350 (scroll-other-window (condition-case nil (scroll-other-window) (error nil)) t)
4351 (scroll-other-window-down (condition-case nil (scroll-other-window-down nil)
4352 (error nil)) t)
4353 ((exit-prefix quit) (signal 'quit nil) t)
4354 (t (or (not (eq key ?\e)) (progn (signal 'quit nil) t)))))
4355 (ding)
4356 (discard-input)))
4357 (when (get-buffer list-buf)
4358 (save-window-excursion (pop-to-buffer list-buf)
4359 (condition-case nil ; Ignore error if user already deleted.
4360 (if (one-window-p) (delete-frame) (delete-window))
4361 (error nil))
4362 (if list-was-shown (bury-buffer list-buf) (kill-buffer list-buf))))
4363 (define-key query-replace-map "l" nil)))))
4364 (let ((ret (eq answer 'act)))
4365 (unless noninteractive (message "%s %s" prompt (if ret "y" "n")))
4366 ret)))
4367
4368(defvar diredp-list-files-map
4369 (let ((map (make-sparse-keymap)))
4370 (define-key map "q" 'quit-window)
4371 (define-key map "\r" 'diredp-find-line-file-other-window)
4372 (define-key map [mouse-2] 'diredp-mouse-find-line-file-other-window)
4373 map)
4374 "Keymap for `diredp-list-files' output.")
4375(fset 'diredp-list-files-map diredp-list-files-map)
4376
4377;;;###autoload
4378(defun diredp-find-line-file-other-window ()
4379 "Visit file named by current line, in another window.
4380The full text of the line is used as the file name."
4381 (interactive)
4382 (let ((file (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
4383 (when file (find-file-other-window file))))
4384
4385;;;###autoload
4386(defun diredp-mouse-find-line-file-other-window (e)
4387 "Visit file named by clicked line, in another window.
4388The full text of the line is used as the file name."
4389 (interactive "e")
4390 (save-excursion (mouse-set-point e) (diredp-find-line-file-other-window)))
4391
4392;;;###autoload
4393(defun diredp-list-marked (&optional arg predicate interactivep) ; Bound to `C-M-l'
4394 "List the marked files in this Dired buffer.
4395A prefix arg specifies files to use instead of the marked files:
4396
4397 * Numeric prefix arg N: The next N files (previous -N, if < 0).
4398 * C-u C-u: All files, but no directories.
4399 * C-u C-u C-u: All files and directories, except `.' and `..'
4400 * C-u C-u C-u C-u: All files and directories, including `.' and `..'
4401 * Any other prefix arg: The current line's file only.
4402
4403You can use `RET' or `mouse-2' to visit any of the files.
4404If `tooltip-mode' is on then moving the mouse over image-file names
4405shows image previews.
4406
4407Non-interactively, non-nil arg PREDICATE is a file-name predicate.
4408List only the files for which it returns non-nil."
4409 (interactive (progn (diredp-ensure-mode) (list current-prefix-arg nil t)))
4410 (let ((files (dired-get-marked-files nil arg predicate 'DISTINGUISH-ONE interactivep)))
4411 (diredp-list-files files)))
4412
4413(defun diredp-list-files (files &optional dir bufname predicate)
4414 "Display FILES, a list of file names. Wildcard patterns are expanded.
4415The files are shown in a new buffer, `*Files*' by default.
4416
4417Optional arg DIR serves as the default directory for expanding file
4418 names that are not absolute. It defaults to `default-directory'.
4419
4420Optional arg BUFNAME is the name of the buffer for the display.
4421 It defaults to `*Files*' (or `*Files*<N>' if `*Files*' exists).
4422
4423Optional arg PREDICATE is a predicate used to filter FILES: only files
4424 satisfying PREDICATE are listed.
4425
4426File names listed are absolute. Mouseover gives help or an image-file
4427preview, and you can use `RET' or `mouse-2' to visit files."
4428 (unless bufname (setq bufname (generate-new-buffer-name "*Files*")))
4429 (diredp-with-help-window bufname
4430 (princ "Files\n-----\n\n")
4431 (let ((all-files-no-wildcards ())
4432 file-alist file-dir)
4433 (dolist (file files)
4434 (unless (or (string= file "") ; Ignore empty file names.
4435 (and predicate (not (funcall predicate file))))
4436 (if (not (diredp-string-match-p "[[?*]" file))
4437 (add-to-list 'all-files-no-wildcards (expand-file-name file))
4438 (setq file-dir (or (file-name-directory file) default-directory)
4439 file-alist (directory-files-and-attributes file-dir 'FULL "[[?*]" 'NOSORT))
4440 (dolist (ff file-alist)
4441 (add-to-list 'all-files-no-wildcards (expand-file-name (car ff) file-dir))))))
4442 (save-excursion (dolist (fff (nreverse all-files-no-wildcards))
4443 (princ fff)
4444 (terpri)))))
4445 (with-current-buffer bufname
4446 (let ((buffer-read-only nil))
4447 (save-excursion
4448 (goto-char (point-min))
4449 (forward-line 3)
4450 (while (not (eobp))
4451 (add-text-properties (line-beginning-position) (line-end-position)
4452 '(mouse-face highlight
4453 help-echo diredp-mouseover-help
4454 dired-filename t
4455 ;; `keymap' does not work for Emacs 20. Could use `local-map'
4456 ;; but that still leaves `RET' bound to `help-follow'.
4457 keymap diredp-list-files-map))
4458 (forward-line 1))))
4459 (set-buffer-modified-p nil)
4460 (setq buffer-read-only t)
4461 (buffer-enable-undo)))
4462
4463(defvar diredp-files-within-dirs-done ()
4464 "Directories already processed by `diredp-files-within'.")
4465
4466
4467;; Not used in the `Dired+' code yet.
4468(defun diredp-directories-within (&optional directory no-symlinks-p predicate)
4469 "List of accessible directories within DIRECTORY.
4470Directories in `icicle-ignored-directories' are skipped, if you use
4471Icicles. Otherwise, directories in `vc-directory-exclusion-list' are
4472skipped.
4473
4474Optional arg DIRECTORY defaults to the value of `default-directory'.
4475Non-nil optional arg NO-SYMLINKS-P means do not follow symbolic links.
4476Non-nil optional arg PREDICATE must be a function that accepts a
4477 file-name argument. Only directories that satisfy PREDICATE are
4478 included in the result."
4479 (unless directory (setq directory default-directory))
4480 (let ((dirs (diredp-files-within (directory-files directory 'FULL diredp-re-no-dot)
4481 () no-symlinks-p 'INCLUDE-DIRS-P
4482 #'file-directory-p)))
4483 (if predicate (diredp-remove-if-not predicate dirs) dirs)))
4484
4485;; Args INCLUDE-DIRS-P and PREDICATE are not used in the `Dired+' code yet
4486;; (except in `diredp-directories-within', which also is not used yet).
4487;;
4488(defun diredp-files-within (file-list accum &optional no-symlinks-p include-dirs-p predicate)
4489 "List of readable files in FILE-LIST, handling directories recursively.
4490FILE-LIST is a list of file names or a function that returns such.
4491If a function then invoke it with no args to get the list of files.
4492
4493Accessible directories in the list of files are processed recursively
4494to include their files and the files in their subdirectories. The
4495directories themselves are not included, unless optional arg
4496INCLUDE-DIRS-P is non-nil. (Directories in
4497`icicle-ignored-directories' are skipped, if you use Icicles.
4498Otherwise, directories in `vc-directory-exclusion-list' are skipped.)
4499
4500But if there is a Dired buffer for such a directory, and if FILE-LIST
4501is a function, then it is invoked in that Dired buffer to return the
4502list of files to use. E.g., if FILE-LIST is `dired-get-marked-files'
4503then only the marked files and subdirectories are included. If you
4504have more than one Dired buffer for a directory that is processed
4505here, then only the first one in `dired-buffers' is used.
4506
4507The list of files is accumulated in ACCUM, which is used for recursive
4508calls.
4509
4510Non-nil optional arg NO-SYMLINKS-P means do not follow symbolic links.
4511
4512Non-nil optional arg INCLUDE-DIRS-P means include directory names
4513along with the names of non-directories.
4514
4515Non-nil optional arg PREDICATE must be a function that accepts a
4516file-name argument. Only files (and possibly directories) that
4517satisfy PREDICATE are included in the result."
4518 ;; Bind `diredp-files-within-dirs-done' for use as a free var in `diredp-files-within-1'.
4519 (let ((diredp-files-within-dirs-done ()))
4520 (nreverse (diredp-files-within-1 file-list accum no-symlinks-p include-dirs-p predicate))))
4521
4522;; `diredp-files-within-dirs-done' is free here, bound in `diredp-files-within'.
4523(defun diredp-files-within-1 (file-list accum no-symlinks-p include-dirs-p predicate)
4524 "Helper for `diredp-files-within'."
4525 (let ((files (if (functionp file-list) (funcall file-list) file-list))
4526 (res accum)
4527 file)
4528 (when (and files predicate) (setq files (diredp-remove-if-not predicate files)))
4529 (while files
4530 (setq file (car files))
4531 (unless (and no-symlinks-p (file-symlink-p file))
4532 (if (file-directory-p file)
4533 ;; Skip directory if ignored, already treated, or inaccessible.
4534 (when (and (not (member (file-name-nondirectory file)
4535 (if (boundp 'icicle-ignored-directories)
4536 icicle-ignored-directories
4537 (and (boundp 'vc-directory-exclusion-list)
4538 vc-directory-exclusion-list))))
4539 (not (member (file-truename file) diredp-files-within-dirs-done))
4540 (file-accessible-directory-p file))
4541 (setq res (diredp-files-within-1 (or (and (functionp file-list)
4542 (dired-buffers-for-dir
4543 (expand-file-name file)) ; Removes killed buffers.
4544 (with-current-buffer
4545 (cdr (assoc (file-name-as-directory file)
4546 dired-buffers))
4547 (funcall file-list)))
4548 (directory-files file 'FULL diredp-re-no-dot))
4549 res no-symlinks-p include-dirs-p predicate))
4550 (when include-dirs-p (push file res))
4551 (push (file-truename file) diredp-files-within-dirs-done))
4552 (when (file-readable-p file) (push file res))))
4553 (pop files))
4554 res))
4555
4556(defun diredp-remove-if (pred xs)
4557 "A copy of list XS with no elements that satisfy predicate PRED."
4558 (let ((result ()))
4559 (dolist (x xs) (unless (funcall pred x) (push x result)))
4560 (nreverse result)))
4561
4562(defun diredp-remove-if-not (pred xs)
4563 "A copy of list XS with only elements that satisfy predicate PRED."
4564 (let ((result ()))
4565 (dolist (x xs) (when (funcall pred x) (push x result)))
4566 (nreverse result)))
4567
4568(when (> emacs-major-version 21) ; Emacs 20 has no PREDICATE arg to `read-file-name'.
4569 (defun diredp-insert-as-subdir (child ancestor &optional in-dired-now-p)
4570 "Insert the current Dired dir into a Dired listing of an ancestor dir.
4571Ancestor means parent, grandparent, etc. at any level.
4572You are prompted for the ancestor directory.
4573The ancestor Dired buffer is selected.
4574
4575Markings and switches in the current Dired buffer are preserved for
4576the subdir listing in the ancestor Dired buffer.
4577
4578Note: If you use Icicles, then you can use
4579`icicle-dired-insert-as-subdir' instead: it is a multi-command. It
4580does the same thing, but it lets you insert any number of descendent
4581directories into a given ancestor-directory Dired buffer.
4582
4583Non-interactively:
4584 Insert CHILD dir into Dired listing for ANCESTOR dir.
4585
4586 Non-nil optional arg IN-DIRED-NOW-P means to use the current buffer
4587 as the Dired buffer from which to pick up markings and switches.
4588 Otherwise, pick them up from a Dired buffer for CHILD, if there is
4589 exactly one such buffer."
4590 (interactive (progn (diredp-ensure-mode)
4591 (list default-directory
4592 (completing-read
4593 "Insert this dir into ancestor dir: "
4594 (mapcar #'list (diredp-ancestor-dirs default-directory)))
4595 t)))
4596 (let ((child-dired-buf (if in-dired-now-p
4597 (current-buffer)
4598 (dired-buffers-for-dir (expand-file-name child))))
4599 (switches ())
4600 (marked ()))
4601 (when (consp child-dired-buf)
4602 (setq child-dired-buf (and (= 1 (length child-dired-buf)) (car child-dired-buf))))
4603 (when child-dired-buf
4604 (with-current-buffer child-dired-buf
4605 (setq switches dired-actual-switches
4606 marked (dired-remember-marks (point-min) (point-max)))))
4607 (dired-other-window ancestor)
4608 (dired-insert-subdir child switches)
4609 (when marked (let ((inhibit-read-only t)) (dired-mark-remembered marked)))
4610 (set-buffer-modified-p nil))))
4611
4612(defun diredp-ancestor-dirs (dir)
4613 "Return a list of the ancestor directories of directory DIR."
4614 (mapcar #'file-name-as-directory
4615 (diredp-maplist (lambda (dd) (mapconcat #'identity (reverse dd) "/"))
4616 (cdr (nreverse (split-string dir "/" t))))))
4617
4618(defun diredp-maplist (function list)
4619 "Map FUNCTION over LIST and its cdrs.
4620A simple, recursive version of the classic `maplist'."
4621 (and list (cons (funcall function list) (diredp-maplist function (cdr list)))))
4622
4623(defun diredp-existing-dired-buffer-p (buffer-name)
4624 "Return non-nil if BUFFER-NAME names a live, existing Dired buffer."
4625 (let ((dbuf (get-buffer buffer-name)))
4626 (and dbuf (buffer-live-p dbuf) (rassq dbuf dired-buffers))))
4627
4628;; From `cl-seq.el', function `union', without keyword treatment.
4629;; (Same as `icicle-set-union' in `icicles-fn.el'.)
4630(defun diredp-set-union (list1 list2)
4631 "Combine LIST1 and LIST2 using a set-union operation.
4632The result list contains all items that appear in either LIST1 or
4633LIST2. Comparison is done using `equal'. This is a non-destructive
4634function; it copies the data if necessary."
4635 (cond ((null list1) list2)
4636 ((null list2) list1)
4637 ((equal list1 list2) list1)
4638 (t
4639 (unless (>= (length list1) (length list2))
4640 (setq list1 (prog1 list2 (setq list2 list1)))) ; Swap them.
4641 (while list2
4642 (unless (member (car list2) list1) (setq list1 (cons (car list2) list1)))
4643 (setq list2 (cdr list2)))
4644 list1)))
4645
4646(defvar diredp-last-copied-filenames ()
4647 "String list of file names last copied to the `kill-ring'.
4648Copying is done by `dired-copy-filename-as-kill' and related commands.")
4649
4650
4651;; REPLACE ORIGINAL in `dired-x.el'.
4652;;
4653;; Put text copied to kill ring in variable `diredp-last-copied-filenames'.
4654;;
4655(defun dired-copy-filename-as-kill (&optional arg)
4656 "Copy names of marked (or next ARG) files into the kill ring.
4657The names are separated by a space.
4658With a zero prefix arg, use the absolute file name of each marked file.
4659With \\[universal-argument], use the file name relative to the Dired buffer's
4660`default-directory'. (This still may contain slashes if in a subdirectory.)
4661
4662If on a subdir headerline, use absolute subdirname instead;
4663prefix arg and marked files are ignored in this case.
4664
4665You can then feed the file name(s) to other commands with \\[yank].
4666
4667The value of global variable `diredp-last-copied-filenames' is updated
4668to the string list of file name(s), so you can obtain it even after
4669the kill ring is modified."
4670 (interactive "P")
4671 (let* ((num-arg (prefix-numeric-value arg))
4672 (string (or (dired-get-subdir)
4673 (mapconcat #'identity
4674 (cond ((not arg) (dired-get-marked-files 'no-dir))
4675 ((zerop num-arg) (dired-get-marked-files))
4676 ((consp arg) (dired-get-marked-files t))
4677 (t (dired-get-marked-files 'no-dir num-arg)))
4678 " "))))
4679 (unless (string= "" string)
4680 (if (eq last-command 'kill-region) (kill-append string nil) (kill-new string))
4681 (setq diredp-last-copied-filenames (car kill-ring-yank-pointer))
4682 (message "%s" string))))
4683
4684(defun diredp-copy-abs-filenames-as-kill () ; Not bound.
4685 "Copy absolute names of marked files in Dired to the kill ring.
4686Also set variable `diredp-last-copied-filenames' to the string that
4687lists the file names.
4688
4689This is the same as using a zero prefix arg with command
4690`dired-copy-filename-as-kill', that is, \\<dired-mode-map>`M-0 \\[dired-copy-filename-as-kill]'."
4691 (interactive (diredp-ensure-mode))
4692 (dired-copy-filename-as-kill 0))
4693
4694;;;###autoload
4695(defalias 'diredp-paste-files 'diredp-yank-files) ; Bound to `C-y'.
4696;;;###autoload
4697(defun diredp-yank-files (&optional dir no-confirm-p)
4698 "Paste files, whose absolute names you copied, to the current directory.
4699With a prefix arg you are instead prompted for the target directory.
4700
4701You should have copied the list of file names as a string to the kill
4702ring using \\<dired-mode-map>`M-0 \\[dired-copy-filename-as-kill]' or \
4703\\[diredp-copy-abs-filenames-as-kill].
4704Those commands also set variable `diredp-last-copied-filenames' to the
4705same string. `diredp-yank-files' uses the value of that variable, not
4706whatever is currently at the head of the kill ring.
4707
4708When called from Lisp, optional arg NO-CONFIRM-P means do not ask for
4709confirmation to copy."
4710 (interactive (and current-prefix-arg
4711 (list (expand-file-name (read-directory-name "Yank files to directory: ")))))
4712 (setq dir (or dir (and (derived-mode-p 'dired-mode) (dired-current-directory))))
4713 (unless (file-directory-p dir) (error "Not a directory: `%s'" dir))
4714 (let ((files diredp-last-copied-filenames))
4715 (unless (stringp files) (error "No copied file names"))
4716 (setq files (diredp-delete-if-not (lambda (file) (file-name-absolute-p file)) (split-string files)))
4717 (unless files (error "No copied absolute file names (Did you use `M-0 w'?)"))
4718 (if (and (not no-confirm-p)
4719 (diredp-y-or-n-files-p "Paste files whose names you copied? " files))
4720 (dired-create-files #'dired-copy-file "Copy" files
4721 (lambda (from)
4722 (expand-file-name (file-name-nondirectory from) dir)))
4723 (message "OK, file-pasting canceled"))))
4724
4725
4726
4727;;; Commands operating on marked at all levels below (recursively)
4728
4729(defun diredp-get-confirmation-recursive (&optional type)
4730 "Get confirmation from user to act on all TYPE here and below.
4731If TYPE is nil use \"files\" in the confirmation prompt, else use TYPE.
4732Raise an error if not confirmed.
4733Raise an error first if not in Dired mode."
4734 (diredp-ensure-mode)
4735 (unless (y-or-n-p (format "Act on ALL %s (or all marked if any) in and UNDER this dir? "
4736 (or type 'files)))
4737 (error "OK, canceled")))
4738
4739;;;###autoload
4740(when (> emacs-major-version 21) ; Emacs 22+ has KILL-ROOT parameter.
4741 (defun diredp-kill-this-tree ()
4742 "Remove this subdir listing and lower listings."
4743 (interactive)
4744 (dired-kill-tree (dired-current-directory) nil 'KILL-ROOT)))
4745
4746;;;###autoload
4747(defun diredp-insert-subdirs (&optional switches interactivep) ; Bound to `M-i'
4748 "Insert the marked subdirectories.
4749Like using \\<dired-mode-map>`\\[dired-maybe-insert-subdir]' at each marked directory line."
4750 (interactive (list (and current-prefix-arg
4751 (read-string "Switches for listing: "
4752 (or (and (boundp 'dired-subdir-switches) dired-subdir-switches)
4753 dired-actual-switches)))
4754 t))
4755 (dolist (subdir (dired-get-marked-files nil
4756 nil
4757 (lambda (fl) (and (file-directory-p fl) ; Exclude `.' and `..'
4758 (not (diredp-string-match-p "/[.][.]?\\'" fl))))
4759 nil
4760 interactivep))
4761 (dired-maybe-insert-subdir subdir switches)))
4762
4763;;;###autoload
4764(defun diredp-insert-subdirs-recursive (&optional ignore-marks-p) ; Bound to `M-+ M-i'
4765 "Insert the marked subdirs, including those in marked subdirs.
4766Like `diredp-insert-subdirs', but act recursively on subdirs.
4767The subdirs inserted are those that are marked in the current Dired
4768buffer, or ALL subdirs in the directory if none are marked. Marked
4769subdirectories are handled recursively in the same way (their marked
4770subdirs are inserted...).
4771
4772With a prefix argument, ignore all marks - include all files in this
4773Dired buffer and all subdirs, recursively."
4774 (interactive (progn (diredp-get-confirmation-recursive 'subdirs) (list current-prefix-arg)))
4775 (dolist (subdir (diredp-get-files ignore-marks-p #'file-directory-p 'INCLUDE-SUBDIRS-P))
4776 (dired-maybe-insert-subdir subdir)))
4777
4778;;;###autoload
4779(defun diredp-do-shell-command-recursive (command &optional ignore-marks-p) ; Bound to `M-+ !'
4780 "Run shell COMMAND on the marked files, including those in marked subdirs.
4781Like `dired-do-shell-command', but act recursively on subdirs.
4782The files included are those that are marked in the current Dired
4783buffer, or all files in the directory if none are marked. Marked
4784subdirectories are handled recursively in the same way.
4785
4786With a prefix argument, ignore all marks - include all files in this
4787Dired buffer and all subdirs, recursively."
4788 (interactive
4789 (progn (diredp-get-confirmation-recursive)
4790 (let* ((prompt "! on *: ")
4791 (cmd (minibuffer-with-setup-hook
4792 (lambda ()
4793 (set (make-local-variable 'minibuffer-default-add-function)
4794 'minibuffer-default-add-dired-shell-commands))
4795 (let ((dired-no-confirm t))
4796 (if (functionp 'dired-guess-shell-command)
4797 ;; Guess cmd based only on files marked in current (top) dir.
4798 (dired-guess-shell-command prompt (dired-get-marked-files t))
4799 (read-shell-command prompt nil nil))))))
4800 (list cmd current-prefix-arg))))
4801 (dired-do-shell-command command nil (diredp-get-files ignore-marks-p)))
4802
4803(when (fboundp 'dired-do-async-shell-command) ; Emacs 23+
4804 (defun diredp-do-async-shell-command-recursive (command &optional ignore-marks-p)
4805 ; Bound to `M-+ &'
4806 "Run async shell COMMAND on marked files, including in marked subdirs.
4807Like `dired-do-async-shell-command', but act recursively on subdirs.
4808The files included are those that are marked in the current Dired
4809buffer, or all files in the directory if none are marked. Marked
4810subdirectories are handled recursively in the same way.
4811
4812With a prefix argument, ignore all marks - include all files in this
4813Dired buffer and all subdirs, recursively."
4814 (interactive
4815 (progn (diredp-get-confirmation-recursive)
4816 (let* ((prompt "! on *: ")
4817 (cmd (minibuffer-with-setup-hook
4818 (lambda ()
4819 (set (make-local-variable 'minibuffer-default-add-function)
4820 'minibuffer-default-add-dired-shell-commands))
4821 (let ((dired-no-confirm t))
4822 (if (functionp 'dired-guess-shell-command)
4823 ;; Guess cmd based only on files marked in current (top) dir.
4824 (dired-guess-shell-command prompt (dired-get-marked-files t))
4825 (read-shell-command prompt nil nil))))))
4826 (list cmd current-prefix-arg))))
4827 (dired-do-async-shell-command command nil (diredp-get-files ignore-marks-p))))
4828
4829;;;###autoload
4830(defun diredp-do-symlink-recursive (&optional ignore-marks-p) ; Bound to `M-+ S'
4831 "Make symbolic links to marked files, including those in marked subdirs.
4832Like `dired-do-symlink', but act recursively on subdirs to pick up the
4833files to link.
4834
4835The files included are those that are marked in the current Dired
4836buffer, or all files in the directory if none are marked. Marked
4837subdirectories are handled recursively in the same way.
4838
4839With a prefix argument, ignore all marks - include all files in this
4840Dired buffer and all subdirs, recursively."
4841 (interactive (progn (diredp-get-confirmation-recursive) (list current-prefix-arg)))
4842 (diredp-do-create-files-recursive #'make-symbolic-link "Symlink" ignore-marks-p))
4843
4844(when (fboundp 'dired-do-relsymlink)
4845 (defun diredp-do-relsymlink-recursive (&optional ignore-marks-p) ; Bound to `M-+ Y'
4846 "Relative symlink all marked files, including those in marked subdirs into a dir.
4847Like `dired-do-relsymlink', but act recursively on subdirs to pick up the
4848files to link.
4849
4850The files included are those that are marked in the current Dired
4851buffer, or all files in the directory if none are marked. Marked
4852subdirectories are handled recursively in the same way.
4853
4854With a prefix argument, ignore all marks - include all files in this
4855Dired buffer and all subdirs, recursively.
4856
4857For absolute symlinks, use \\[diredp-do-symlink-recursive]."
4858 (interactive (progn (diredp-get-confirmation-recursive) (list current-prefix-arg)))
4859 (diredp-do-create-files-recursive #'dired-make-relative-symlink "RelSymLink" ignore-marks-p)))
4860
4861;;;###autoload
4862(defun diredp-do-hardlink-recursive (&optional ignore-marks-p) ; Bound to `M-+ H'
4863 "Add hard links for marked files, including those in marked subdirs.
4864Like `dired-do-hardlink', but act recursively on subdirs to pick up the
4865files to link.
4866
4867The files included are those that are marked in the current Dired
4868buffer, or all files in the directory if none are marked. Marked
4869subdirectories are handled recursively in the same way.
4870
4871With a prefix argument, ignore all marks - include all files in this
4872Dired buffer and all subdirs, recursively."
4873 (interactive (progn (diredp-get-confirmation-recursive) (list current-prefix-arg)))
4874 (diredp-do-create-files-recursive #'dired-hardlink "Hardlink" ignore-marks-p))
4875
4876;;;###autoload
4877(defun diredp-do-print-recursive (&optional ignore-marks-p) ; Bound to `M-+ P'
4878 "Print the marked files, including those in marked subdirs.
4879Like `dired-do-print', but act recursively on subdirs to pick up the
4880files to print.
4881
4882The files included are those that are marked in the current Dired
4883buffer, or all files in the directory if none are marked. Marked
4884subdirectories are handled recursively in the same way.
4885
4886With a prefix argument, ignore all marks - include all files in this
4887Dired buffer and all subdirs, recursively."
4888 (interactive (progn (diredp-get-confirmation-recursive) (list current-prefix-arg)))
4889 (let* ((file-list (diredp-get-files ignore-marks-p))
4890 (command (dired-mark-read-string
4891 "Print %s with: "
4892 (mapconcat #'identity
4893 (cons lpr-command (if (stringp lpr-switches) (list lpr-switches) lpr-switches))
4894 " ")
4895 'print nil file-list)))
4896 (dired-run-shell-command (dired-shell-stuff-it command file-list nil))))
4897
4898;;;###autoload
4899(defun diredp-image-dired-display-thumbs-recursive (&optional ignore-marks-p append do-not-pop)
4900 ; Bound to `M-+ C-t d'
4901 "Display thumbnails of marked files, including those in marked subdirs.
4902Like `image-dired-display-thumbs', but act recursively on subdirs.
4903Optional arguments APPEND and DO-NOT-POP are as for
4904`image-dired-display-thumbs'.
4905
4906The files included are those that are marked in the current Dired
4907buffer, or all files in the directory if none are marked. Marked
4908subdirectories are handled recursively in the same way.
4909
4910With a prefix argument, ignore all marks - include all files in this
4911Dired buffer and all subdirs, recursively."
4912 (interactive (progn (diredp-image-dired-required-msg)
4913 (diredp-get-confirmation-recursive)
4914 (list current-prefix-arg)))
4915 (let ((buf (image-dired-create-thumbnail-buffer))
4916 thumb-name files dired-buf)
4917 (setq files (diredp-get-files ignore-marks-p)
4918 dired-buf (current-buffer))
4919 (with-current-buffer buf
4920 (let ((inhibit-read-only t))
4921 (if append (goto-char (point-max)) (erase-buffer))
4922 (mapc (lambda (curr-file)
4923 (setq thumb-name (image-dired-thumb-name curr-file))
4924 (if (and (not (file-exists-p thumb-name))
4925 (not (= 0 (image-dired-create-thumb curr-file thumb-name))))
4926 (message "Thumb could not be created for file %s" curr-file)
4927 (image-dired-insert-thumbnail thumb-name curr-file dired-buf)))
4928 files))
4929 (case image-dired-line-up-method
4930 (dynamic (image-dired-line-up-dynamic))
4931 (fixed (image-dired-line-up))
4932 (interactive (image-dired-line-up-interactive))
4933 (none nil)
4934 (t (image-dired-line-up-dynamic))))
4935 (if do-not-pop
4936 (display-buffer image-dired-thumbnail-buffer)
4937 (pop-to-buffer image-dired-thumbnail-buffer))))
4938
4939;;;###autoload
4940(defun diredp-image-dired-tag-files-recursive (&optional ignore-marks-p) ; Bound to `M-+ C-t t'
4941 "Tag marked files with an `image-dired' tag, including in marked subdirs.
4942Like `image-dired-tag-files', but act recursively on subdirs.
4943The files included are those that are marked in the current Dired
4944buffer, or all files in the directory if none are marked. Marked
4945subdirectories are handled recursively in the same way.
4946
4947With a prefix argument, ignore all marks - include all files in this
4948Dired buffer and all subdirs, recursively."
4949 (interactive (progn (diredp-image-dired-required-msg)
4950 (diredp-get-confirmation-recursive)
4951 (list current-prefix-arg)))
4952 (let ((tag (read-string "Tags to add (separate tags with a semicolon): ")))
4953 (image-dired-write-tags (mapcar (lambda (x) (cons x tag)) (diredp-get-files ignore-marks-p)))))
4954
4955;;;###autoload
4956(defun diredp-image-dired-delete-tag-recursive (&optional ignore-marks-p) ; Bound to `M-+ C-t r'
4957 "Remove `image-dired' tag for marked files, including in marked subdirs.
4958Like `image-dired-delete-tag', but act recursively on subdirs.
4959The files included are those that are marked in the current Dired
4960buffer, or all files in the directory if none are marked. Marked
4961subdirectories are handled recursively in the same way.
4962
4963With a prefix argument, ignore all marks - include all files in this
4964Dired buffer and all subdirs, recursively."
4965 (interactive (progn (diredp-image-dired-required-msg)
4966 (diredp-get-confirmation-recursive)
4967 (list current-prefix-arg)))
4968 (image-dired-remove-tag (diredp-get-files ignore-marks-p) (read-string "Tag to remove: ")))
4969
4970;;;###autoload
4971(defun diredp-image-dired-comment-files-recursive (&optional ignore-marks-p)
4972 ; Bound to `M-+ C-t c'
4973 "Add comment to marked files in dired, including those in marked subdirs.
4974Like `image-dired-dired-comment-files' but act recursively on subdirs.
4975The files included are those that are marked in the current Dired
4976buffer, or all files in the directory if none are marked. Marked
4977subdirectories are handled recursively in the same way.
4978
4979With a prefix argument, ignore all marks - include all files in this
4980Dired buffer and all subdirs, recursively."
4981 (interactive (progn (diredp-image-dired-required-msg)
4982 (diredp-get-confirmation-recursive)
4983 (list current-prefix-arg)))
4984 (let ((comment (image-dired-read-comment)))
4985 (image-dired-write-comments (mapcar (lambda (curr-file) (cons curr-file comment))
4986 (diredp-get-files ignore-marks-p)))))
4987
4988(when (> emacs-major-version 22)
4989 (defun diredp-do-decrypt-recursive (&optional ignore-marks-p) ; Bound to `M-+ : d'
4990 "Decrypt marked files, including those in marked subdirs.
4991Like `epa-dired-do-decrypt', but act recursively on subdirs to pick up
4992the files to decrypt.
4993
4994The files included are those that are marked in the current Dired
4995buffer, or all files in the directory if none are marked. Marked
4996subdirectories are handled recursively in the same way.
4997
4998With a prefix argument, ignore all marks - include all files in this
4999Dired buffer and all subdirs, recursively."
5000 (interactive (progn (diredp-get-confirmation-recursive) (list current-prefix-arg)))
5001 (dolist (file (diredp-get-files ignore-marks-p))
5002 (epa-decrypt-file (expand-file-name file)))
5003 (revert-buffer))
5004
5005
5006 (defun diredp-do-verify-recursive (&optional ignore-marks-p) ; Bound to `M-+ : v'
5007 "Verify marked files, including those in marked subdirs.
5008Like `epa-dired-do-verify', but act recursively on subdirs to pick up
5009the files to verify.
5010
5011The files included are those that are marked in the current Dired
5012buffer, or all files in the directory if none are marked. Marked
5013subdirectories are handled recursively in the same way.
5014
5015With a prefix argument, ignore all marks - include all files in this
5016Dired buffer and all subdirs, recursively."
5017 (interactive (progn (diredp-get-confirmation-recursive) (list current-prefix-arg)))
5018 (dolist (file (diredp-get-files ignore-marks-p))
5019 (epa-verify-file (expand-file-name file)))
5020 (revert-buffer))
5021
5022 (defun diredp-do-sign-recursive (&optional ignore-marks-p) ; Bound to `M-+ : s'
5023 "Sign marked files, including those in marked subdirs.
5024Like `epa-dired-do-sign', but act recursively on subdirs to pick up
5025the files to sign.
5026
5027The files included are those that are marked in the current Dired
5028buffer, or all files in the directory if none are marked. Marked
5029subdirectories are handled recursively in the same way.
5030
5031With a prefix argument, ignore all marks - include all files in this
5032Dired buffer and all subdirs, recursively."
5033 (interactive (progn (diredp-get-confirmation-recursive) (list current-prefix-arg)))
5034 (dolist (file (diredp-get-files ignore-marks-p))
5035 (epa-sign-file (expand-file-name file)
5036 (epa-select-keys (epg-make-context) "Select keys for signing.
5037If none are selected, the default secret key is used. ")
5038 (y-or-n-p "Make a detached signature? ")))
5039 (revert-buffer))
5040
5041 (defun diredp-do-encrypt-recursive (&optional ignore-marks-p) ; Bound to `M-+ : e'
5042 "Encrypt marked files, including those in marked subdirs.
5043Like `epa-dired-do-encrypt', but act recursively on subdirs to pick up
5044the files to encrypt.
5045
5046The files included are those that are marked in the current Dired
5047buffer, or all files in the directory if none are marked. Marked
5048subdirectories are handled recursively in the same way.
5049
5050With a prefix argument, ignore all marks - include all files in this
5051Dired buffer and all subdirs, recursively."
5052 (interactive (progn (diredp-get-confirmation-recursive) (list current-prefix-arg)))
5053 (dolist (file (diredp-get-files ignore-marks-p))
5054 (epa-encrypt-file (expand-file-name file)
5055 (epa-select-keys (epg-make-context) "Select recipients for encryption.
5056If none are selected, symmetric encryption is performed. ")))
5057 (revert-buffer)))
5058
5059;;;###autoload
5060(defun diredp-do-bookmark-recursive (&optional ignore-marks-p prefix) ; Bound to `M-+ M-b'
5061 "Bookmark the marked files, including those in marked subdirs.
5062Like `diredp-do-bookmark', but act recursively on subdirs.
5063The files included are those that are marked in the current Dired
5064buffer, or all files in the directory if none are marked. Marked
5065subdirectories are handled recursively in the same way.
5066
5067With a prefix argument, ignore all marks - include all files in this
5068Dired buffer and all subdirs, recursively."
5069 (interactive (progn (diredp-get-confirmation-recursive)
5070 (list current-prefix-arg
5071 (and diredp-prompt-for-bookmark-prefix-flag
5072 (read-string "Prefix for bookmark name: ")))))
5073 (dolist (file (diredp-get-files ignore-marks-p))
5074 (diredp-bookmark prefix file 'NO-MSG-P)))
5075
5076;;;###autoload
5077(defun diredp-do-bookmark-dirs-recursive (ignore-marks-p &optional msg-p)
5078 "Bookmark this Dired buffer and marked subdirectory Dired buffers, recursively.
5079Create a Dired bookmark for this directory and for each of its marked
5080subdirectories. Handle each of the marked subdirectory similarly:
5081bookmark it and its marked subdirectories, and so on, recursively.
5082Name each of these Dired bookmarks with the Dired buffer name.
5083
5084After creating the Dired bookmarks, create a sequence bookmark, named
5085`DIRBUF and subdirs', where DIRBUF is the name of the original buffer.
5086This bookmark represents the whole Dired tree rooted in the directory
5087where you invoked the command. Jumping to this sequence bookmark
5088restores all of the Dired buffers making up the tree, by jumping to
5089each of their bookmarks.
5090
5091With a prefix arg, bookmark the marked and unmarked subdirectory Dired
5092buffers, recursively, that is, ignore markings.
5093
5094Note:
5095
5096* If there is more than one Dired buffer for a given subdirectory then
5097 only the first such is used.
5098
5099* This command creates new bookmarks. It never updates or overwrites
5100 an existing bookmark.
5101
5102You need library `Bookmark+' for this command."
5103 (interactive (progn (unless (featurep 'bookmark+)
5104 (error "You need library `Bookmark+' for this command"))
5105 (diredp-get-confirmation-recursive 'subdirs)
5106 (list current-prefix-arg t)))
5107 (diredp-ensure-mode)
5108 (let ((sdirs (diredp-get-subdirs ignore-marks-p))
5109 (snames ())
5110 dbufs)
5111 (when (and msg-p sdirs) (message "Checking descendent directories..."))
5112 (dolist (dir (cons default-directory sdirs))
5113 (when (setq dbufs (dired-buffers-for-dir (expand-file-name dir))) ; Dirs with Dired buffers only.
5114 (with-current-buffer (car dbufs)
5115 (let ((bname (bookmark-buffer-name))
5116 (count 2))
5117 (while (and (bmkp-get-bookmark-in-alist bname 'NOERROR) (setq bname (format "%s[%d]" bname count))))
5118 (bookmark-set bname nil nil 'NO-UPDATE-P) ; Inhibit updating displayed list.
5119 (push bname snames)))))
5120 (let ((bname (format "%s and subdirs" (bookmark-buffer-name)))
5121 (count 2))
5122 (while (and (bmkp-get-bookmark-in-alist bname 'NOERROR) (setq bname (format "%s[%d]" bname count))))
5123 (bmkp-set-sequence-bookmark bname (nreverse snames) -1 'MSGP))
5124 (bmkp-refresh/rebuild-menu-list nil)))
5125
5126;;;###autoload
5127(defun diredp-do-bookmark-in-bookmark-file-recursive (bookmark-file ; Bound to `M-+ C-M-B', aka `M-+ C-M-S-b')
5128 &optional prefix ignore-marks-p
5129 bfile-bookmarkp)
5130 "Bookmark files here and below in BOOKMARK-FILE and save BOOKMARK-FILE.
5131Like `diredp-do-bookmark-in-bookmark-file', but act recursively on
5132subdirs. The files included are those that are marked in the current
5133Dired buffer, or all files in the directory if none are marked.
5134Marked subdirectories are handled recursively in the same way.
5135
5136With a prefix argument, ignore all marks - include all files in this
5137Dired buffer and all subdirs, recursively."
5138 (interactive
5139 (progn (diredp-get-confirmation-recursive)
5140 (let ((d-r-b-f-args (diredp-read-bookmark-file-args)))
5141 (list (car d-r-b-f-args) (cadr d-r-b-f-args) (car (cddr d-r-b-f-args))))))
5142 (diredp-do-bookmark-in-bookmark-file bookmark-file prefix nil bfile-bookmarkp
5143 (diredp-get-files ignore-marks-p)))
5144
5145;;;###autoload
5146(defun diredp-set-bookmark-file-bookmark-for-marked-recursive (bookmark-file
5147 &optional prefix arg)
5148 ; Bound to `M-+ C-M-b'
5149 "Bookmark the marked files and create a bookmark-file bookmark for them.
5150Like `diredp-set-bookmark-file-bookmark-for-marked', but act
5151recursively on subdirs.
5152
5153The files included are those that are marked in the current Dired
5154buffer, or all files in the directory if none are marked. Marked
5155subdirectories are handled recursively in the same way.
5156
5157With a prefix argument, ignore all marks - include all files in this
5158Dired buffer and all subdirs, recursively."
5159 (interactive (progn (diredp-get-confirmation-recursive)
5160 (diredp-read-bookmark-file-args)))
5161 (diredp-ensure-bookmark+)
5162 (diredp-do-bookmark-in-bookmark-file-recursive bookmark-file prefix arg 'CREATE-BOOKMARK-FILE-BOOKMARK))
5163
5164;;;###autoload
5165(defun diredp-do-find-marked-files-recursive (&optional arg) ; Bound to `M-+ F'
5166 "Find marked files simultaneously, including those in marked subdirs.
5167Like `dired-do-find-marked-files', but act recursively on subdirs.
5168The files included are those that are marked in the current Dired
5169buffer, or all files in the directory if none are marked. Marked
5170subdirectories are handled recursively in the same way.
5171
5172With (explicit) numeric prefix ARG >= 0, find the files but do not
5173display them.
5174
5175With numeric prefix ARG <= 0, ignore all marks - include all files in
5176this Dired buffer and all subdirs, recursively.
5177
5178Note that prefix-argument behavior is different for this command than
5179for `dired-do-find-marked-files'. In particular, a negative numeric
5180prefix arg does not cause the files to be shown in separate frames.
5181Only non-nil `pop-up-frames' (or equivalent configuration) causes
5182the files to be shown in separate frames."
5183 (interactive (progn (diredp-get-confirmation-recursive)
5184 (list current-prefix-arg)))
5185 (let ((narg (prefix-numeric-value arg)))
5186 (dired-simultaneous-find-file (diredp-get-files (<= narg 0)) (and arg (>= narg 0) narg))))
5187
5188(when (fboundp 'dired-do-isearch-regexp) ; Emacs 23+
5189 (defun diredp-do-isearch-recursive (&optional ignore-marks-p) ; Bound to `M-+ M-s a C-s'
5190 "Isearch the marked files, including those in marked subdirs.
5191With a prefix argument, ignore all marks - include all files in this
5192Dired buffer and all subdirs, recursively."
5193 (interactive (progn (diredp-get-confirmation-recursive) (list current-prefix-arg)))
5194 (multi-isearch-files (diredp-get-files ignore-marks-p)))
5195
5196 (defun diredp-do-isearch-regexp-recursive (&optional ignore-marks-p) ; `M-+ M-s a C-M-s'
5197 "Regexp-Isearch the marked files, including those in marked subdirs.
5198With a prefix argument, ignore all marks - include all files in this
5199Dired buffer and all subdirs, recursively."
5200 (interactive (progn (diredp-get-confirmation-recursive) (list current-prefix-arg)))
5201 (multi-isearch-files-regexp (diredp-get-files ignore-marks-p))))
5202
5203(defun diredp-do-search-recursive (regexp &optional ignore-marks-p) ; Bound to `M-+ A'
5204 "Regexp-search the marked files, including those in marked subdirs.
5205With a prefix argument, ignore all marks - include all files in this
5206Dired buffer and all subdirs, recursively.
5207
5208Stops when a match is found.
5209To continue searching for the next match, use `\\[tags-loop-continue]'."
5210 (interactive (progn (diredp-get-confirmation-recursive)
5211 (list (read-string "Search marked files (regexp): ")
5212 current-prefix-arg)))
5213 (tags-search regexp '(diredp-get-files ignore-marks-p)))
5214
5215;;;###autoload
5216(defun diredp-do-query-replace-regexp-recursive (from to &optional arg)
5217 ; Bound to `M-+ Q'
5218 "Do `query-replace-regexp' on marked files, including in marked subdirs.
5219Query-replace FROM with TO.
5220
5221Like `dired-do-query-replace', but act recursively on subdirs.
5222The files included are those that are marked in the current Dired
5223buffer, or all files in the directory if none are marked. Marked
5224subdirectories are handled recursively in the same way.
5225
5226With an (explicit) numeric prefix argument:
5227
5228* >= 0 means ignore all marks - include ALL files in this Dired buffer
5229 and all subdirs, recursively.
5230
5231* <= 0 means replace only word-delimited matches.
5232
5233If you exit (`\\[keyboard-quit]', `RET' or `q'), you can resume the query replacement
5234using `\\[tags-loop-continue]'."
5235 (interactive (progn (diredp-get-confirmation-recursive)
5236 (let ((common (query-replace-read-args "Query replace regexp in marked files" t t)))
5237 (list (nth 0 common)
5238 (nth 1 common)
5239 current-prefix-arg))))
5240 (let* ((narg (and arg (prefix-numeric-value arg)))
5241 (delimited (and narg (<= narg 0)))
5242 (ignore-marks-p (and narg (>= narg 0)))
5243 (files (diredp-get-files ignore-marks-p))
5244 (fit-frame-min-width 30)
5245 (fit-frame-min-height 15))
5246 (dolist (file files)
5247 (let ((buffer (get-file-buffer file)))
5248 (when (and buffer (with-current-buffer buffer buffer-read-only))
5249 (error "File `%s' is visited read-only" file))))
5250 (tags-query-replace from to delimited `',files)))
5251
5252;;;###autoload
5253(defun diredp-do-grep-recursive (command-args) ; Bound to `M+ C-M-G'
5254 "Run `grep' on marked files, including those in marked subdirs.
5255Like `diredp-do-grep', but act recursively on subdirs.
5256The files included are those that are marked in the current Dired
5257buffer, or all files in the directory if none are marked. Marked
5258subdirectories are handled recursively in the same way.
5259
5260With a prefix argument, ignore all marks - include all files in this
5261Dired buffer and all subdirs, recursively."
5262 (interactive (progn (diredp-get-confirmation-recursive)
5263 (unless (if (< emacs-major-version 22)
5264 grep-command
5265 (and grep-command (or (not grep-use-null-device) (eq grep-use-null-device t))))
5266 (grep-compute-defaults))
5267 (list (diredp-do-grep-1 (diredp-get-files current-prefix-arg)))))
5268 (grep command-args))
5269
5270;;;###autoload
5271(defun diredp-marked-recursive (dirname &optional ignore-marks-p) ; Not bound to a key
5272 "Open Dired on marked files, including those in marked subdirs.
5273Like `diredp-marked', but act recursively on subdirs.
5274
5275See `diredp-do-find-marked-files-recursive' for a description of the
5276files included. In particular, if no files are marked here or in a
5277marked subdir, then all files in the directory are included.
5278
5279With a prefix argument, ignore all marks - include all files in this
5280Dired buffer and all subdirs, recursively.
5281
5282When called from Lisp, DIRNAME here must be a string, not a cons. It
5283is used as the name of the new Dired buffer."
5284 (interactive (progn (diredp-get-confirmation-recursive) (list nil current-prefix-arg)))
5285 (dired (cons (or dirname (generate-new-buffer-name (buffer-name))) (diredp-get-files ignore-marks-p))))
5286
5287;;;###autoload
5288(defun diredp-marked-recursive-other-window (dirname &optional ignore-marks-p) ; Bound to `M-+ C-M-*'
5289 "Same as `diredp-marked-recursive', but uses a different window."
5290 (interactive (progn (diredp-get-confirmation-recursive) (list nil current-prefix-arg)))
5291 (dired-other-window
5292 (cons (or dirname (generate-new-buffer-name (buffer-name))) (diredp-get-files ignore-marks-p))))
5293
5294;;;###autoload
5295(defun diredp-list-marked-recursive (&optional ignore-marks-p predicate) ; Bound to `M-+ C-M-l'
5296 "List the files marked here and in marked subdirs, recursively.
5297The files included are those that are marked in the current Dired
5298buffer, or all files in the directory if none are marked. Marked
5299subdirectories are handled recursively in the same way.
5300
5301With a prefix argument, all marks are ignored: all files in this Dired
5302buffer and all descendent directories are included.
5303
5304You can use `RET' or `mouse-2' to visit any of the files.
5305If `tooltip-mode' is on then moving the mouse over image-file names
5306shows image previews.
5307
5308Non-interactively, non-nil arg PREDICATE is a file-name predicate.
5309List only the files for which it returns non-nil."
5310 (interactive ; No need for `diredp-get-confirmation-recursive' here.
5311 (progn (diredp-ensure-mode) (list current-prefix-arg)))
5312 (let ((files (diredp-get-files ignore-marks-p predicate))) (diredp-list-files files)))
5313
5314;;;###autoload
5315(defun diredp-flag-auto-save-files-recursive (&optional arg) ; `M-+ #'
5316 "Flag all auto-save files for deletion, including in marked subdirs.
5317A non-negative prefix arg means to unmark (unflag) them instead.
5318
5319A non-positive prefix arg means to ignore subdir markings and act
5320instead on ALL subdirs. That is, flag all in this directory and all
5321descendant directories."
5322 (interactive "P")
5323 (let ((dired-marker-char dired-del-marker))
5324 (diredp-mark-recursive-1 arg "auto-save files" "auto-save file" '(diredp-looking-at-p "^.* #.+#$"))))
5325
5326(when (fboundp 'char-displayable-p) ; Emacs 22+
5327
5328 (defun diredp-change-marks-recursive (old new &optional arg predicate) ; `M-+ * c'
5329 "Change all OLD marks to NEW marks, including those in marked subdirs.
5330The files included are those that are marked in the current Dired
5331buffer, or all files in the directory if none are marked. Marked
5332subdirectories are handled recursively in the same way.
5333
5334* A non-positive prefix arg means ignore subdir markings and act
5335 instead on ALL subdirs.
5336
5337* A non-negative prefix arg means do not change marks on subdirs
5338 themselves.
5339
5340Note: If there is more than one Dired buffer for a given subdirectory
5341then only the first such is used.
5342
5343Non-interactively, non-nil arg PREDICATE is a file-name predicate.
5344Act on only the files for which it returns non-nil."
5345 (interactive
5346 (progn (diredp-get-confirmation-recursive)
5347 (let* ((cursor-in-echo-area t)
5348 (old (progn (message "Change (old mark): ") (read-char)))
5349 (new (progn (message "Change `%c' marks to (new mark): " old) (read-char))))
5350 (list old new current-prefix-arg))))
5351 (let* ((numarg (and arg (prefix-numeric-value arg)))
5352 (nosubs (natnump numarg))
5353 (ignore-marks (and numarg (<= numarg 0)))
5354 (dired-marker-char new)
5355 (sdirs (diredp-get-subdirs ignore-marks))
5356 (old-strg (format "\n%c" old))
5357 (count 0)
5358 dbufs)
5359 (unless (char-displayable-p old) (error "Not a displayable character: `%c'" old))
5360 (unless (char-displayable-p new) (error "Not a displayable character: `%c'" new))
5361 (message "Changing mark `%c' to `%c'..." old new)
5362 (dolist (dir (cons default-directory sdirs))
5363 (when (setq dbufs (dired-buffers-for-dir (expand-file-name dir))) ; Dirs with Dired buffers only.
5364 (with-current-buffer (car dbufs)
5365 (let ((inhibit-read-only t)
5366 (file nil))
5367 (save-excursion
5368 (goto-char (point-min))
5369 (while (search-forward old-strg nil t)
5370 (save-match-data (setq file (dired-get-filename 'no-dir t)))
5371 ;; Do nothing if changing from UNmarked and not on a file or dir name.
5372 (unless (and (= old ? ) (not file))
5373 ;; Do nothing if marked subdir and not changing subdir marks.
5374 (unless (and nosubs file (file-directory-p file))
5375 (subst-char-in-region (match-beginning 0) (match-end 0) old new)
5376 (setq count (1+ count))))))))))
5377 (message "%d mark%s changed from `%c' to `%c'" count (dired-plural-s count) old new)))
5378
5379 (defun diredp-unmark-all-marks-recursive (&optional arg) ; `M-+ U'
5380 "Remove ALL marks everywhere, including in marked subdirs.
5381A prefix arg is as for `diredp-unmark-all-files-recursive'.
5382Note that a negative prefix arg (e.g. `C--') removes all marks from
5383this Dired buffer and then does the same recursively for each of its
5384subdirs."
5385 (interactive (progn (diredp-get-confirmation-recursive) (list current-prefix-arg)))
5386 (diredp-unmark-all-files-recursive ?\r arg))
5387
5388 (defun diredp-unmark-all-files-recursive (mark &optional arg predicate) ; `M-+ M-DEL'
5389 "Remove a given mark (or ALL) everywhere, including in marked subdirs.
5390You are prompted for the mark character to remove. If you hit `RET'
5391instead then ALL mark characters are removed.
5392
5393The files included are those that are marked in the current Dired
5394buffer, or all files in the directory if none are marked. Marked
5395subdirectories are handled recursively in the same way.
5396
5397* A non-positive prefix arg means ignore subdir markings and act
5398 instead on ALL subdirs.
5399
5400* A non-negative prefix arg means do not change marks on subdirs
5401 themselves.
5402
5403Note: If there is more than one Dired buffer for a given subdirectory
5404then only the first such is used.
5405
5406Non-interactively, non-nil arg PREDICATE is a file-name predicate.
5407Act on only the files for which it returns non-nil."
5408 (interactive
5409 (progn (diredp-get-confirmation-recursive)
5410 (let* ((cursor-in-echo-area t)
5411 (mrk (progn (message "Remove marks (RET means all): ") (read-char))))
5412 (list mrk current-prefix-arg))))
5413 (let* ((numarg (and arg (prefix-numeric-value arg)))
5414 (nosubs (natnump numarg))
5415 (ignore-marks (and numarg (<= numarg 0)))
5416 (dired-marker-char ?\ ) ; Unmark
5417 (sdirs (diredp-get-subdirs ignore-marks))
5418 (mrk-strg (format "\n%c" mark))
5419 (count 0)
5420 dbufs)
5421 (unless (char-displayable-p mark) (error "Not a displayable character: `%c'" mark))
5422 (if (eq mark ?\r)
5423 (message "Unmarking ALL marks here and below...")
5424 (message "Unmarking mark `%c' here and below..." mark))
5425 (dolist (dir (cons default-directory sdirs))
5426 (when (setq dbufs (dired-buffers-for-dir (expand-file-name dir))) ; Dirs with Dired buffers only.
5427 (with-current-buffer (car dbufs)
5428 (let ((inhibit-read-only t)
5429 (file nil))
5430 (save-excursion
5431 (goto-char (point-min))
5432 (while (if (eq mark ?\r)
5433 (re-search-forward dired-re-mark nil t)
5434 (search-forward mrk-strg nil t))
5435 (save-match-data (setq file (dired-get-filename 'no-dir t)))
5436 ;; Do nothing if marked subdir and not changing subdir marks.
5437 (unless (and nosubs file (file-directory-p file))
5438 (subst-char-in-region (match-beginning 0) (match-end 0) (preceding-char) ?\ ))
5439 (setq count (1+ count))))))))
5440 (message "%d mark%s UNmarked" count (dired-plural-s count))))
5441
5442 )
5443
5444(when (and (memq system-type '(windows-nt ms-dos)) (fboundp 'w32-browser))
5445 (defun diredp-multiple-w32-browser-recursive (&optional ignore-marks-p)
5446 "Run Windows apps for with marked files, including those in marked subdirs.
5447Like `dired-multiple-w32-browser', but act recursively on subdirs.
5448
5449See `diredp-do-find-marked-files-recursive' for a description of the
5450files included. In particular, if no files are marked here or in a
5451marked subdir, then all files in the directory are included."
5452 (interactive (progn (diredp-get-confirmation-recursive) (list current-prefix-arg)))
5453 (let ((files (diredp-get-files ignore-marks-p)))
5454 (while files
5455 (w32-browser (car files))
5456 (sleep-for w32-browser-wait-time)
5457 (setq files (cdr files))))))
5458
5459;;;###autoload
5460(defun diredp-copy-filename-as-kill-recursive (&optional arg) ; Bound to `M-+ M-w'
5461 "Copy names of marked files here and in marked subdirs, to `kill-ring'.
5462The names are separated by a space.
5463
5464Like `dired-copy-filename-as-kill', but act recursively on subdirs.
5465\(Do not copy subdir names themselves.)
5466
5467With no prefix arg, use relative file names.
5468With a zero prefix arg, use absolute file names.
5469With a plain prefix arg (`C-u'), use names relative to the current
5470Dired directory. (This might contain slashes if in a subdirectory.)
5471
5472If on a subdir headerline, use absolute subdir name instead - prefix
5473arg and marked files are ignored in this case.
5474
5475The files included are those that are marked in the current Dired
5476buffer, or all files in the directory if none are marked. Marked
5477subdirectories are handled recursively in the same way.
5478
5479The names are copied to the kill ring and to variable
5480`diredp-last-copied-filenames'."
5481 (interactive ; No need for `diredp-get-confirmation-recursive' here.
5482 (progn (diredp-ensure-mode) (list current-prefix-arg)))
5483 (let* ((files (mapcar (cond ((zerop (prefix-numeric-value arg)) #'identity)
5484 ((consp arg) (lambda (fn) (concat (dired-current-directory t)
5485 (file-name-nondirectory fn))))
5486 (t (lambda (fn) (file-name-nondirectory fn))))
5487 (diredp-get-files)))
5488 (string (mapconcat #'identity files " ")))
5489 (unless (string= "" string)
5490 (if (eq last-command 'kill-region) (kill-append string nil) (kill-new string))
5491 (setq diredp-last-copied-filenames (car kill-ring-yank-pointer)))
5492 (message "%s" string)))
5493
5494;;;###autoload
5495(defun diredp-copy-abs-filenames-as-kill-recursive (&optional ignore-marks-p) ; Not bound.
5496 "Copy absolute names of files marked here and in marked subdirs, recursively.
5497The names are copied to the kill ring and to variable
5498`dired-copy-filename-as-kill'.
5499
5500The files whose names are copied are those that are marked in the
5501current Dired buffer, or all files in the directory if none are
5502marked. Marked subdirectories are handled recursively in the same
5503way."
5504 (interactive ; No need for `diredp-get-confirmation-recursive' here.
5505 (progn (diredp-ensure-mode) (list current-prefix-arg)))
5506 (diredp-copy-filename-as-kill-recursive 0)
5507 (setq diredp-last-copied-filenames (car kill-ring-yank-pointer)))
5508
5509;;;###autoload
5510(defun diredp-mark-files-regexp-recursive (regexp &optional marker-char ignore-marks-p) ; Bound to `M-+ % m'
5511 "Mark all files matching REGEXP, including those in marked subdirs.
5512Like `dired-mark-files-regexp' but act recursively on marked subdirs.
5513
5514The file names to be matched by this command are always absolute -
5515they include the full directory. Note that this does NOT correspond
5516to the default behavior for `dired-mark-files-regexp'. The other
5517matching possibilities offered by `dired-mark-files-regexp' are not
5518available for this command.
5519
5520Directories `.' and `..' are never marked.
5521
5522A non-negative prefix arg means to UNmark the files instead.
5523
5524A non-positive prefix arg means to ignore subdir markings and act
5525instead on ALL subdirs. That is, mark all matching files in this
5526directory and all descendant directories.
5527
5528REGEXP is an Emacs regexp, not a shell wildcard. Thus, use `\\.o$' for
5529object files--just `.o' will mark more than you might think.
5530
5531REGEXP is added to `regexp-search-ring', for regexp search.
5532
5533Note: If there is more than one Dired buffer for a given subdirectory
5534then only the first such is used."
5535 (interactive (let* ((numarg (and current-prefix-arg (prefix-numeric-value current-prefix-arg)))
5536 (unmark (and numarg (>= numarg 0)))
5537 (ignorep (and numarg (<= numarg 0))))
5538 (list (diredp-read-regexp (concat (if unmark "UNmark" "Mark") " files (regexp): "))
5539 (and unmark ?\040)
5540 ignorep)))
5541 (add-to-list 'regexp-search-ring regexp) ; Add REGEXP to `regexp-search-ring'.
5542 (let ((dired-marker-char (or marker-char dired-marker-char))
5543 (sdirs (diredp-get-subdirs ignore-marks-p))
5544 (matched 0)
5545 (changed 0)
5546 dbufs chg.mtch)
5547 (message "%s files..." (if (eq ?\040 dired-marker-char) "UNmarking" "Marking"))
5548 (dolist (dir (cons default-directory sdirs))
5549 (when (setq dbufs (dired-buffers-for-dir (expand-file-name dir))) ; Dirs with Dired buffers only.
5550 (with-current-buffer (car dbufs)
5551 (setq chg.mtch (diredp-mark-if (and (not (diredp-looking-at-p dired-re-dot))
5552 (not (eolp)) ; Empty line
5553 (let ((fn (dired-get-filename nil 'NO-ERROR)))
5554 (and fn (diredp-string-match-p regexp fn))))
5555 "file")
5556 changed (+ changed (or (car chg.mtch) 0))
5557 matched (+ matched (or (cdr chg.mtch) 0))))))
5558 (message "%s file%s%s%s newly %s"
5559 matched
5560 (dired-plural-s matched)
5561 (if (not (= matched changed)) " matched, " "")
5562 (if (not (= matched changed)) changed "")
5563 (if (eq ?\040 dired-marker-char) "unmarked" "marked"))))
5564
5565(defun diredp-mark-extension-recursive (extension &optional arg) ; Bound to `M-+ * .'
5566 "Mark all files with a certain EXTENSION, including in marked subdirs.
5567A `.' is not automatically prepended to the string entered.
5568
5569This is like `diredp-mark/unmark-extension', but this acts recursively
5570on marked subdirs, and a non-positive prefix arg acts differently.
5571
5572A non-negative prefix arg means to unmark them instead.
5573
5574A non-positive prefix arg means to ignore subdir markings and act
5575instead on ALL subdirs. That is, mark all in this directory and all
5576descendant directories.
5577
5578Non-interactively, EXTENSION is the extension (a string). It can also
5579be a list of extension strings.
5580Optional argument ARG is the prefix arg."
5581 (interactive (let* ((numarg (and current-prefix-arg (prefix-numeric-value current-prefix-arg)))
5582 (unmark (and numarg (>= numarg 0))))
5583 (list (diredp-read-regexp (concat (if unmark "UNmark" "Mark") " extension: "))
5584 current-prefix-arg)))
5585 (let* ((numarg (and arg (prefix-numeric-value arg)))
5586 (unmark (and numarg (>= numarg 0)))
5587 (ignorep (and numarg (<= numarg 0))))
5588 (or (listp extension) (setq extension (list extension)))
5589 (diredp-mark-files-regexp-recursive (concat ".+[.]\\("
5590 (mapconcat #'regexp-quote extension "\\|")
5591 "\\)$")
5592 (if unmark ?\040 dired-marker-char)
5593 ignorep)))
5594
5595;;;###autoload
5596(defun diredp-mark-autofiles-recursive (&optional arg) ; Bound to `M-+ * B'
5597 "Mark all autofiles, including in marked subdirs.
5598Autofiles are files that have an autofile bookmark.
5599A non-negative prefix arg means to unmark them instead.
5600
5601A non-positive prefix arg means to ignore subdir markings and act
5602instead on ALL subdirs. That is, mark all in this directory and all
5603descendant directories."
5604 (interactive "P")
5605 (diredp-ensure-bookmark+)
5606 (diredp-ensure-mode)
5607 (diredp-mark-recursive-1 arg "autofiles" "autofile"
5608 '(and (not (diredp-looking-at-p dired-re-dot)) (not (eolp))
5609 (let ((fname (dired-get-filename nil t)))
5610 (and fname (bmkp-get-autofile-bookmark fname))))))
5611
5612;;;###autoload
5613(defun diredp-mark-executables-recursive (&optional arg) ; Bound to `M-+ * *'
5614 "Mark all executable files, including in marked subdirs.
5615The files included are those that are marked in the current Dired
5616buffer, or all files in the directory if none are marked. Marked
5617subdirectories are handled recursively in the same way.
5618
5619A non-negative prefix arg means to unmark them instead.
5620
5621A non-positive prefix arg means to ignore subdir markings and act
5622instead on ALL subdirs. That is, mark all in this directory and all
5623descendant directories."
5624 (interactive "P")
5625 (diredp-mark-recursive-1 arg "executable files" "executable file" '(diredp-looking-at-p dired-re-exe)))
5626
5627;;;###autoload
5628(defun diredp-mark-directories-recursive (&optional arg) ; Bound to `M-+ * /'
5629 "Mark all directories except `.' and `..', including in marked subdirs.
5630The directories included are those that are marked in the current
5631Dired buffer, or all subdirs in the directory if none are marked.
5632Marked subdirectories are handled recursively in the same way.
5633
5634A non-negative prefix arg means to unmark them instead.
5635
5636A non-positive prefix arg means to ignore subdir markings and act
5637instead on ALL subdirs. That is, mark all in this directory and all
5638descendant directories."
5639 (interactive "P")
5640 (diredp-mark-recursive-1 arg "directories" "directory" '(and (diredp-looking-at-p dired-re-dir)
5641 (not (diredp-looking-at-p dired-re-dot)))))
5642;;;###autoload
5643(defun diredp-mark-symlinks-recursive (&optional arg) ; Bound to `M-+ * @'
5644 "Mark all symbolic links, including in marked subdirs.
5645The symlinks included are those that are marked in the current Dired
5646buffer, or all symlinks in the directory if none are marked. Marked
5647subdirectories are handled recursively in the same way.
5648
5649A non-negative prefix arg means to unmark them instead.
5650
5651A non-positive prefix arg means to ignore subdir markings and act
5652instead on ALL subdirs. That is, mark all in this directory and all
5653descendant directories."
5654 (interactive "P")
5655 (diredp-mark-recursive-1 arg "symlinks" "symbolic link" '(diredp-looking-at-p dired-re-sym)))
5656
5657(defun diredp-mark-recursive-1 (arg plural singular predicate-sexp)
5658 "Helper for `diredp-mark-*-recursive' commands."
5659 (let* ((numarg (and arg (prefix-numeric-value arg)))
5660 (unmark (and numarg (>= numarg 0)))
5661 (ignorep (and numarg (<= numarg 0)))
5662 (dired-marker-char (if unmark ?\040 dired-marker-char))
5663 (sdirs (diredp-get-subdirs ignorep))
5664 (changed 0)
5665 (matched 0)
5666 dbufs chg.mtch)
5667 (message "%s %s..." (if (eq ?\040 dired-marker-char) "UNmarking" "Marking") plural)
5668 (dolist (dir (cons default-directory sdirs))
5669 (when (setq dbufs (dired-buffers-for-dir (expand-file-name dir))) ; Dirs with Dired buffers only.
5670 (with-current-buffer (car dbufs)
5671 (setq chg.mtch (diredp-mark-if (eval predicate-sexp) singular)
5672 changed (+ changed (or (car chg.mtch) 0))
5673 matched (+ matched (or (cdr chg.mtch) 0))))))
5674 (message "%s %s%s%s newly %s"
5675 matched
5676 (if (= 1 matched) singular plural)
5677 (if (not (= matched changed)) " matched, " "")
5678 (if (not (= matched changed)) changed "")
5679 (if (eq ?\040 dired-marker-char) "unmarked" "marked"))))
5680
5681;;;###autoload
5682(defun diredp-capitalize-recursive (&optional ignore-marks-p) ; Bound to `M-+ % c'
5683 "Rename marked files, including in marked subdirs, by capitalizing them.
5684Like `diredp-capitalize', but act recursively on subdirs.
5685
5686The files included are those that are marked in the current Dired
5687buffer, or all files in the directory if none are marked. Marked
5688subdirectories are handled recursively in the same way.
5689
5690With a prefix argument, ignore all marks - include all files in this
5691Dired buffer and all subdirs, recursively."
5692 (interactive (progn (diredp-get-confirmation-recursive) (list current-prefix-arg)))
5693 (diredp-create-files-non-directory-recursive
5694 #'dired-rename-file #'capitalize "Rename by capitalizing:" ignore-marks-p))
5695
5696;;;###autoload
5697(defun diredp-upcase-recursive (&optional ignore-marks-p) ; Bound to `M-+ % u'
5698 "Rename marked files, including in marked subdirs, making them uppercase.
5699Like `dired-upcase', but act recursively on subdirs.
5700
5701The files included are those that are marked in the current Dired
5702buffer, or all files in the directory if none are marked. Marked
5703subdirectories are handled recursively in the same way.
5704
5705With a prefix argument, ignore all marks - include all files in this
5706Dired buffer and all subdirs, recursively."
5707 (interactive (progn (diredp-get-confirmation-recursive) (list current-prefix-arg)))
5708 (diredp-create-files-non-directory-recursive
5709 #'dired-rename-file #'upcase "Rename to uppercase:" ignore-marks-p))
5710
5711;;;###autoload
5712(defun diredp-downcase-recursive (&optional ignore-marks-p) ; Bound to `M-+ % l'
5713 "Rename marked files, including in marked subdirs, making them lowercase.
5714Like `dired-downcase', but act recursively on subdirs.
5715
5716The files included are those that are marked in the current Dired
5717buffer, or all files in the directory if none are marked. Marked
5718subdirectories are handled recursively in the same way.
5719
5720With a prefix argument, ignore all marks - include all files in this
5721Dired buffer and all subdirs, recursively."
5722 (interactive (progn (diredp-get-confirmation-recursive) (list current-prefix-arg)))
5723 (diredp-create-files-non-directory-recursive
5724 #'dired-rename-file #'downcase "Rename to lowercase:" ignore-marks-p))
5725
5726;;;###autoload
5727(defun diredp-do-apply-function-recursive (function &optional arg) ; Bound to `M-+ @'
5728 "Apply FUNCTION to the marked files.
5729Like `diredp-do-apply-function' but act recursively on subdirs.
5730
5731The files acted on are those that are marked in the current Dired
5732buffer, or all files in the directory if none are marked. Marked
5733subdirectories are handled recursively in the same way.
5734
5735With a plain prefix ARG (`C-u'), visit each file and invoke FUNCTION
5736 with no arguments.
5737Otherwise, apply FUNCTION to each file name.
5738
5739Any other prefix arg behaves according to the ARG argument of
5740`dired-get-marked-files'. In particular, `C-u C-u' operates on all
5741files in the Dired buffer."
5742 (interactive (progn (diredp-get-confirmation-recursive)
5743 (list (read (completing-read "Function: " obarray 'functionp nil nil
5744 (and (boundp 'function-name-history) 'function-name-history)))
5745 current-prefix-arg)))
5746 (if (and (consp arg) (< (car arg) 16))
5747 (dolist (file (diredp-get-files)) (with-current-buffer (find-file-noselect file) (funcall function)))
5748 (dolist (file (diredp-get-files arg)) (funcall function file))))
5749
5750;;;###autoload
5751(defun diredp-do-delete-recursive (arg) ; Bound to `M-+ D'
5752 "Delete marked (not flagged) files, including in marked subdirs.
5753Like `dired-do-delete' but act recursively on subdirs.
5754
5755The files to be deleted are those that are marked in the current Dired
5756buffer, or all files in the directory if none are marked. Marked
5757subdirectories are handled recursively in the same way."
5758 (interactive (progn (diredp-get-confirmation-recursive) (list current-prefix-arg)))
5759 (unless arg
5760 (ding)
5761 (message "NOTE: Deletion of files marked `%c' (not those flagged `%c')."
5762 dired-marker-char dired-del-marker))
5763 (let* ((files (diredp-get-files nil nil nil nil 'ONLY-MARKED-P))
5764 (count (length files))
5765 (trashing (and (boundp 'delete-by-moving-to-trash) delete-by-moving-to-trash))
5766 (succ 0))
5767 (if (dired-mark-pop-up
5768 " *Deletions*" 'delete files dired-deletion-confirmer
5769 (format "%s %s " (if trashing "Trash" "Delete") (dired-mark-prompt arg files)))
5770 (let ((progress-reporter (and (fboundp 'make-progress-reporter)
5771 (make-progress-reporter (if trashing "Trashing..." "Deleting...")
5772 succ
5773 count)))
5774 (failures ()))
5775 (unless progress-reporter (message "Deleting..."))
5776 (dolist (file files)
5777 (condition-case err
5778 (progn (if (fboundp 'dired-delete-file) ; Emacs 22+
5779 (dired-delete-file file dired-recursive-deletes trashing)
5780 ;; This test is equivalent to (and (file-directory-p file) (not (file-symlink-p file)))
5781 ;; but more efficient.
5782 (if (eq t (car (file-attributes file))) (delete-directory file) (delete-file file)))
5783 (setq succ (1+ succ))
5784 (when (fboundp 'progress-reporter-update)
5785 (progress-reporter-update progress-reporter succ)))
5786 (error (dired-log "%s\n" err) ; Catch errors from failed deletions.
5787 (setq failures (cons file failures))))
5788 (dired-clean-up-after-deletion file))
5789 (if failures
5790 (dired-log-summary (format "%d of %d deletion%s failed"
5791 (length failures) count (dired-plural-s count))
5792 failures)
5793 (if (fboundp 'progress-reporter-done)
5794 (progress-reporter-done progress-reporter)
5795 (message "Deleting...done")))
5796 (let ((sdirs (diredp-get-subdirs))
5797 dbufs)
5798 (dolist (dir (cons default-directory sdirs))
5799 (when (setq dbufs (dired-buffers-for-dir (expand-file-name dir))) ; Dirs with Dired buffers only.
5800 (with-current-buffer (car dbufs) (dired-revert))))))
5801 (message "OK. NO deletions performed"))))
5802
5803;;;###autoload
5804(defun diredp-do-move-recursive (&optional ignore-marks-p) ; Bound to `M-+ R'
5805 "Move marked files, including in marked subdirs, to a given directory.
5806Like `dired-do-rename', but act recursively on subdirs to pick up the
5807files to move.
5808
5809The files included are those that are marked in the current Dired
5810buffer, or all files in the directory if none are marked. Marked
5811subdirectories are handled recursively in the same way.
5812
5813This means move the marked files of marked subdirs and their marked
5814subdirs, etc. It does not mean move or rename the subdirs themselves
5815recursively.
5816
5817With a prefix argument, ignore all marks - include all files in this
5818Dired buffer and all subdirs, recursively.
5819
5820Renames any buffers that are visiting the files.
5821
5822The default suggested for the target directory depends on the value of
5823`dired-dwim-target', which see."
5824 (interactive (progn (diredp-get-confirmation-recursive) (list current-prefix-arg)))
5825 (diredp-do-create-files-recursive #'dired-rename-file "Move" ignore-marks-p))
5826
5827;;;###autoload
5828(defun diredp-do-copy-recursive (&optional ignore-marks-p) ; Bound to `M-+ C'
5829 "Copy marked files, including in marked subdirs, to a given directory.
5830Like `dired-do-copy', but act recursively on subdirs to pick up the
5831files to copy.
5832
5833The files included are those that are marked in the current Dired
5834buffer, or all files in the directory if none are marked. Marked
5835subdirectories are handled recursively in the same way.
5836
5837This means copy the marked files of marked subdirs and their marked
5838subdirs, etc. It does not mean copy the subdirs themselves
5839recursively.
5840
5841With a prefix argument, ignore all marks - include all files in this
5842Dired buffer and all subdirs, recursively.
5843
5844Preserves the last-modified date when copying, unless
5845`dired-copy-preserve-time' is nil.
5846
5847The default suggested for the target directory depends on the value of
5848`dired-dwim-target', which see.
5849
5850This command copies symbolic links by creating new ones, like UNIX
5851command `cp -d'."
5852 (interactive (progn (diredp-get-confirmation-recursive) (list current-prefix-arg)))
5853 (let ((dired-recursive-copies nil)) ; Doesn't have to be nil, but let's not go overboard now.
5854 (diredp-do-create-files-recursive #'dired-copy-file "Copy" ignore-marks-p)))
5855
5856(defun diredp-do-create-files-recursive (file-creator operation ignore-marks-p)
5857 "Create a new file for each marked file, including those in marked subdirs.
5858Like `dired-do-create-files', but act recursively on subdirs, and
5859always keep markings.
5860Prompts for the target directory, in which to create the files.
5861FILE-CREATOR OPERATION is as in `dired-create-files'.
5862Non-nil IGNORE-MARKS-P means ignore all marks - include all files in this
5863Dired buffer and all subdirs, recursively."
5864 (lexical-let* ((fn-list (diredp-get-files ignore-marks-p))
5865 (target-dir (dired-dwim-target-directory))
5866 (defaults (and (fboundp 'dired-dwim-target-defaults) ; Emacs 23+
5867 (dired-dwim-target-defaults fn-list target-dir)))
5868 (target (expand-file-name
5869 (if (fboundp 'minibuffer-with-setup-hook) ; Emacs 22+
5870 (minibuffer-with-setup-hook
5871 (lambda ()
5872 (set (make-local-variable 'minibuffer-default-add-function)
5873 nil)
5874 (setq minibuffer-default defaults))
5875 (funcall (if (fboundp 'read-directory-name)
5876 #'read-directory-name
5877 #'read-file-name)
5878 (concat operation " files to: ")
5879 default-directory default-directory))
5880 (funcall (if (fboundp 'read-directory-name)
5881 #'read-directory-name
5882 #'read-file-name)
5883 (concat operation "files to: ")
5884 default-directory default-directory)))))
5885 (unless (file-directory-p target) (error "Target is not a directory: `%s'" target))
5886 (dired-create-files
5887 file-creator operation fn-list
5888 #'(lambda (from) (expand-file-name (file-name-nondirectory from) target))
5889 ;; Hard-code `*' marker, or else it will be removed in lower dirs because the code uses
5890 ;; `dired-file-marker', which only works in the current Dired directory.
5891 ?*)))
5892
5893(defun diredp-create-files-non-directory-recursive (file-creator basename-constructor operation
5894 &optional ignore-marks-p)
5895 "Apply FILE-CREATOR + BASENAME-CONSTRUCTOR to non-dir part of marked names.
5896Like `dired-create-files-non-directory', but act recursively on subdirs.
5897
5898The files acted on are those marked in the current Dired buffer, or
5899all files in the directory if none are marked. Marked subdirectories
5900are handled recursively in the same way.
5901
5902With non-nil IGNORE-MARKS-P, ignore all marks - include all files in
5903this Dired buffer and all subdirs, recursively."
5904 (let (rename-non-directory-query)
5905 (dired-create-files
5906 file-creator
5907 operation
5908 (diredp-get-files ignore-marks-p)
5909 #'(lambda (from)
5910 (let ((to (concat (file-name-directory from)
5911 (funcall basename-constructor (file-name-nondirectory from)))))
5912 (and (let ((help-form (format "\
5913Type SPC or `y' to %s one file, DEL or `n' to skip to next,
5914`!' to %s all remaining matches with no more questions."
5915 (downcase operation)
5916 (downcase operation))))
5917 (dired-query 'rename-non-directory-query (concat operation " `%s' to `%s'")
5918 (dired-make-relative from) (dired-make-relative to)))
5919 to)))
5920 ;; Hard-code `*' marker, or else it will be removed in lower dirs because the code uses
5921 ;; `dired-file-marker', which only works in the current Dired directory.
5922 ?*)))
5923
5924(defun diredp-do-chxxx-recursive (attribute-name program op-symbol &optional ignore-marks-p default)
5925 "Change attributes of the marked files, including those in marked subdirs.
5926Refresh their file lines.
5927
5928Like `dired-do-chxxx', but act recursively on subdirs. The subdirs
5929acted on are those that are marked in the current Dired buffer, or all
5930subdirs in the directory if none are marked. Marked subdirectories
5931are handled recursively in the same way.
5932
5933ATTRIBUTE-NAME is a string describing the attribute to the user.
5934PROGRAM is the program used to change the attribute.
5935OP-SYMBOL is the type of operation (for use in `dired-mark-pop-up').
5936Non-nil IGNORE-MARKS-P means ignore all marks - include all files in this
5937Dired buffer and all subdirs, recursively."
5938 (let* ((this-buff (current-buffer))
5939 (files (diredp-get-files ignore-marks-p))
5940 (prompt (concat "Change " attribute-name " of %s to: "))
5941 (new-attribute (if (> emacs-major-version 22)
5942 (dired-mark-read-string prompt nil op-symbol
5943 ignore-marks-p files default)
5944 (dired-mark-read-string prompt nil op-symbol ignore-marks-p files)))
5945 (operation (concat program " " new-attribute))
5946 failures)
5947 (setq failures (dired-bunch-files 10000 (function dired-check-process)
5948 (append (list operation program)
5949 (unless (string-equal new-attribute "")
5950 (if (equal attribute-name "Timestamp")
5951 (list "-t" new-attribute)
5952 (list new-attribute)))
5953 (and (diredp-string-match-p "gnu" system-configuration)
5954 '("--"))) ; --------------------------------
5955 files))
5956 (with-current-buffer this-buff (diredp-do-redisplay-recursive 'MSGP))
5957 (when failures (dired-log-summary (format "%s: error" operation) nil))))
5958
5959;;;###autoload
5960(defun diredp-do-chmod-recursive (&optional ignore-marks-p) ; Bound to `M-+ M'
5961 "Change the mode of the marked files, including those in marked subdirs.
5962Symbolic modes like `g+w' are allowed.
5963
5964Note that marked subdirs are not changed. Their markings are used only
5965to indicate that some of their files are to be changed.
5966
5967With a prefix argument, ignore all marks - include all files in this
5968Dired buffer and all subdirs, recursively."
5969 (interactive (progn (diredp-get-confirmation-recursive) (list current-prefix-arg)))
5970 (let* ((files (diredp-get-files ignore-marks-p))
5971 (modestr (and (stringp (car files)) (nth 8 (file-attributes (car files)))))
5972 (default (and (stringp modestr)
5973 (string-match "^.\\(...\\)\\(...\\)\\(...\\)$" modestr)
5974 (replace-regexp-in-string "-" "" (format "u=%s,g=%s,o=%s"
5975 (match-string 1 modestr)
5976 (match-string 2 modestr)
5977 (match-string 3 modestr)))))
5978 (modes (if (> emacs-major-version 22)
5979 (dired-mark-read-string
5980 "Change mode of marked files here and below to: " nil 'chmod
5981 nil files default)
5982 (dired-mark-read-string
5983 "Change mode of marked files here and below to: " nil 'chmod
5984 nil files))))
5985 (when (equal modes "") (error "No file mode specified"))
5986 (dolist (file files)
5987 (set-file-modes file (or (and (diredp-string-match-p "^[0-7]+" modes) (string-to-number modes 8))
5988 (file-modes-symbolic-to-number modes (file-modes file)))))
5989 (diredp-do-redisplay-recursive 'MSGP)))
5990
5991(unless (memq system-type '(windows-nt ms-dos))
5992 (defun diredp-do-chgrp-recursive (&optional ignore-marks-p)
5993 "Change the group of the marked (or next ARG) files.
5994With a prefix argument, ignore all marks - include all files in this
5995Dired buffer and all subdirs, recursively."
5996 (interactive "P")
5997 (diredp-do-chxxx-recursive "Group" "chgrp" 'chgrp ignore-marks-p)))
5998
5999(unless (memq system-type '(windows-nt ms-dos))
6000 (defun diredp-do-chown-recursive (&optional ignore-marks-p)
6001 "Change the owner of the marked (or next ARG) files.
6002With a prefix argument, ignore all marks - include all files in this
6003Dired buffer and all subdirs, recursively."
6004 (interactive "P")
6005 (diredp-do-chxxx-recursive "Owner" dired-chown-program 'chown ignore-marks-p)))
6006
6007;;;###autoload
6008(defun diredp-do-touch-recursive (&optional ignore-marks-p)
6009 "Change the timestamp of marked files, including those in marked subdirs.
6010This calls `touch'. Like `dired-do-touch', but act recursively on
6011subdirs. The subdirs inserted are those that are marked in the
6012current Dired buffer, or all subdirs in the directory if none are
6013marked. Marked subdirectories are handled recursively in the same
6014way.
6015
6016With a prefix argument, ignore all marks - include all files in this
6017Dired buffer and all subdirs, recursively."
6018 (interactive (progn (diredp-get-confirmation-recursive) (list current-prefix-arg)))
6019 (diredp-do-chxxx-recursive "Timestamp" (if (boundp 'dired-touch-program)
6020 dired-touch-program ; Emacs 22+
6021 "touch")
6022 'touch
6023 ignore-marks-p
6024 (format-time-string "%Y%m%d%H%M.%S" (current-time))))
6025
6026;;;###autoload
6027(defun diredp-do-redisplay-recursive (&optional msgp)
6028 "Redisplay marked file lines, including those in marked subdirs.
6029Non-nil MSGP means show status messages.
6030Like `dired-do-redisplay' with no args, but act recursively on
6031subdirs."
6032 (interactive (progn (diredp-ensure-mode)
6033 (unless (y-or-n-p "Act on all marked file lines in and UNDER this dir? ")
6034 (error "OK, canceled"))
6035 (list t)))
6036 (when msgp (message "Redisplaying..."))
6037 (dolist (dir (cons default-directory
6038 (diredp-get-files nil #'file-directory-p 'INCLUDE-SUBDIRS 'DONT-ASK)))
6039 (with-current-buffer (dired-noselect dir)
6040 ;; `message' is much faster than making `dired-map-over-marks' show progress
6041 (dired-uncache (if (consp dired-directory) (car dired-directory) dired-directory))
6042 (dired-map-over-marks
6043 (let ((fname (dired-get-filename))
6044 ;; Postpone readin hook till we map over all marked files (Bug#6810).
6045 (dired-after-readin-hook nil))
6046 (message "Redisplaying... %s" fname)
6047 (dired-update-file-line fname))
6048 nil)
6049 (run-hooks 'dired-after-readin-hook)
6050 (dired-move-to-filename)))
6051 (when msgp (message "Redisplaying...done")))
6052
6053
6054;;; `diredp-marked(-other-window)' tries to treat SWITCHES, but SWITCHES seems to be ignored
6055;;; by `dired' when the DIRNAME arg is a cons, at least on MS Windows. I filed Emacs bug #952
6056;;; on 2008-09-10, but this doesn't work in Emacs 20, 21, 22, or 23, so I don't know if it will
6057;;; ever be fixed. If it is declared a non-bug and it doesn't work on any platforms, then I'll
6058;;; remove SWITCHES here, alas.
6059
6060;;;###autoload
6061(defun diredp-marked (dirname &optional n switches) ; Not bound
6062 "Open Dired on only the marked files or the next N files.
6063With a non-zero numeric prefix arg N, use the next abs(N) files.
6064A plain (`C-u'), zero, or negative prefix arg prompts for listing
6065switches as in command `dired'.
6066
6067Note that the marked files can include files in inserted
6068subdirectories, so the Dired buffer that is opened can contain files
6069from multiple directories in the same tree."
6070 (interactive (progn (diredp-ensure-mode)
6071 (let ((num (and current-prefix-arg
6072 (atom current-prefix-arg)
6073 (not (zerop (prefix-numeric-value current-prefix-arg)))
6074 (abs (prefix-numeric-value current-prefix-arg)))))
6075 (list (cons (generate-new-buffer-name (buffer-name)) (dired-get-marked-files t num))
6076 num
6077 (and current-prefix-arg ; Switches
6078 (or (consp current-prefix-arg)
6079 (< (prefix-numeric-value current-prefix-arg) 0))
6080 (read-string "Dired listing switches: " dired-listing-switches))))))
6081 (unless (or n (save-excursion (goto-char (point-min))
6082 (and (re-search-forward (dired-marker-regexp) nil t)
6083 (re-search-forward (dired-marker-regexp) nil t))))
6084 (error "No marked files"))
6085 (dired dirname switches))
6086
6087;;;###autoload
6088(defun diredp-marked-other-window (dirname &optional n switches) ; Bound to `C-M-*'
6089 "Same as `diredp-marked', but uses a different window."
6090 (interactive (progn (diredp-ensure-mode)
6091 (let ((num (and current-prefix-arg
6092 (atom current-prefix-arg)
6093 (not (zerop (prefix-numeric-value current-prefix-arg)))
6094 (abs (prefix-numeric-value current-prefix-arg)))))
6095 (list (cons (generate-new-buffer-name (buffer-name)) (dired-get-marked-files t num))
6096 num
6097 (and current-prefix-arg ; Switches
6098 (or (consp current-prefix-arg)
6099 (< (prefix-numeric-value current-prefix-arg) 0))
6100 (read-string "Dired listing switches: " dired-listing-switches))))))
6101 (unless (or n (save-excursion (goto-char (point-min))
6102 (and (re-search-forward (dired-marker-regexp) nil t)
6103 (re-search-forward (dired-marker-regexp) nil t))))
6104 (error "No marked files"))
6105 (dired-other-window dirname switches))
6106
6107
6108;; Similar to `dired-mark-extension' in `dired-x.el'.
6109;; The difference is that this uses prefix arg to unmark, not to determine the mark character.
6110;;;###autoload
6111(defun diredp-mark/unmark-extension (extension &optional unmark-p) ; Bound to `* .'
6112 "Mark all files with a certain EXTENSION for use in later commands.
6113A `.' is not automatically prepended to the string entered.
6114Non-nil prefix argument UNMARK-P means unmark instead of mark.
6115
6116Non-interactively, EXTENSION is the extension (a string). It can also
6117 be a list of extension strings.
6118Optional argument UNMARK-P is the prefix arg."
6119 (interactive (list (diredp-read-regexp (concat (if current-prefix-arg "UNmark" "Mark") "ing extension: "))
6120 current-prefix-arg))
6121 (or (listp extension) (setq extension (list extension)))
6122 (dired-mark-files-regexp (concat ".";; Do not match names with nothing but an extension
6123 "\\("
6124 (mapconcat #'regexp-quote extension "\\|")
6125 "\\)$")
6126 (and current-prefix-arg ?\040)))
6127
6128(defun diredp-mark-files-tagged-all/none (tags &optional none-p unmarkp prefix)
6129 "Mark or unmark files tagged with all or none of TAGS.
6130TAGS is a list of strings, the tag names.
6131NONEP non-nil means mark/unmark files that have none of the TAGS.
6132UNMARKP non-nil means unmark; nil means mark.
6133PREFIX non-nil is the prefix of the autofile bookmarks to check.
6134
6135As a special case, if TAGS is empty, then mark or unmark the files
6136that have any tags at all, or if NONEP is non-nil then mark or unmark
6137those that have no tags at all."
6138 (let ((dired-marker-char (if unmarkp ?\040 dired-marker-char)))
6139 (diredp-mark-if (and (not (diredp-looking-at-p dired-re-dot)) (not (eolp))
6140 (let* ((fname (dired-get-filename nil t))
6141 (bmk (and fname (bmkp-get-autofile-bookmark fname nil prefix)))
6142 (btgs (and bmk (bmkp-get-tags bmk)))
6143 (presentp nil)
6144 (allp (and btgs (catch 'diredp-m-f-t-an
6145 (dolist (tag tags)
6146 (setq presentp (assoc-default tag btgs nil t))
6147 (unless (if none-p (not presentp) presentp)
6148 (throw 'diredp-m-f-t-an nil)))
6149 t))))
6150 (if (null tags)
6151 (if none-p (not btgs) btgs)
6152 allp)))
6153 (if none-p "no-tags-matching file" "all-tags-matching file"))))
6154
6155(defun diredp-mark-files-tagged-some/not-all (tags &optional notallp unmarkp prefix)
6156 "Mark or unmark files tagged with any or not all of TAGS.
6157TAGS is a list of strings, the tag names.
6158NOTALLP non-nil means mark/unmark files that do not have all TAGS.
6159UNMARKP non-nil means unmark; nil means mark.
6160PREFIX non-nil is the prefix of the autofile bookmarks to check.
6161
6162As a special case, if TAGS is empty, then mark or unmark the files
6163that have any tags at all, or if NOTALLP is non-nil then mark or
6164unmark those that have no tags at all."
6165 (let ((dired-marker-char (if unmarkp ?\040 dired-marker-char)))
6166 (diredp-mark-if (and (not (diredp-looking-at-p dired-re-dot)) (not (eolp))
6167 (let* ((fname (dired-get-filename nil t))
6168 (bmk (and fname
6169 (bmkp-get-autofile-bookmark fname nil prefix)))
6170 (btgs (and bmk (bmkp-get-tags bmk)))
6171 (presentp nil)
6172 (allp (and btgs (catch 'diredp-m-f-t-sna
6173 (dolist (tag tags)
6174 (setq presentp (assoc-default tag btgs nil t))
6175 (when (if notallp (not presentp) presentp)
6176 (throw 'diredp-m-f-t-sna t)))
6177 nil))))
6178 (if (null tags) (if notallp (not btgs) btgs) allp)))
6179 (if notallp "some-tags-not-matching file" "some-tags-matching file"))))
6180
6181;;;###autoload
6182(defun diredp-mark-files-tagged-all (tags &optional none-p prefix) ; `T m *'
6183 "Mark all files that are tagged with *each* tag in TAGS.
6184As a special case, if TAGS is empty, then mark the files that have
6185 any tags at all (i.e., at least one tag).
6186With a prefix arg, mark all that are *not* tagged with *any* TAGS.
6187You need library `bookmark+.el' to use this command."
6188 (interactive (list (and (fboundp 'bmkp-read-tags-completing) (bmkp-read-tags-completing))
6189 current-prefix-arg
6190 (and diredp-prompt-for-bookmark-prefix-flag
6191 (read-string "Prefix for autofile bookmark names: "))))
6192 (diredp-ensure-bookmark+)
6193 (diredp-ensure-mode)
6194 (diredp-mark-files-tagged-all/none tags none-p nil prefix))
6195
6196;;;###autoload
6197(defun diredp-mark-files-tagged-none (tags &optional allp prefix) ; `T m ~ +'
6198 "Mark all files that are not tagged with *any* tag in TAGS.
6199As a special case, if TAGS is empty, then mark the files that have
6200 no tags at all.
6201With a prefix arg, mark all that are tagged with *each* tag in TAGS.
6202You need library `bookmark+.el' to use this command."
6203 (interactive (list (and (fboundp 'bmkp-read-tags-completing) (bmkp-read-tags-completing))
6204 current-prefix-arg
6205 (and diredp-prompt-for-bookmark-prefix-flag
6206 (read-string "Prefix for autofile bookmark names: "))))
6207 (diredp-ensure-bookmark+)
6208 (diredp-ensure-mode)
6209 (diredp-mark-files-tagged-all/none tags (not allp) nil prefix))
6210
6211;;;###autoload
6212(defun diredp-mark-files-tagged-some (tags &optional somenotp prefix) ; `T m +'
6213 "Mark all files that are tagged with *some* tag in TAGS.
6214As a special case, if TAGS is empty, then mark the files that have
6215 any tags at all (i.e., at least one tag).
6216With a prefix arg, mark all that are *not* tagged with *all* TAGS.
6217You need library `bookmark+.el' to use this command."
6218 (interactive (list (and (fboundp 'bmkp-read-tags-completing) (bmkp-read-tags-completing))
6219 current-prefix-arg
6220 (and diredp-prompt-for-bookmark-prefix-flag
6221 (read-string "Prefix for autofile bookmark names: "))))
6222 (diredp-ensure-bookmark+)
6223 (diredp-ensure-mode)
6224 (diredp-mark-files-tagged-some/not-all tags somenotp nil prefix))
6225
6226;;;###autoload
6227(defun diredp-mark-files-tagged-not-all (tags &optional somep prefix) ; `T m ~ *'
6228 "Mark all files that are not tagged with *all* TAGS.
6229As a special case, if TAGS is empty, then mark the files that have
6230 no tags at all.
6231With a prefix arg, mark all that are tagged with *some* TAGS.
6232You need library `bookmark+.el' to use this command."
6233 (interactive (list (and (fboundp 'bmkp-read-tags-completing) (bmkp-read-tags-completing))
6234 current-prefix-arg
6235 (and diredp-prompt-for-bookmark-prefix-flag
6236 (read-string "Prefix for autofile bookmark names: "))))
6237 (diredp-ensure-bookmark+)
6238 (diredp-ensure-mode)
6239 (diredp-mark-files-tagged-some/not-all tags (not somep) nil prefix))
6240
6241;;;###autoload
6242(defun diredp-mark-files-tagged-regexp (regexp &optional notp prefix) ; `T m %'
6243 "Mark files that have at least one tag that matches REGEXP.
6244With a prefix arg, mark all that are tagged but have no matching tags.
6245You need library `bookmark+.el' to use this command."
6246 (interactive (list (read-string "Regexp: ")
6247 current-prefix-arg
6248 (and diredp-prompt-for-bookmark-prefix-flag
6249 (read-string "Prefix for autofile bookmark names: "))))
6250 (diredp-ensure-bookmark+)
6251 (diredp-ensure-mode)
6252 (diredp-mark-if (and (not (diredp-looking-at-p dired-re-dot)) (not (eolp))
6253 (lexical-let* ((fname (dired-get-filename nil t))
6254 (bmk (and fname
6255 (bmkp-get-autofile-bookmark fname nil prefix)))
6256 (btgs (and bmk (bmkp-get-tags bmk)))
6257 (anyp (and btgs (bmkp-some #'(lambda (tag)
6258 (diredp-string-match-p
6259 regexp
6260 (bmkp-tag-name tag)))
6261 btgs))))
6262 (and btgs (if notp (not anyp) anyp))))
6263 "some-tag-matching-regexp file"))
6264
6265;;;###autoload
6266(defun diredp-unmark-files-tagged-regexp (regexp &optional notp prefix) ; `T u %'
6267 "Unmark files that have at least one tag that matches REGEXP.
6268With a prefix arg, unmark all that are tagged but have no matching tags.
6269You need library `bookmark+.el' to use this command."
6270 (interactive (list (read-string "Regexp: ")
6271 current-prefix-arg
6272 (and diredp-prompt-for-bookmark-prefix-flag
6273 (read-string "Prefix for autofile bookmark names: "))))
6274 (diredp-ensure-bookmark+)
6275 (diredp-ensure-mode)
6276 (let ((dired-marker-char ?\040))
6277 (diredp-mark-if (and (not (diredp-looking-at-p dired-re-dot)) (not (eolp))
6278 (lexical-let* ((fname (dired-get-filename nil t))
6279 (bmk (and fname (bmkp-get-autofile-bookmark fname nil prefix)))
6280 (btgs (and bmk (bmkp-get-tags bmk)))
6281 (anyp (and btgs (bmkp-some #'(lambda (tag)
6282 (diredp-string-match-p
6283 regexp
6284 (bmkp-tag-name tag)))
6285 btgs))))
6286 (and btgs (if notp (not anyp) anyp))))
6287 "some-tag-matching-regexp file")))
6288
6289;;;###autoload
6290(defun diredp-unmark-files-tagged-all (tags &optional none-p prefix) ; `T u *'
6291 "Unmark all files that are tagged with *each* tag in TAGS.
6292As a special case, if TAGS is empty, then unmark the files that have
6293 any tags at all (i.e., at least one tag).
6294With a prefix arg, unmark all that are *not* tagged with *any* TAGS.
6295You need library `bookmark+.el' to use this command."
6296 (interactive (list (and (fboundp 'bmkp-read-tags-completing) (bmkp-read-tags-completing))
6297 current-prefix-arg
6298 (and diredp-prompt-for-bookmark-prefix-flag
6299 (read-string "Prefix for autofile bookmark names: "))))
6300 (diredp-ensure-bookmark+)
6301 (diredp-ensure-mode)
6302 (diredp-mark-files-tagged-all/none tags none-p 'UNMARK prefix))
6303
6304;;;###autoload
6305(defun diredp-unmark-files-tagged-none (tags &optional allp prefix) ; `T u ~ +'
6306 "Unmark all files that are *not* tagged with *any* tag in TAGS.
6307As a special case, if TAGS is empty, then unmark the files that have
6308 no tags at all.
6309With a prefix arg, unmark all that are tagged with *each* tag in TAGS.
6310You need library `bookmark+.el' to use this command."
6311 (interactive (list (and (fboundp 'bmkp-read-tags-completing) (bmkp-read-tags-completing))
6312 current-prefix-arg
6313 (and diredp-prompt-for-bookmark-prefix-flag
6314 (read-string "Prefix for autofile bookmark names: "))))
6315 (diredp-ensure-bookmark+)
6316 (diredp-ensure-mode)
6317 (diredp-mark-files-tagged-all/none tags (not allp) 'UNMARK prefix))
6318
6319;;;###autoload
6320(defun diredp-unmark-files-tagged-some (tags &optional somenotp prefix) ; `T u +'
6321 "Unmark all files that are tagged with *some* tag in TAGS.
6322As a special case, if TAGS is empty, then unmark the files that have
6323 any tags at all.
6324With a prefix arg, unmark all that are *not* tagged with *all* TAGS.
6325You need library `bookmark+.el' to use this command."
6326 (interactive (list (and (fboundp 'bmkp-read-tags-completing) (bmkp-read-tags-completing))
6327 current-prefix-arg
6328 (and diredp-prompt-for-bookmark-prefix-flag
6329 (read-string "Prefix for autofile bookmark names: "))))
6330 (diredp-ensure-bookmark+)
6331 (diredp-ensure-mode)
6332 (diredp-mark-files-tagged-some/not-all tags somenotp 'UNMARK prefix))
6333
6334;;;###autoload
6335(defun diredp-unmark-files-tagged-not-all (tags &optional somep prefix) ; `T u ~ *'
6336 "Unmark all files that are *not* tagged with *all* TAGS.
6337As a special case, if TAGS is empty, then unmark the files that have
6338 no tags at all.
6339With a prefix arg, unmark all that are tagged with *some* TAGS.
6340You need library `bookmark+.el' to use this command."
6341 (interactive (list (and (fboundp 'bmkp-read-tags-completing) (bmkp-read-tags-completing))
6342 current-prefix-arg
6343 (and diredp-prompt-for-bookmark-prefix-flag
6344 (read-string "Prefix for autofile bookmark names: "))))
6345 (diredp-ensure-bookmark+)
6346 (diredp-ensure-mode)
6347 (diredp-mark-files-tagged-some/not-all tags (not somep) 'UNMARK prefix))
6348
6349;;;###autoload
6350(defun diredp-do-tag (tags &optional prefix arg) ; `T > +'
6351 "Tag the marked (or the next prefix argument) files.
6352You need library `bookmark+.el' to use this command.
6353
6354Hit `RET' to enter each tag, then hit `RET' again after the last tag.
6355You can use completion to enter each tag. Completion is lax: you are
6356not limited to existing tags.
6357
6358TAGS is a list of strings. PREFIX is as for `diredp-do-bookmark'.
6359
6360A prefix argument ARG specifies files to use instead of those marked.
6361 An integer means use the next ARG files (previous -ARG, if < 0).
6362 `C-u': Use the current file (whether or not any are marked).
6363 `C-u C-u': Use all files in Dired, except directories.
6364 `C-u C-u C-u': Use all files and directories, except `.' and `..'.
6365 `C-u C-u C-u C-u': Use all files and all directories."
6366 (interactive (progn (diredp-ensure-bookmark+)
6367 (diredp-ensure-mode)
6368 (list (bmkp-read-tags-completing)
6369 (and diredp-prompt-for-bookmark-prefix-flag
6370 (read-string "Prefix for autofile bookmark name: "))
6371 current-prefix-arg)))
6372 (dired-map-over-marks-check (lexical-let ((pref prefix)) #'(lambda () (diredp-tag tags pref)))
6373 arg 'tag (diredp-fewer-than-2-files-p arg)))
6374
6375(defun diredp-tag (tags &optional prefix)
6376 "Add tags to the file or directory named on the current line.
6377You need library `bookmark+.el' to use this function.
6378The bookmark name is the non-directory portion of the file name,
6379 prefixed by PREFIX if it is non-nil.
6380Return nil for success, file name otherwise."
6381 (bookmark-maybe-load-default-file)
6382 (let ((file (dired-get-file-for-visit))
6383 failure)
6384 (condition-case err
6385 (bmkp-autofile-add-tags file tags nil prefix)
6386 (error (setq failure (error-message-string err))))
6387 (if (not failure)
6388 nil ; Return nil for success.
6389 (dired-log failure)
6390 (dired-make-relative file)))) ; Return file name for failure.
6391
6392;;;###autoload
6393(defun diredp-mouse-do-tag (event) ; Not bound
6394 "In Dired, add some tags to this file.
6395You need library `bookmark+.el' to use this command."
6396 (interactive "e")
6397 (diredp-ensure-bookmark+)
6398 (diredp-ensure-mode)
6399 (lexical-let ((mouse-pos (event-start event))
6400 (dired-no-confirm t)
6401 (prefix (and diredp-prompt-for-bookmark-prefix-flag
6402 (read-string "Prefix for bookmark name: "))))
6403 (select-window (posn-window mouse-pos))
6404 (goto-char (posn-point mouse-pos))
6405 (dired-map-over-marks-check #'(lambda () (diredp-tag (bmkp-read-tags-completing) prefix))
6406 1 'tag t))
6407 (diredp-previous-line 1))
6408
6409;;;###autoload
6410(defun diredp-do-untag (tags &optional prefix arg) ; `T > -'
6411 "Remove some tags from the marked (or the next prefix arg) files.
6412You need library `bookmark+.el' to use this command.
6413
6414Hit `RET' to enter each tag, then hit `RET' again after the last tag.
6415You can use completion to enter each tag. Completion is lax: you are
6416not limited to existing tags.
6417
6418TAGS is a list of strings. PREFIX is as for `diredp-do-bookmark'.
6419
6420A prefix argument ARG specifies files to use instead of those marked.
6421 An integer means use the next ARG files (previous -ARG, if < 0).
6422 `C-u': Use the current file (whether or not any are marked).
6423 `C-u C-u': Use all files in Dired, except directories.
6424 `C-u C-u C-u': Use all files and directories, except `.' and `..'.
6425 `C-u C-u C-u C-u': Use all files and all directories."
6426 (interactive (progn (diredp-ensure-bookmark+)
6427 (diredp-ensure-mode)
6428 (list (bmkp-read-tags-completing)
6429 (and diredp-prompt-for-bookmark-prefix-flag
6430 (read-string "Prefix for bookmark name: "))
6431 current-prefix-arg)))
6432 (dired-map-over-marks-check (lexical-let ((pref prefix))
6433 #'(lambda () (diredp-untag tags pref)))
6434 arg 'untag (diredp-fewer-than-2-files-p arg)))
6435
6436(defun diredp-untag (tags &optional prefix)
6437 "Remove some tags from the file or directory named on the current line.
6438You need library `bookmark+.el' to use this function.
6439The bookmark name is the non-directory portion of the file name,
6440 prefixed by PREFIX if it is non-nil.
6441Return nil for success, file name otherwise."
6442 (bookmark-maybe-load-default-file)
6443 (let ((file (dired-get-file-for-visit))
6444 failure)
6445 (condition-case err
6446 (bmkp-autofile-remove-tags file tags nil prefix)
6447 (error (setq failure (error-message-string err))))
6448 (if (not failure)
6449 nil ; Return nil for success.
6450 (dired-log failure)
6451 (dired-make-relative file)))) ; Return file name for failure.
6452
6453;;;###autoload
6454(defun diredp-mouse-do-untag (event) ; Not bound
6455 "In Dired, remove some tags from this file.
6456You need library `bookmark+.el' to use this command."
6457 (interactive "e")
6458 (diredp-ensure-bookmark+)
6459 (diredp-ensure-mode)
6460 (lexical-let ((mouse-pos (event-start event))
6461 (dired-no-confirm t)
6462 (prefix (and diredp-prompt-for-bookmark-prefix-flag
6463 (read-string "Prefix for bookmark name: "))))
6464 (select-window (posn-window mouse-pos))
6465 (goto-char (posn-point mouse-pos))
6466 (lexical-let* ((bmk (bmkp-get-autofile-bookmark (dired-get-filename) nil prefix))
6467 (btgs (and bmk (bmkp-get-tags bmk))))
6468 (unless btgs (error "File has no tags to remove"))
6469 (dired-map-over-marks-check
6470 #'(lambda () (diredp-untag (bmkp-read-tags-completing btgs) prefix)) 1 'untag t)))
6471 (diredp-previous-line 1))
6472
6473;;;###autoload
6474(defun diredp-do-remove-all-tags (&optional prefix arg) ; `T > 0'
6475 "Remove all tags from the marked (or the next prefix arg) files.
6476You need library `bookmark+.el' to use this command.
6477
6478PREFIX is as for `diredp-do-bookmark'.
6479
6480A prefix argument ARG specifies files to use instead of those marked.
6481 An integer means use the next ARG files (previous -ARG, if < 0).
6482 `C-u': Use the current file (whether or not any are marked).
6483 `C-u C-u': Use all files in Dired, except directories.
6484 `C-u C-u C-u': Use all files and directories, except `.' and `..'.
6485 `C-u C-u C-u C-u': Use all files and all directories."
6486 (interactive (progn (diredp-ensure-bookmark+)
6487 (diredp-ensure-mode)
6488 (list (and diredp-prompt-for-bookmark-prefix-flag
6489 (read-string "Prefix for bookmark name: "))
6490 current-prefix-arg)))
6491 (lexical-let ((pref prefix))
6492 (dired-map-over-marks-check #'(lambda () (diredp-remove-all-tags pref)) arg 'remove-all-tags
6493 (diredp-fewer-than-2-files-p arg))))
6494
6495(defun diredp-remove-all-tags (&optional prefix)
6496 "Remove all tags from the file or directory named on the current line.
6497You need library `bookmark+.el' to use this function.
6498The bookmark name is the non-directory portion of the file name,
6499 prefixed by PREFIX if it is non-nil.
6500Return nil for success, file name otherwise."
6501 (bookmark-maybe-load-default-file)
6502 (let ((file (dired-get-file-for-visit))
6503 failure)
6504 (condition-case err
6505 (bmkp-remove-all-tags (bmkp-autofile-set file nil prefix))
6506 (error (setq failure (error-message-string err))))
6507 (if (not failure)
6508 nil ; Return nil for success.
6509 (dired-log failure)
6510 (dired-make-relative file)))) ; Return file name for failure.
6511
6512;;;###autoload
6513(defun diredp-mouse-do-remove-all-tags (event) ; Not bound
6514 "In Dired, remove all tags from the marked (or next prefix arg) files.
6515You need library `bookmark+.el' to use this command."
6516 (interactive "e")
6517 (diredp-ensure-bookmark+)
6518 (diredp-ensure-mode)
6519 (lexical-let ((mouse-pos (event-start event))
6520 (dired-no-confirm t)
6521 (prefix (and diredp-prompt-for-bookmark-prefix-flag
6522 (read-string "Prefix for bookmark name: "))))
6523 (select-window (posn-window mouse-pos))
6524 (goto-char (posn-point mouse-pos))
6525 (dired-map-over-marks-check #'(lambda () (diredp-remove-all-tags prefix))
6526 1 'remove-all-tags t))
6527 (diredp-previous-line 1))
6528
6529;;;###autoload
6530(defun diredp-do-paste-add-tags (&optional prefix arg) ; `T > p', `T > C-y'
6531 "Add previously copied tags to the marked (or next prefix arg) files.
6532The tags were previously copied from a file to `bmkp-copied-tags'.
6533You need library `bookmark+.el' to use this command.
6534
6535A prefix argument ARG specifies files to use instead of those marked.
6536 An integer means use the next ARG files (previous -ARG, if < 0).
6537 `C-u': Use the current file (whether or not any are marked).
6538 `C-u C-u': Use all files in Dired, except directories.
6539 `C-u C-u C-u': Use all files and directories, except `.' and `..'.
6540 `C-u C-u C-u C-u': Use all files and all directories."
6541 (interactive (progn (diredp-ensure-bookmark+)
6542 (diredp-ensure-mode)
6543 (list (and diredp-prompt-for-bookmark-prefix-flag
6544 (read-string "Prefix for autofile bookmark name: "))
6545 current-prefix-arg)))
6546 (dired-map-over-marks-check (lexical-let ((pref prefix))
6547 #'(lambda () (diredp-paste-add-tags pref)))
6548 arg 'paste-add-tags
6549 (diredp-fewer-than-2-files-p arg)))
6550
6551(defun diredp-paste-add-tags (&optional prefix)
6552 "Add previously copied tags to the file or directory on the current line.
6553The tags were previously copied from a file to `bmkp-copied-tags'.
6554You need library `bookmark+.el' to use this function.
6555The bookmark name is the non-directory portion of the file name,
6556 prefixed by PREFIX if it is non-nil.
6557Return nil for success, file name otherwise."
6558 (bookmark-maybe-load-default-file)
6559 (let ((file (dired-get-file-for-visit))
6560 failure)
6561 (condition-case err
6562 (bmkp-autofile-add-tags file bmkp-copied-tags nil prefix)
6563 (error (setq failure (error-message-string err))))
6564 (if (not failure)
6565 nil ; Return nil for success.
6566 (dired-log failure)
6567 (dired-make-relative file)))) ; Return file name for failure.
6568
6569;;;###autoload
6570(defun diredp-mouse-do-paste-add-tags (event) ; Not bound
6571 "In Dired, add previously copied tags to this file.
6572The tags were previously copied from a file to `bmkp-copied-tags'.
6573You need library `bookmark+.el' to use this command."
6574 (interactive "e")
6575 (diredp-ensure-bookmark+)
6576 (diredp-ensure-mode)
6577 (lexical-let ((mouse-pos (event-start event))
6578 (dired-no-confirm t)
6579 (prefix (and diredp-prompt-for-bookmark-prefix-flag
6580 (read-string "Prefix for bookmark name: "))))
6581 (select-window (posn-window mouse-pos))
6582 (goto-char (posn-point mouse-pos))
6583 (dired-map-over-marks-check #'(lambda () (diredp-paste-add-tags prefix))
6584 1 'paste-add-tags t))
6585 (diredp-previous-line 1))
6586
6587;;;###autoload
6588(defun diredp-do-paste-replace-tags (&optional prefix arg) ; `T > q'
6589 "Replace tags for marked (or next prefix arg) files with copied tags.
6590The tags were previously copied from a file to `bmkp-copied-tags'.
6591You need library `bookmark+.el' to use this command.
6592
6593A prefix argument ARG specifies files to use instead of those marked.
6594 An integer means use the next ARG files (previous -ARG, if < 0).
6595 `C-u': Use the current file (whether or not any are marked).
6596 `C-u C-u': Use all files in Dired, except directories.
6597 `C-u C-u C-u': Use all files and directories, except `.' and `..'.
6598 `C-u C-u C-u C-u': Use all files and all directories."
6599 (interactive (progn (diredp-ensure-bookmark+)
6600 (diredp-ensure-mode)
6601 (list (and diredp-prompt-for-bookmark-prefix-flag
6602 (read-string "Prefix for autofile bookmark name: "))
6603 current-prefix-arg)))
6604 (dired-map-over-marks-check (lexical-let ((pref prefix))
6605 #'(lambda () (diredp-paste-replace-tags pref)))
6606 arg 'paste-replace-tags (diredp-fewer-than-2-files-p arg)))
6607
6608(defun diredp-paste-replace-tags (&optional prefix)
6609 "Replace tags for this file or dir with tags copied previously.
6610The tags were previously copied from a file to `bmkp-copied-tags'.
6611You need library `bookmark+.el' to use this function.
6612The bookmark name is the non-directory portion of the file name,
6613 prefixed by PREFIX if it is non-nil.
6614Return nil for success, file name otherwise."
6615 (bookmark-maybe-load-default-file)
6616 (let ((file (dired-get-file-for-visit))
6617 failure)
6618 (condition-case err
6619 (progn (bmkp-remove-all-tags (bmkp-autofile-set file nil prefix))
6620 (bmkp-autofile-add-tags file bmkp-copied-tags nil prefix))
6621 (error (setq failure (error-message-string err))))
6622 (if (not failure)
6623 nil ; Return nil for success.
6624 (dired-log failure)
6625 (dired-make-relative file))))
6626
6627;;;###autoload
6628(defun diredp-mouse-do-paste-replace-tags (event) ; Not bound
6629 "In Dired, replace tags for this file with tags copied previously.
6630The tags were previously copied from a file to `bmkp-copied-tags'.
6631You need library `bookmark+.el' to use this command."
6632 (interactive "e")
6633 (diredp-ensure-bookmark+)
6634 (diredp-ensure-mode)
6635 (lexical-let ((mouse-pos (event-start event))
6636 (dired-no-confirm t)
6637 (prefix (and diredp-prompt-for-bookmark-prefix-flag
6638 (read-string "Prefix for bookmark name: "))))
6639 (select-window (posn-window mouse-pos))
6640 (goto-char (posn-point mouse-pos))
6641 (dired-map-over-marks-check #'(lambda () (diredp-paste-replace-tags prefix))
6642 1 'paste-replace-tags t))
6643 (diredp-previous-line 1))
6644
6645;;;###autoload
6646(defun diredp-do-set-tag-value (tag value &optional prefix arg) ; `T > v'
6647 "Set TAG value to VALUE, for the marked (or next prefix arg) files.
6648This does not change the TAG name.
6649You need library `bookmark+.el' to use this command.
6650
6651PREFIX is as for `diredp-do-bookmark'.
6652
6653A prefix argument ARG specifies files to use instead of those marked.
6654 An integer means use the next ARG files (previous -ARG, if < 0).
6655 `C-u': Use the current file (whether or not any are marked).
6656 `C-u C-u': Use all files in Dired, except directories.
6657 `C-u C-u C-u': Use all files and directories, except `.' and `..'.
6658 `C-u C-u C-u C-u': Use all files and all directories."
6659 (interactive (progn (diredp-ensure-bookmark+)
6660 (diredp-ensure-mode)
6661 (list (bmkp-read-tag-completing)
6662 (read (read-string "Value: "))
6663 (and diredp-prompt-for-bookmark-prefix-flag
6664 (read-string "Prefix for bookmark name: "))
6665 current-prefix-arg)))
6666 (dired-map-over-marks-check (lexical-let ((tg tag)
6667 (val value)
6668 (pref prefix))
6669 #'(lambda () (diredp-set-tag-value tg val pref)))
6670 arg 'set-tag-value (diredp-fewer-than-2-files-p arg)))
6671
6672(defun diredp-set-tag-value (tag value &optional prefix)
6673 "Set TAG value to VALUE for this file or directory.
6674This does not change the TAG name.
6675You need library `bookmark+.el' to use this function.
6676The bookmark name is the non-directory portion of the file name,
6677 prefixed by PREFIX if it is non-nil.
6678Return nil for success, file name otherwise."
6679 (bookmark-maybe-load-default-file)
6680 (let ((file (dired-get-file-for-visit))
6681 failure)
6682 (condition-case err
6683 (bmkp-set-tag-value (bmkp-autofile-set file nil prefix) tag value)
6684 (error (setq failure (error-message-string err))))
6685 (if (not failure)
6686 nil ; Return nil for success.
6687 (dired-log failure)
6688 (dired-make-relative file)))) ; Return file name for failure.
6689
6690;;;###autoload
6691(defun diredp-mouse-do-set-tag-value (event) ; Not bound
6692 "In Dired, set the value of a tag for this file.
6693This does not change the tag name.
6694You need library `bookmark+.el' to use this command."
6695 (interactive "e")
6696 (diredp-ensure-bookmark+)
6697 (diredp-ensure-mode)
6698 (lexical-let ((mouse-pos (event-start event))
6699 (dired-no-confirm t)
6700 (prefix (and diredp-prompt-for-bookmark-prefix-flag
6701 (read-string "Prefix for bookmark name: "))))
6702 (select-window (posn-window mouse-pos))
6703 (goto-char (posn-point mouse-pos))
6704 (dired-map-over-marks-check #'(lambda () (diredp-set-tag-value (bmkp-read-tag-completing)
6705 (read (read-string "Value: "))
6706 prefix))
6707 1 'set-tag-value t))
6708 (diredp-previous-line 1))
6709
6710
6711;; Define these even if `Bookmark+' is not loaded.
6712;;;###autoload
6713(defun diredp-mark-autofiles () ; Bound to `* B'
6714 "Mark all autofiles, that is, files that have an autofile bookmark."
6715 (interactive)
6716 (diredp-ensure-bookmark+)
6717 (diredp-ensure-mode)
6718 (diredp-mark/unmark-autofiles))
6719
6720;;;###autoload
6721(defun diredp-unmark-autofiles ()
6722 "Unmark all autofiles, that is, files that have an autofile bookmark."
6723 (interactive)
6724 (diredp-ensure-bookmark+)
6725 (diredp-ensure-mode)
6726 (diredp-mark/unmark-autofiles t))
6727
6728;;;###autoload
6729(defun diredp-mark/unmark-autofiles (&optional unmarkp)
6730 "Mark all autofiles, or unmark if UNMARKP is non-nil."
6731 (let ((dired-marker-char (if unmarkp ?\040 dired-marker-char)))
6732 (diredp-mark-if (and (not (diredp-looking-at-p dired-re-dot)) (not (eolp))
6733 (let ((fname (dired-get-filename nil t)))
6734 (and fname (bmkp-get-autofile-bookmark fname))))
6735 "autofile")))
6736
6737(when (and (fboundp 'bmkp-get-autofile-bookmark) ; Defined in `bookmark+-1.el'.
6738 (fboundp 'hlt-highlight-region)) ; Defined in `highlight.el'.
6739
6740 (defun diredp-highlight-autofiles ()
6741 "Highlight files that are autofile bookmarks.
6742Highlighting uses face `diredp-autofile-name'."
6743 (save-excursion
6744 (goto-char (point-min))
6745 (while (re-search-forward dired-move-to-filename-regexp nil t)
6746 ;; If Dired details are hidden the match data gets changed.
6747 (let* ((bmk (save-match-data
6748 (bmkp-get-autofile-bookmark (buffer-substring (match-end 0) (line-end-position)))))
6749 (tags (and bmk (bmkp-get-tags bmk))))
6750 (when bmk
6751 (hlt-highlight-region (match-end 0) (line-end-position)
6752 (if tags
6753 'diredp-tagged-autofile-name
6754 'diredp-autofile-name)))))))
6755
6756 (cond ((fboundp 'define-minor-mode)
6757 ;; Emacs 21+. Use `eval' so that even if the library is byte-compiled with Emacs 20,
6758 ;; loading it into Emacs 21+ will define variable `diredp-highlight-autofiles-mode'.
6759 (eval '(define-minor-mode diredp-highlight-autofiles-mode
6760 "Toggle automatic highlighting of autofile bookmarks.
6761When you turn this on, it ensures that your bookmark file is loaded.
6762
6763NOTE: This mode is ON BY DEFAULT. More precisely, when `dired+.el' is
6764loaded (for the first time per Emacs session), the mode is turned ON.
6765To prevent this and have the mode OFF by default, you must do one of
6766the following:
6767
6768 * Put (diredp-highlight-autofiles-mode -1) in your init file, AFTER
6769 it loads `dired+.el'.
6770
6771 * Customize option `diredp-highlight-autofiles-mode' to `nil', AND
6772 ensure that your `custom-file' (or the `custom-saved-variables'
6773 part of your init file) is evaluated before `dired+.el' is loaded.
6774
6775You need libraries `Bookmark and `highlight.el' for this command."
6776 :init-value t :global t :group 'Dired-Plus :require 'dired+
6777 (if (not diredp-highlight-autofiles-mode)
6778 (remove-hook 'dired-after-readin-hook #'diredp-highlight-autofiles)
6779 (add-hook 'dired-after-readin-hook #'diredp-highlight-autofiles)
6780 (bookmark-maybe-load-default-file))
6781 (when (derived-mode-p 'dired-mode) (dired-revert nil nil))
6782 (when (interactive-p)
6783 (message "Dired highlighting of autofile bookmarks is now %s"
6784 (if diredp-highlight-autofiles-mode "ON" "OFF"))))))
6785 (t;; Emacs 20.
6786 (defun diredp-highlight-autofiles-mode (&optional arg)
6787 "Toggle automatic highlighting of autofile bookmarks.
6788When you turn this on, it ensures that your bookmark file is loaded.
6789
6790NOTE: This mode is ON BY DEFAULT. More precisely, when `dired+.el' is
6791loaded (for the first time per Emacs session), the mode is turned ON.
6792To prevent this and have the mode OFF by default, you must do one of
6793the following:
6794
6795 * Put (diredp-highlight-autofiles-mode -1) in your init file, AFTER
6796 it loads `dired+.el'.
6797
6798 * Customize option `diredp-highlight-autofiles-mode' to `nil', AND
6799 ensure that your `custom-file' (or the `custom-saved-variables'
6800 part of your init file) is evaluated before `dired+.el' is loaded.
6801
6802You need libraries `Bookmark and `highlight.el' for this command."
6803 (interactive (list (or current-prefix-arg 'toggle)))
6804 (setq diredp-highlight-autofiles-mode (if (eq arg 'toggle)
6805 (not diredp-highlight-autofiles-mode)
6806 (> (prefix-numeric-value arg) 0)))
6807 (if (not diredp-highlight-autofiles-mode)
6808 (remove-hook 'dired-after-readin-hook #'diredp-highlight-autofiles)
6809 (add-hook 'dired-after-readin-hook #'diredp-highlight-autofiles)
6810 (bookmark-maybe-load-default-file))
6811 (when (derived-mode-p 'dired-mode) (dired-revert nil nil))
6812 (when (interactive-p) (message "Dired highlighting of autofile bookmarks is now %s"
6813 (if diredp-highlight-autofiles-mode "ON" "OFF"))))))
6814
6815 ;; Turn it ON BY DEFAULT.
6816 (unless (or (boundp 'diredp-loaded-p) (get 'diredp-highlight-autofiles-mode 'saved-value))
6817 (diredp-highlight-autofiles-mode 1))
6818 )
6819
6820;;;###autoload
6821(defun diredp-do-bookmark (&optional prefix arg) ; Bound to `M-b'
6822 "Bookmark the marked (or the next prefix argument) files.
6823Each bookmark name is the non-directory portion of the file name,
6824 prefixed by PREFIX if it is non-nil.
6825Interactively, you are prompted for the PREFIX if
6826 `diredp-prompt-for-bookmark-prefix-flag' is non-nil.
6827The bookmarked position is the beginning of the file.
6828If you use library `bookmark+.el' then the bookmark is an autofile.
6829
6830A prefix argument ARG specifies files to use instead of those marked.
6831 An integer means use the next ARG files (previous -ARG, if < 0).
6832 `C-u': Use the current file (whether or not any are marked).
6833 `C-u C-u': Use all files in Dired, except directories.
6834 `C-u C-u C-u': Use all files and directories, except `.' and `..'.
6835 `C-u C-u C-u C-u': Use all files and all directories."
6836 (interactive (progn (diredp-ensure-mode)
6837 (list (and diredp-prompt-for-bookmark-prefix-flag
6838 (read-string "Prefix for bookmark name: "))
6839 current-prefix-arg)))
6840 (dired-map-over-marks-check (lexical-let ((pref prefix))
6841 #'(lambda () (diredp-bookmark pref nil 'NO-MSG-P)))
6842 arg 'bookmark (diredp-fewer-than-2-files-p arg)))
6843
6844;;;###autoload
6845(defun diredp-mouse-do-bookmark (event) ; Not bound
6846 "In Dired, bookmark this file. See `diredp-do-bookmark'."
6847 (interactive "e")
6848 (lexical-let ((mouse-pos (event-start event))
6849 (dired-no-confirm t)
6850 (prefix (and diredp-prompt-for-bookmark-prefix-flag
6851 (read-string "Prefix for bookmark name: "))))
6852 (select-window (posn-window mouse-pos))
6853 (goto-char (posn-point mouse-pos))
6854 (dired-map-over-marks-check #'(lambda () (diredp-bookmark prefix nil)) nil 'bookmark t))
6855 (diredp-previous-line 1))
6856
6857(defun diredp-bookmark (&optional prefix file no-msg-p)
6858 "Bookmark the file or directory FILE.
6859If you use library `bookmark+.el' then the bookmark is an autofile.
6860Return nil for success or the file name otherwise.
6861
6862The bookmark name is the (non-directory) file name, prefixed by
6863 optional arg PREFIX (a string) if non-nil.
6864
6865FILE defaults to the file name on the current Dired line.
6866
6867Non-nil optional arg NO-MSG-P means do not show progress messages."
6868 (bookmark-maybe-load-default-file)
6869 (let ((fil (or file (dired-get-file-for-visit)))
6870 (failure nil))
6871 (condition-case err
6872 (if (fboundp 'bmkp-autofile-set) ; Bookmark+ - just set an autofile bookmark.
6873 (bmkp-autofile-set fil nil prefix nil (not no-msg-p))
6874 ;; Vanilla `bookmark.el' (or very old Bookmark+ version).
6875 (let ((bookmark-make-record-function
6876 (cond ((and (require 'image nil t) (require 'image-mode nil t)
6877 (condition-case nil (image-type fil) (error nil)))
6878 ;; Last two lines of function are from `image-bookmark-make-record'.
6879 ;; But don't use that directly, because it uses
6880 ;; `bookmark-make-record-default', which gets nil for `filename'.
6881 (lambda ()
6882 `((filename . ,fil)
6883 (position . 0)
6884 ;; NEED to keep this part of code sync'd with `bmkp-make-record-for-target-file'.
6885 (image-type . ,(image-type fil))
6886 (handler . image-bookmark-jump)))) ; In `image-mode.el'.
6887 (t
6888 (lambda ()
6889 `((filename . ,fil)
6890 (position . 0)))))))
6891 (bookmark-store (concat prefix (file-name-nondirectory fil)) (cdr (bookmark-make-record)) nil)))
6892 (error (setq failure (error-message-string err))))
6893 (if (not failure)
6894 nil ; Return nil for success.
6895 (if (fboundp 'bmkp-autofile-set)
6896 (dired-log failure)
6897 (dired-log "Failed to create bookmark for `%s':\n%s\n" fil failure))
6898 (dired-make-relative fil)))) ; Return file name for failure.
6899
6900;;;###autoload
6901(defun diredp-set-bookmark-file-bookmark-for-marked (bookmark-file ; Bound to `C-M-b'
6902 &optional prefix arg)
6903 "Bookmark the marked files and create a bookmark-file bookmark for them.
6904The bookmarked position is the beginning of the file.
6905Jumping to the bookmark-file bookmark loads the set of file bookmarks.
6906You need library `bookmark+.el' to use this command.
6907
6908Each bookmark name is the non-directory portion of the file name,
6909 prefixed by PREFIX if it is non-nil.
6910Interactively, you are prompted for PREFIX if
6911 `diredp-prompt-for-bookmark-prefix-flag' is non-nil.
6912
6913A prefix argument ARG specifies files to use instead of those marked.
6914 An integer means use the next ARG files (previous -ARG, if < 0).
6915 `C-u': Use the current file (whether or not any are marked).
6916 `C-u C-u': Use all files in Dired, except directories.
6917 `C-u C-u C-u': Use all files and directories, except `.' and `..'.
6918 `C-u C-u C-u C-u': Use all files and all directories.
6919
6920You are also prompted for the bookmark file, BOOKMARK-FILE. The
6921default is `.emacs.bmk' in the current directory, but you can enter
6922any file name, anywhere.
6923
6924The marked-file bookmarks are added to file BOOKMARK-FILE, but this
6925command does not make BOOKMARK-FILE the current bookmark file. To
6926make it current, just jump to the bookmark-file bookmark created by
6927this command. That bookmark (which bookmarks BOOKMARK-FILE) is
6928defined in that current bookmark file.
6929
6930Example:
6931
6932 Bookmark file `~/.emacs.bmk' is current before invoking this command.
6933 The current (Dired) directory is `/foo/bar'.
6934 The marked files are bookmarked in the (possibly new) bookmark file
6935 `/foo/bar/.emacs.bmk'.
6936 The bookmarks for the marked files have names prefixed by `FOOBAR '.
6937 The name of the bookmark-file bookmark is `Foobar Files'.
6938 Bookmark `Foobar Files' is itself in bookmark file `~/.emacs.bmk'.
6939 Bookmark file `~/.emacs.bmk' is current after invoking this command.
6940
6941You are prompted for the name of the bookmark-file bookmark, the
6942BOOKMARK-FILE for the marked-file bookmarks, and a PREFIX string for
6943each of the marked-file bookmarks.
6944
6945See also command `diredp-do-bookmark-in-bookmark-file'."
6946 (interactive (diredp-read-bookmark-file-args))
6947 (diredp-ensure-bookmark+)
6948 (diredp-do-bookmark-in-bookmark-file bookmark-file prefix arg 'CREATE-BOOKMARK-FILE-BOOKMARK))
6949
6950;;;###autoload
6951(defun diredp-do-bookmark-in-bookmark-file (bookmark-file ; Bound to `C-M-B' (aka `C-M-S-b')
6952 &optional prefix arg bfile-bookmarkp files)
6953 "Bookmark marked files in BOOKMARK-FILE and save BOOKMARK-FILE.
6954The files bookmarked are the marked files, by default.
6955The bookmarked position is the beginning of the file.
6956You are prompted for BOOKMARK-FILE. The default is `.emacs.bmk' in
6957the current directory, but you can enter any file name, anywhere.
6958You need library `bookmark+.el' to use this command.
6959
6960The marked files are bookmarked in file BOOKMARK-FILE, but this
6961command does not make BOOKMARK-FILE the current bookmark file. To
6962make it current, use `\\[bmkp-switch-bookmark-file]' (`bmkp-switch-bookmark-file').
6963
6964Each bookmark name is the non-directory portion of the file name,
6965 prefixed by PREFIX if it is non-nil.
6966Interactively, you are prompted for PREFIX if
6967 `diredp-prompt-for-bookmark-prefix-flag' is non-nil.
6968
6969Interactively, a prefix argument ARG specifies the files to use
6970instead of those marked.
6971
6972 An integer means use the next ARG files (previous -ARG, if < 0).
6973 `C-u': Use the current file (whether or not any are marked).
6974 `C-u C-u': Use all files in Dired, except directories.
6975 `C-u C-u C-u': Use all files and directories, except `.' and `..'.
6976 `C-u C-u C-u C-u': Use all files and all directories.
6977
6978See also command `diredp-set-bookmark-file-bookmark-for-marked'.
6979
6980Non-interactively:
6981
6982 * Non-nil BFILE-BOOKMARKP means create a bookmark-file bookmark for
6983 BOOKMARK-FILE.
6984 * Non-nil FILES is the list of files to bookmark."
6985 (interactive (diredp-read-bookmark-file-args))
6986 (diredp-ensure-bookmark+)
6987 (let ((bfile-exists-p (file-readable-p bookmark-file)))
6988 (unless bfile-exists-p (bmkp-empty-file bookmark-file))
6989 (unless bmkp-current-bookmark-file (setq bmkp-current-bookmark-file bookmark-default-file))
6990 (let ((old-bmkp-current-bookmark-file bmkp-current-bookmark-file))
6991 (unwind-protect
6992 (progn (bmkp-switch-bookmark-file bookmark-file) ; Changes `*-current-bookmark-file'.
6993 (if files
6994 (dolist (file files) (diredp-bookmark prefix file 'NO-MSG-P))
6995 (dired-map-over-marks-check
6996 (lexical-let ((pref prefix)) #'(lambda () (diredp-bookmark pref nil 'NO-MSG-P)))
6997 arg 'bookmark (diredp-fewer-than-2-files-p arg)))
6998 (bookmark-save)
6999 (unless bfile-exists-p (revert-buffer)))
7000 (unless (bmkp-same-file-p old-bmkp-current-bookmark-file bmkp-current-bookmark-file)
7001 (bmkp-switch-bookmark-file old-bmkp-current-bookmark-file 'NO-MSG))))
7002 (when bfile-bookmarkp (bmkp-set-bookmark-file-bookmark bookmark-file))))
7003
7004(defun diredp-read-bookmark-file-args ()
7005 "Read args for `diredp-do-bookmark-in-bookmark-file' and similar."
7006 (diredp-ensure-bookmark+)
7007 (diredp-ensure-mode)
7008 (list (let* ((insert-default-directory t)
7009 (bmk-file (expand-file-name
7010 (read-file-name
7011 "Use bookmark file (default is in CURRENT dir): " nil
7012 (if (or (> emacs-major-version 23)
7013 (and (= emacs-major-version 23) (> emacs-minor-version 1)))
7014 (list ".emacs.bmk" bookmark-default-file)
7015 ".emacs.bmk")))))
7016 bmk-file)
7017 (and diredp-prompt-for-bookmark-prefix-flag (read-string "Prefix for autofile bookmark names: "))
7018 current-prefix-arg))
7019
7020
7021;; REPLACE ORIGINAL in `dired.el'.
7022;;
7023;; Allows for consp `dired-directory' too.
7024;;
7025(defun dired-buffers-for-dir (dir &optional file)
7026 "Return a list of buffers that Dired DIR (top level or in-situ subdir).
7027If FILE is non-nil, include only those whose wildcard pattern (if any)
7028matches FILE.
7029The list is in reverse order of buffer creation, most recent last.
7030As a side effect, killed Dired buffers for DIR are removed from
7031`dired-buffers'."
7032 (setq dir (file-name-as-directory dir))
7033 (let (result buf)
7034 (dolist (elt dired-buffers)
7035 (setq buf (cdr elt))
7036 (cond ((null (buffer-name buf)) ; Buffer is killed - clean up.
7037 (setq dired-buffers (delq elt dired-buffers)))
7038 ((dired-in-this-tree dir (car elt))
7039 (with-current-buffer buf
7040 (and (assoc dir dired-subdir-alist)
7041 (or (null file)
7042 (if (stringp dired-directory)
7043 ;; Allow for consp `dired-directory' too.
7044 (let ((wildcards (file-name-nondirectory (if (consp dired-directory)
7045 (car dired-directory)
7046 dired-directory))))
7047 (or (zerop (length wildcards))
7048 (diredp-string-match-p (dired-glob-regexp wildcards) file)))
7049 (member (expand-file-name file dir) (cdr dired-directory))))
7050 (setq result (cons buf result)))))))
7051 result))
7052
7053
7054;; If you use library `files+.el', you need not use these commands
7055;; explicitly, because that library redefines `find-file-read-args' to
7056;; do the same thing, in Dired mode. These are provided here in case
7057;; you want to bind them directly - for example, in case your code
7058;; does not use `find-file-read-args'.
7059;;
7060;;;###autoload
7061(defun diredp-find-a-file (filename &optional wildcards) ; Not bound
7062 "`find-file', but use file on current line as default (`M-n')."
7063 (interactive (diredp-find-a-file-read-args "Find file: " nil))
7064 (find-file filename wildcards))
7065
7066;;;###autoload
7067(defun diredp-find-a-file-other-frame (filename &optional wildcards) ; Not bound
7068 "`find-file-other-frame', but use file under cursor as default (`M-n')."
7069 (interactive (diredp-find-a-file-read-args "Find file: " nil))
7070 (find-file-other-frame filename wildcards))
7071
7072;;;###autoload
7073(defun diredp-find-a-file-other-window (filename &optional wildcards) ; Not bound
7074 "`find-file-other-window', but use file under cursor as default (`M-n')."
7075 (interactive (diredp-find-a-file-read-args "Find file: " nil))
7076 (find-file-other-window filename wildcards))
7077
7078;;;###autoload
7079(defun diredp-find-a-file-read-args (prompt mustmatch) ; Not bound
7080 (list (lexical-let ((find-file-default (abbreviate-file-name (dired-get-file-for-visit))))
7081 (minibuffer-with-setup-hook (lambda ()
7082 (setq minibuffer-default find-file-default))
7083 (read-file-name prompt nil default-directory mustmatch)))
7084 t))
7085
7086;;;###autoload
7087(defun diredp-find-file-reuse-dir-buffer () ; Not bound
7088 "Like `dired-find-file', but reuse Dired buffers.
7089Unlike `dired-find-alternate-file' this does not use
7090`find-alternate-file' unless (1) the target is a directory that is not
7091yet visited as a Dired buffer, and (2) the current (Dired) buffer is
7092not visited also in some other window (possibly in an iconified
7093frame)."
7094 (interactive)
7095 (set-buffer-modified-p nil)
7096 (let ((file (dired-get-file-for-visit)))
7097 (diredp--reuse-dir-buffer-helper file)))
7098
7099;;;###autoload
7100(defun diredp-mouse-find-file-reuse-dir-buffer (event &optional find-file-func find-dir-func) ; Not bound
7101 "Like `dired-mouse-find-file', but reuse Dired buffers.
7102Unlike `dired-find-alternate-file' this does not use
7103`find-alternate-file' unless (1) the target is a directory that is not
7104yet visited as a Dired buffer, and (2) the current (Dired) buffer is
7105not visited also in some other window (possibly in an iconified
7106frame).
7107
7108Non-nil optional args FIND-FILE-FUNC and FIND-DIR-FUNC specify
7109functions to visit the file and directory, respectively.
7110Defaults: `find-file' and `dired', respectively."
7111 (interactive "e")
7112 (let (window pos file)
7113 (save-excursion
7114 (setq window (posn-window (event-end event))
7115 pos (posn-point (event-end event)))
7116 (unless (windowp window) (error "No file chosen"))
7117 (set-buffer (window-buffer window))
7118 (goto-char pos)
7119 (setq file (dired-get-file-for-visit)))
7120 (select-window window)
7121 (diredp--reuse-dir-buffer-helper file find-file-func find-dir-func)))
7122
7123(defun diredp--reuse-dir-buffer-helper (file &optional find-file-func find-dir-func other-window)
7124 "Helper for commands `diredp-*-reuse-dir-buffer' commands.
7125Non-nil optional args FIND-FILE-FUNC and FIND-DIR-FUNC specify
7126functions to visit the file and directory, respectively.
7127Defaults: `find-file' and `dired', respectively.
7128
7129Unlike `dired-find-alternate-file' this does not use
7130`find-alternate-file' unless (1) the target is a directory that is not
7131yet visited as a Dired buffer, and (2) the current (Dired) buffer is
7132not visited also in some other window (possibly in an iconified
7133frame)."
7134 (setq find-file-func (or find-file-func (if other-window #'find-file-other-window #'find-file))
7135 find-dir-func (or find-dir-func (if other-window #'dired-other-window #'dired)))
7136 (let (;; This binding prevents problems with preserving point in windows displaying Dired buffers, because
7137 ;; reverting a Dired buffer empties it, which changes the places where the markers used by
7138 ;; `switch-to-buffer-preserve-window-point' point.
7139 (switch-to-buffer-preserve-window-point (and (boundp 'switch-to-buffer-preserve-window-point) ; Emacs 24+
7140 (or (not (boundp 'dired-auto-revert-buffer))
7141 (not dired-auto-revert-buffer))
7142 switch-to-buffer-preserve-window-point))
7143 (find-file-run-dired t)
7144 (wins ())
7145 (alt-find-file-func (if other-window
7146 #'find-alternate-file-other-window
7147 #'find-alternate-file))
7148 dir-bufs)
7149 (if (or (not (file-directory-p file)) ; New is a not a directory
7150 (dired-buffers-for-dir file) ; or there is a Dired buffer for it, even as a subdir.
7151 (and (setq dir-bufs (dired-buffers-for-dir default-directory)) ; Dired bufs for current (old).
7152 (progn
7153 (dolist (buf dir-bufs)
7154 (setq wins (append wins (get-buffer-window-list buf 'NOMINI 0))))
7155 (setq wins (delq nil wins))
7156 (cdr wins)))) ; More than one window showing current Dired buffer.
7157 (if (file-directory-p file)
7158 (or (and (cdr dired-subdir-alist) (dired-goto-subdir file)) ; New is a subdir inserted in current
7159 (funcall find-dir-func file))
7160 (funcall find-file-func (file-name-sans-versions file t)))
7161 (funcall alt-find-file-func (file-name-sans-versions file t)))))
7162
7163;;;###autoload
7164(defalias 'toggle-diredp-find-file-reuse-dir 'diredp-toggle-find-file-reuse-dir)
7165;;;###autoload
7166(defun diredp-toggle-find-file-reuse-dir (force-p) ; Bound to `C-M-R' (aka `C-M-S-r')
7167 "Toggle whether Dired `find-file' commands reuse directories.
7168This applies also to `dired-w32-browser' commands and
7169`diredp-up-directory'.
7170
7171A prefix arg specifies directly whether or not to reuse.
7172 If its numeric value is non-negative then reuse; else do not reuse.
7173
7174To set the behavior as a preference (default behavior), put this in
7175your ~/.emacs, where VALUE is 1 to reuse or -1 to not reuse:
7176
7177 (diredp-toggle-find-file-reuse-dir VALUE)
7178
7179Note: This affects only these commands:
7180
7181 `dired-find-file'
7182 `dired-mouse-find-file'
7183
7184It does not affect the corresponding `-other-window' commands. Note
7185too that, by default, mouse clicks to open files or directories open
7186in another window: command `diredp-mouse-find-file-other-window', not
7187`dired-mouse-find-file'. If you want a mouse click to reuse a
7188directory then bind `mouse-2' to `dired-mouse-find-file' instead."
7189 (interactive "P")
7190 (if force-p ; Force.
7191 (if (natnump (prefix-numeric-value force-p))
7192 (diredp-make-find-file-keys-reuse-dirs)
7193 (diredp-make-find-file-keys-not-reuse-dirs))
7194 (if (where-is-internal 'dired-find-file dired-mode-map 'ascii)
7195 (diredp-make-find-file-keys-reuse-dirs)
7196 (diredp-make-find-file-keys-not-reuse-dirs))))
7197
7198(defun diredp-make-find-file-keys-reuse-dirs ()
7199 "Make find-file keys reuse Dired buffers."
7200 (substitute-key-definition 'diredp-up-directory 'diredp-up-directory-reuse-dir-buffer dired-mode-map)
7201 (substitute-key-definition 'dired-find-file 'diredp-find-file-reuse-dir-buffer dired-mode-map)
7202 (substitute-key-definition 'dired-mouse-find-file 'diredp-mouse-find-file-reuse-dir-buffer dired-mode-map)
7203 ;; These commands are defined in `w32-browser.el' (for use with MS Windows).
7204 (substitute-key-definition 'dired-w32-browser 'dired-w32-browser-reuse-dir-buffer dired-mode-map)
7205 (substitute-key-definition 'dired-mouse-w32-browser 'dired-mouse-w32-browser-reuse-dir-buffer dired-mode-map)
7206 (message "Reusing Dired buffers is now ON"))
7207
7208(defun diredp-make-find-file-keys-not-reuse-dirs ()
7209 "Make find-file keys not reuse Dired buffers (i.e. act normally)."
7210 (substitute-key-definition 'diredp-up-directory-reuse-dir-buffer 'diredp-up-directory dired-mode-map)
7211 (substitute-key-definition 'diredp-find-file-reuse-dir-buffer 'dired-find-file dired-mode-map)
7212 (substitute-key-definition 'diredp-mouse-find-file-reuse-dir-buffer 'dired-mouse-find-file dired-mode-map)
7213 ;; These commands are defined in `w32-browser.el' (for use with MS Windows).
7214 (substitute-key-definition 'dired-w32-browser-reuse-dir-buffer 'dired-w32-browser dired-mode-map)
7215 (substitute-key-definition 'dired-mouse-w32-browser-reuse-dir-buffer 'dired-mouse-w32-browser dired-mode-map)
7216 (message "Reusing Dired buffers is now OFF"))
7217
7218;;;###autoload
7219(defun diredp-omit-marked () ; Not bound
7220 "Omit lines of marked files. Return the number of lines omitted."
7221 (interactive)
7222 (let ((old-modified-p (buffer-modified-p))
7223 count)
7224 (when (interactive-p) (message "Omitting marked lines..."))
7225 (setq count (dired-do-kill-lines nil "Omitted %d line%s."))
7226 (set-buffer-modified-p old-modified-p) ; So no `%*' appear in mode-line.
7227 count))
7228
7229;;;###autoload
7230(defun diredp-omit-unmarked () ; Not bound
7231 "Omit lines of unmarked files. Return the number of lines omitted."
7232 (interactive)
7233 (let ((old-modified-p (buffer-modified-p))
7234 count)
7235 (dired-toggle-marks)
7236 (message "Omitting unmarked lines...")
7237 (setq count (diredp-omit-marked))
7238 (dired-toggle-marks) ; Marks all except `.', `..'
7239 (set-buffer-modified-p old-modified-p) ; So no `%*' appear in mode-line.
7240 count))
7241
7242;;;###autoload
7243(defun diredp-ediff (file2) ; Bound to `='
7244 "Compare file at cursor with file FILE2 using `ediff'.
7245FILE2 defaults to the file at the cursor as well. If you enter just a
7246directory name for FILE2, then the file at the cursor is compared with
7247a file of the same name in that directory. FILE2 is the second file
7248given to `ediff'; the file at the cursor is the first.
7249
7250Try to guess a useful default value for FILE2, as follows:
7251
7252* If the mark is active, use the file at mark.
7253* Else if the file at cursor is a autosave file or a backup file, use
7254 the corresponding base file.
7255* Else if there is any backup file for the file at point, use the
7256 newest backup file for it.
7257* Else use the file at point."
7258 (interactive (progn (require 'ediff)
7259 (list (ediff-read-file-name ; In `ediff-util.el'.
7260 (format "Compare %s with" (dired-get-filename t))
7261 (dired-current-directory)
7262 (let* ((file (dired-get-filename))
7263 (file-sans-dir (file-name-nondirectory file))
7264 (file-dir (file-name-directory file))
7265 (file-at-mark (and transient-mark-mode
7266 mark-active
7267 (save-excursion (goto-char (mark t))
7268 (dired-get-filename t t))))
7269 (last-backup (file-newest-backup file)))
7270 (cond
7271 (file-at-mark)
7272 ((auto-save-file-name-p file-sans-dir)
7273 (expand-file-name (substring file-sans-dir 1 -1) file-dir))
7274 ((backup-file-name-p file-sans-dir)
7275 (expand-file-name (file-name-sans-versions file-sans-dir) file-dir))
7276 (last-backup)
7277 (t file)))))))
7278 (ediff-files (dired-get-filename) file2)) ; In `ediff.el'.
7279
7280(defun diredp-fewer-than-2-files-p (arg)
7281 "Return non-nil iff fewer than two files are to be treated by dired.
7282More precisely, return non-nil iff ARG is nil and fewer than two
7283files are marked, or ARG is -1, 0 or 1."
7284 (if arg
7285 (and (integerp arg) (< (abs arg) 2)) ; Next or previous file (or none).
7286 (not (save-excursion ; Fewer than two marked files.
7287 (goto-char (point-min))
7288 (re-search-forward (dired-marker-regexp) nil t 2)))))
7289
7290;;;###autoload
7291(defun diredp-do-apply-function (function &optional arg) ; Bound to `@'
7292 "Apply FUNCTION to the marked files.
7293With a plain prefix ARG (`C-u'), visit each file and invoke FUNCTION
7294 with no arguments.
7295Otherwise, apply FUNCTION to each file name.
7296
7297Any other prefix arg behaves according to the ARG argument of
7298`dired-get-marked-files'. In particular, `C-u C-u' operates on all
7299files in the Dired buffer."
7300 (interactive (list (read (completing-read "Function: " obarray 'functionp nil nil
7301 (and (boundp 'function-name-history) 'function-name-history)))
7302 current-prefix-arg))
7303 (if (and (consp arg) (< (car arg) 16))
7304 (dolist (file (dired-get-marked-files))
7305 (with-current-buffer (find-file-noselect file) (funcall function)))
7306 (dolist (file (dired-get-marked-files nil arg)) (funcall function file))))
7307
7308
7309;; REPLACE ORIGINAL in `dired-aux.el'.
7310;;
7311;; 1. Redisplay only if at most one file is being treated.
7312;; 2. Doc string reflects `Dired+'s version of `dired-map-over-marks-check'.
7313;;
7314;;;###autoload
7315(defun dired-do-compress (&optional arg) ; Bound to `Z'
7316 "Compress or uncompress marked (or next prefix argument) files.
7317A prefix argument ARG specifies files to use instead of marked.
7318 An integer means use the next ARG files (previous -ARG, if < 0).
7319 `C-u': Use the current file (whether or not any are marked).
7320 `C-u C-u': Use all files in Dired, except directories.
7321 `C-u C-u C-u': Use all files and directories, except `.' and `..'.
7322 `C-u C-u C-u C-u': Use all files and all directories."
7323 (interactive "P")
7324 (dired-map-over-marks-check #'dired-compress arg 'compress (diredp-fewer-than-2-files-p arg)))
7325
7326
7327;; REPLACE ORIGINAL in `dired-aux.el'.
7328;;
7329;; 1. Redisplay only if at most one file is being treated.
7330;; 2. Doc string reflects `Dired+'s version of `dired-map-over-marks-check'.
7331;;
7332;;;###autoload
7333(defun dired-do-byte-compile (&optional arg) ; Bound to `B'
7334 "Byte compile marked Emacs Lisp files.
7335A prefix argument ARG specifies files to use instead of those marked.
7336 * An integer means use the next ARG files (previous -ARG, if < 0).
7337 * Two or more `C-u' (e.g. `C-u C-u') means ignore any marks and use
7338 all files in the Dired buffer.
7339 * Any other prefix arg means use the current file."
7340 (interactive (let* ((arg current-prefix-arg)
7341 (C-u (and (consp arg) arg)))
7342 (when (and C-u (> (prefix-numeric-value arg) 16)) (setq arg '(16)))
7343 (list arg)))
7344 (dired-map-over-marks-check #'dired-byte-compile arg 'byte-compile
7345 (diredp-fewer-than-2-files-p arg)))
7346
7347
7348;; REPLACE ORIGINAL in `dired-aux.el'.
7349;;
7350;; 1. Redisplay only if at most one file is being treated.
7351;; 2. Doc string reflects `Dired+' version of `dired-map-over-marks-check'.
7352;;
7353;;;###autoload
7354(defun dired-do-load (&optional arg) ; Bound to `L'
7355 "Load the marked Emacs Lisp files.
7356A prefix argument ARG specifies files to use instead of those marked.
7357 * An integer means use the next ARG files (previous -ARG, if < 0).
7358 * Two or more `C-u' (e.g. `C-u C-u') means ignore any marks and use
7359 all files in the Dired buffer.
7360 * Any other prefix arg means use the current file."
7361 (interactive (let* ((arg current-prefix-arg)
7362 (C-u (and (consp arg) arg)))
7363 (when (and C-u (> (prefix-numeric-value arg) 16)) (setq arg '(16)))
7364 (list arg)))
7365 (dired-map-over-marks-check #'dired-load arg 'load (diredp-fewer-than-2-files-p arg)))
7366
7367
7368(when (fboundp 'multi-isearch-files)
7369
7370 ;; REPLACE ORIGINAL in `dired.el':
7371 ;;
7372 ;; 1. Added optional arg ARG, so you can act on next ARG files or on all files.
7373 ;; 2. Added optional arg INTERACTIVEP.
7374 ;; 3. Do not raise error if no files when not INTERACTIVEP.
7375 ;;
7376 (defun dired-do-isearch (&optional arg interactivep)
7377 "Search for a string through all marked files using Isearch.
7378A prefix argument ARG specifies files to use instead of those marked.
7379 * An integer means use the next ARG files (previous -ARG, if < 0).
7380 * Two or more `C-u' (e.g. `C-u C-u') means ignore any marks and use
7381 all files in the Dired buffer.
7382 * Any other prefix arg means use the current file.
7383When invoked interactively, raise an error if no files are marked."
7384 (interactive (let* ((arg current-prefix-arg)
7385 (C-u (and (consp arg) arg)))
7386 (when (and C-u (> (prefix-numeric-value arg) 16)) (setq arg '(16)))
7387 (list arg t)))
7388 (multi-isearch-files (dired-get-marked-files nil arg 'dired-nondirectory-p nil interactivep)))
7389
7390
7391 ;; REPLACE ORIGINAL in `dired.el':
7392 ;;
7393 ;; 1. Added optional arg ARG, so you can act on next ARG files or on all files.
7394 ;; 2. Added optional arg INTERACTIVEP.
7395 ;; 3. Do not raise error if no files when not INTERACTIVEP.
7396 ;;
7397 (defun dired-do-isearch-regexp (&optional arg interactivep)
7398 "Search for a regexp through all marked files using Isearch.
7399A prefix arg behaves as follows:
7400 * An integer means use the next ARG files (previous -ARG, if < 0).
7401 * Two or more `C-u' (e.g. `C-u C-u') means ignore any marks and use
7402 all files in the Dired buffer.
7403 * Any other prefix arg means use the current file.
7404When invoked interactively, raise an error if no files are marked."
7405 (interactive (let* ((arg current-prefix-arg)
7406 (C-u (and (consp arg) arg)))
7407 (when (and C-u (> (prefix-numeric-value arg) 16)) (setq arg '(16)))
7408 (list arg t)))
7409 (multi-isearch-files-regexp (dired-get-marked-files nil arg 'dired-nondirectory-p nil interactivep)))
7410
7411 )
7412
7413
7414;; REPLACE ORIGINAL in `dired.el':
7415;;
7416;; 1. Added optional arg ARG, so you can act on next ARG files or on all files.
7417;; 2. Added optional arg INTERACTIVEP.
7418;; 3. Do not raise error if no files when not INTERACTIVEP.
7419;;
7420;;;###autoload
7421(defun dired-do-search (regexp &optional arg interactivep)
7422 "Search through all marked files for a match for REGEXP.
7423Stops when a match is found.
7424To continue searching for next match, use command \\[tags-loop-continue].
7425
7426A prefix arg behaves as follows:
7427 * An integer means use the next ARG files (previous -ARG, if < 0).
7428 * Two or more `C-u' (e.g. `C-u C-u') means ignore any marks and use
7429 all files in the Dired buffer.
7430 * Any other prefix arg means use the current file.
7431
7432When invoked interactively, raise an error if no files are marked."
7433 (interactive (let* ((arg current-prefix-arg)
7434 (C-u (and (consp arg) arg)))
7435 (when (and C-u (> (prefix-numeric-value arg) 16)) (setq arg '(16)))
7436 (list (diredp-read-regexp "Search marked files (regexp): ")
7437 arg
7438 t)))
7439 (tags-search regexp `(dired-get-marked-files nil ',arg 'dired-nondirectory-p nil ,interactivep)))
7440
7441
7442;; REPLACE ORIGINAL in `dired.el':
7443;;
7444;; 1. Added optional arg ARG, so you can act on next ARG files or on all files.
7445;; 2. Added optional arg INTERACTIVEP.
7446;; 3. Do not raise error if no files when not INTERACTIVEP.
7447;;
7448;;;###autoload
7449(defun dired-do-query-replace-regexp (from to &optional arg interactivep)
7450 "Do `query-replace-regexp' of FROM with TO, on all marked files.
7451NOTE: A prefix arg for this command acts differently than for other
7452commands, so that you can use it to request word-delimited matches.
7453
7454With a prefix argument:
7455 * An odd number of plain `C-u': act on the marked files, but replace
7456 only word-delimited matches.
7457 * More than one plain `C-u': act on all files, ignoring whether any
7458 are marked.
7459 * Any other prefix arg: Act on the next numeric-prefix files.
7460
7461So for example:
7462 * `C-u C-u C-u': act on all files, replacing word-delimited matches.
7463 * `C-u 4': act on the next 4 files. `C-4' means the same thing.
7464 * `C-u': act on the marked files, replacing word-delimited matches.
7465
7466When invoked interactively, raise an error if no files are marked.
7467
7468If you exit (\\[keyboard-quit], RET or q), you can resume the query replace
7469with the command \\[tags-loop-continue]."
7470 (interactive (let ((common (query-replace-read-args "Query replace regexp in marked files" t t)))
7471 (list (nth 0 common)
7472 (nth 1 common)
7473 current-prefix-arg
7474 t)))
7475 (let* ((argnum (and (consp arg) (prefix-numeric-value arg)))
7476 (delimited (and argnum (eq (logand (truncate (log argnum 4)) 1) 1))) ; Odd number of plain `C-u'.
7477 (all (and argnum (> argnum 4))) ; At least 3 plain `C-u'.
7478 (dgmf-arg (dired-get-marked-files nil
7479 (if (and arg (atom arg)) (abs arg) (and all '(16)))
7480 'dired-nondirectory-p
7481 nil
7482 interactivep)))
7483 (dolist (file dgmf-arg)
7484 (let ((buffer (get-file-buffer file)))
7485 (when (and buffer (with-current-buffer buffer buffer-read-only))
7486 (error "File `%s' is visited read-only" file))))
7487 (tags-query-replace from to delimited `',dgmf-arg)))
7488
7489;;;###autoload
7490(defun diredp-do-grep (command-args) ; Bound to `C-M-G'
7491 "Run `grep' on marked (or next prefix arg) files.
7492A prefix argument behaves according to the ARG argument of
7493`dired-get-marked-files'. In particular, `C-u C-u' operates on all
7494files in the Dired buffer."
7495 (interactive (progn (unless (if (< emacs-major-version 22)
7496 grep-command
7497 (and grep-command (or (not grep-use-null-device) (eq grep-use-null-device t))))
7498 (grep-compute-defaults))
7499 (list (diredp-do-grep-1))))
7500 (grep command-args))
7501
7502;; Optional arg FILES is no longer used. It was used in `diredp-do-grep' before the
7503;; new `dired-get-marked-files'.
7504(defun diredp-do-grep-1 (&optional files)
7505 "Helper function for `diredp-do-grep'.
7506Non-nil optional arg FILES are the files to grep, overriding the files
7507choice described for `diredp-do-grep'."
7508 (let ((default (and (fboundp 'grep-default-command)
7509 (if (fboundp 'grepp-default-regexp-fn) ; In `grep+.el'.
7510 (grep-default-command (funcall (grepp-default-regexp-fn)))
7511 (grep-default-command)))))
7512 (read-from-minibuffer
7513 "grep <pattern> <files> : "
7514 (let ((up-to-files (concat grep-command " ")))
7515 (cons (concat up-to-files
7516 (mapconcat #'identity
7517 (or files (mapcar 'shell-quote-argument
7518 (dired-get-marked-files nil current-prefix-arg)))
7519 " "))
7520 (- (length up-to-files) 2)))
7521 nil nil 'grep-history default)))
7522
7523(when (memq system-type '(windows-nt ms-dos))
7524 (define-derived-mode diredp-w32-drives-mode fundamental-mode "Drives"
7525 "Mode for Dired buffer listing MS Windows drives (local or remote)."
7526 (setq buffer-read-only t)))
7527
7528;; The next two commands were originally taken from Emacs Wiki, page WThirtyTwoBrowseNetDrives:
7529;; https://www.emacswiki.org/emacs/WThirtyTwoBrowseNetDrives. They are referred to there as
7530;; commands `show-net-connections' and `netdir'. I am hoping that the contributor (anonymous)
7531;; does not mind my adapting them and including them in `Dired+'.
7532
7533(when (memq system-type '(windows-nt ms-dos))
7534 (defun diredp-w32-list-mapped-drives () ; Not bound
7535 "List network connection information for shared MS Windows resources.
7536This just invokes the Windows `NET USE' command."
7537 (interactive)
7538 (shell-command "net use")
7539 (display-buffer "*Shell Command Output*")))
7540
7541(when (memq system-type '(windows-nt ms-dos))
7542 (defun diredp-w32-drives (&optional other-window-p) ; Bound to `:/'
7543 "Visit a list of MS Windows drives for use by Dired.
7544With a prefix argument use another window for the list.
7545In the list, use `mouse-2' or `RET' to open Dired for a given drive.
7546
7547The drives listed are the remote drives currently available, as
7548determined by the Windows command `NET USE', plus the local drives
7549specified by option `diredp-w32-local-drives', which you can
7550customize.
7551
7552Note: When you are in Dired at the root of a drive (e.g. directory
7553 `C:/'), command `diredp-up-directory' invokes this command.
7554 So you can use `\\[diredp-up-directory]' to go up to the list of drives."
7555 (interactive "P")
7556 (require 'widget)
7557 (let ((drive (copy-sequence diredp-w32-local-drives))
7558 (inhibit-read-only t))
7559 (with-temp-buffer
7560 (insert (shell-command-to-string "net use"))
7561 (goto-char (point-min))
7562 (while (re-search-forward "[A-Z]: +\\\\\\\\[^ ]+" nil t nil)
7563 (setq drive (cons (split-string (match-string 0)) drive))))
7564 (if other-window-p
7565 (pop-to-buffer "*Windows Drives*")
7566 (switch-to-buffer "*Windows Drives*"))
7567 (erase-buffer)
7568 (widget-minor-mode 1)
7569 (dolist (drv (sort drive (lambda (a b) (string-lessp (car a) (car b)))))
7570 (lexical-let ((drv drv))
7571 (widget-create 'push-button
7572 :notify (lambda (widget &rest ignore) (dired (car drv)))
7573 (concat (car drv) " " (cadr drv))))
7574 (widget-insert "\n"))
7575 (goto-char (point-min))
7576 (diredp-w32-drives-mode))))
7577
7578;; $$$$$$ NO LONGER USED. Was used in `diredp-do-grep(-1)' before new `dired-get-marked-files'.
7579(defun diredp-all-files ()
7580 "List of all files shown in current Dired buffer.
7581Directories are not included."
7582 (let ((pos (make-marker))
7583 (files ())
7584 file)
7585 (save-excursion
7586 (goto-char (point-min)) (beginning-of-line)
7587 (while (not (eobp))
7588 (beginning-of-line)
7589 (while (and (not (eobp)) (dired-between-files)) (forward-line 1))
7590 (save-excursion (forward-line 1) (move-marker pos (1+ (point))))
7591 (setq file (dired-get-filename nil t)) ; Non-nil second arg means "also . and ..".
7592 (when file ; Remove directory portion if in same directory.
7593 (setq file (dired-get-filename (dired-in-this-tree file default-directory) t)))
7594 (unless (or (not file) (file-directory-p file)) (push file files))
7595 (goto-char pos))
7596 (move-marker pos nil))
7597 (setq files (sort files (if (and (featurep 'ls-lisp)
7598 (not (symbol-value 'ls-lisp-use-insert-directory-program)))
7599 'ls-lisp-string-lessp
7600 (if case-fold-search
7601 (lambda (s1 s2) (string-lessp (upcase s1) (upcase s2)))
7602 'string-lessp))))))
7603
7604
7605;; REPLACE ORIGINAL in `dired-aux.el'.
7606;;
7607;; 1. Use `diredp-this-subdir' instead of `dired-get-filename'.
7608;; 2. If on a subdir listing header line or a non-dir file in a subdir listing, go to
7609;; the line for the subdirectory in the parent directory listing.
7610;; 3. Fit one-window frame after inserting subdir.
7611;;
7612;;;###autoload
7613(defun dired-maybe-insert-subdir (dirname &optional switches no-error-if-not-dir-p)
7614 ; Bound to `i'
7615 "Move to Dired subdirectory line or subdirectory listing.
7616This bounces you back and forth between a subdirectory line and its
7617inserted listing header line. Using it on a non-directory line in a
7618subdirectory listing acts the same as using it on the subdirectory
7619header line.
7620
7621* If on a subdirectory line, then go to the subdirectory's listing,
7622 creating it if not yet present.
7623
7624* If on a subdirectory listing header line or a non-directory file in
7625 a subdirectory listing, then go to the line for the subdirectory in
7626 the parent directory listing.
7627
7628* If on a non-directory file in the top Dired directory listing, do
7629 nothing.
7630
7631Subdirectories are listed in the same position as for `ls -lR' output.
7632
7633With a prefix arg, you can edit the `ls' switches used for this
7634listing. Add `R' to the switches to expand the directory tree under a
7635subdirectory.
7636
7637Dired remembers the switches you specify with a prefix arg, so
7638reverting the buffer does not reset them. However, you might
7639sometimes need to reset some subdirectory switches after a
7640`dired-undo'. You can reset all subdirectory switches to the
7641default value using \\<dired-mode-map>\\[dired-reset-subdir-switches]. See \
7642Info node
7643`(emacs)Subdir switches' for more details."
7644 (interactive (list (diredp-this-subdir)
7645 (and current-prefix-arg
7646 (read-string "Switches for listing: "
7647 (or (and (boundp 'dired-subdir-switches) dired-subdir-switches)
7648 dired-actual-switches)))))
7649 (let ((opoint (point))
7650 (filename dirname))
7651 (cond ((consp filename) ; Subdir header line or non-directory file.
7652 (setq filename (car filename))
7653 (if (assoc filename dired-subdir-alist)
7654 (dired-goto-file filename) ; Subdir header line.
7655 (dired-insert-subdir (substring (file-name-directory filename) 0 -1))))
7656 (t
7657 ;; We don't need a marker for opoint as the subdir is always
7658 ;; inserted *after* opoint.
7659 (setq dirname (file-name-as-directory dirname))
7660 (or (and (not switches) (dired-goto-subdir dirname))
7661 (dired-insert-subdir dirname switches no-error-if-not-dir-p))
7662 ;; Push mark so that it's easy to go back. Do this after the
7663 ;; insertion message so that the user sees the `Mark set' message.
7664 (push-mark opoint)
7665 (when (and (get-buffer-window (current-buffer)) ; Fit one-window frame.
7666 (fboundp 'fit-frame-if-one-window)) ; In `autofit-frame.el'.
7667 (fit-frame-if-one-window))))))
7668
7669(defun diredp-this-subdir ()
7670 "This line's filename, if directory, or `dired-current-directory' list.
7671If on a directory line, then return the directory name.
7672Else return a singleton list of a directory name, which is as follows:
7673 If on a subdirectory header line (either of the two lines), then use
7674 that subdirectory name. Else use the parent directory name."
7675 (or (let ((file (dired-get-filename nil t)))
7676 (and file
7677 (file-directory-p file)
7678 (not (member (file-relative-name file (file-name-directory (directory-file-name file)))
7679 '("." ".." "./" "../")))
7680 file))
7681 (list (dired-current-directory))))
7682
7683
7684;; REPLACE ORIGINAL in `dired.el'.
7685;;
7686;; No-op: does nothing now.
7687;;
7688(defun dired-insert-subdir-validate (dirname &optional switches))
7689
7690
7691;;; $$$$$$$$
7692;;; ;; REPLACE ORIGINAL in `dired-aux.el'.
7693;;; ;;
7694;;; ;; 1. Do not require that DIRNAME be in the current directory tree (no error if not).
7695;;; ;; 2. Use `dolist' instead of `mapcar'.
7696;;; ;;
7697;;; (defun dired-insert-subdir-validate (dirname &optional switches)
7698;;; "Raise an error if it is invalid to insert DIRNAME with SWITCHES."
7699;;; ;;; (or (dired-in-this-tree dirname (expand-file-name default-directory)) ; REMOVED
7700;;; ;;; (error "%s: not in this directory tree" dirname))
7701;;; (let ((real-switches (or switches (and (boundp 'dired-subdir-switches) ; Emacs 22+
7702;;; dired-subdir-switches))))
7703;;; (when real-switches
7704;;; (let (case-fold-search)
7705;;; (dolist (switchs '("F" "b")) ; Switches that matter for `dired-get-filename'.
7706;;; (unless (eq (null (diredp-string-match-p switchs real-switches))
7707;;; (null (diredp-string-match-p switchs dired-actual-switches)))
7708;;; (error "Can't have dirs with and without `-%s' switches together" switchs)))))))
7709
7710
7711;; REPLACE ORIGINAL in `dired-aux.el'.
7712;;
7713;; If NEW-DIR is not a descendent of a directory in the buffer, put it at eob.
7714;;
7715(defun dired-insert-subdir-newpos (new-dir)
7716 "Move to the proper position for inserting NEW-DIR, and return it.
7717Respect the order within each directory tree. But if NEW-DIR is not a
7718descendent of any directory in the buffer, then put it at the end."
7719 (let ((alist dired-subdir-alist)
7720 elt dir new-pos)
7721 (while alist
7722 (setq elt (car alist)
7723 alist (cdr alist)
7724 dir (car elt))
7725 (if (dired-tree-lessp dir new-dir)
7726 (setq new-pos (dired-get-subdir-max elt) ; Position NEW-DIR after DIR.
7727 alist ())
7728 (setq new-pos (point-max))))
7729 (goto-char new-pos))
7730 (unless (eobp) (forward-line -1))
7731 (insert "\n")
7732 (point))
7733
7734
7735;; This is like original `dired-hide-subdir' in `dired-aux.el', except:
7736;;
7737;; 1. Plain prefix arg means invoke `dired-hide-all'. Added optional arg NEXT.
7738;; 2. Do not move to the next subdir.
7739;; 3. Modified to work with also with older Emacs versions.
7740;;
7741(defun diredp-hide-subdir-nomove (arg &optional next)
7742 "Hide or unhide the current directory.
7743Unlike `dired-hide-subdir', this does not advance the cursor to the
7744next directory header line.
7745
7746With a plain prefix arg (`C-u'), invoke `dired-hide-all' to hide or
7747 show everything.
7748With a numeric prefix arg N, hide this subdirectory and the next N-1
7749 subdirectories."
7750 (interactive "P")
7751 (dired-hide-check)
7752 (if (consp arg)
7753 (dired-hide-all 'IGNORED) ; Arg needed for older Emacs versions.
7754 (setq arg (prefix-numeric-value arg))
7755 (let ((modflag (buffer-modified-p)))
7756 (while (>= (setq arg (1- arg)) 0)
7757 (let* ((cur-dir (dired-current-directory))
7758 (hidden-p (dired-subdir-hidden-p cur-dir))
7759 (elt (assoc cur-dir dired-subdir-alist))
7760 (end-pos (1- (dired-get-subdir-max elt)))
7761 buffer-read-only)
7762 (goto-char (dired-get-subdir-min elt)) ; Keep header line visible, hide rest
7763 (skip-chars-forward "^\n\r")
7764 (if hidden-p
7765 (subst-char-in-region (point) end-pos ?\r ?\n)
7766 (subst-char-in-region (point) end-pos ?\n ?\r)))
7767 (when next (dired-next-subdir 1 t)))
7768 (if (fboundp 'restore-buffer-modified-p)
7769 (restore-buffer-modified-p modflag)
7770 (set-buffer-modified-p modflag)))))
7771
7772;;; ----------------------
7773;;; If we instead renamed `diredp-hide-subdir-nomove' to `dired-hide-subdir' as a replacement,
7774;;; then we would define things this way:
7775;;;
7776;;;
7777;;; ;; REPLACE ORIGINAL in `dired-aux.el'.
7778;;; ;;
7779;;; ;; 1. Plain prefix arg means invoke `dired-hide-all'. Added optional arg NEXT.
7780;;; ;;
7781;;; ;; 2. Do not move to the next subdir.
7782;;; ;;
7783;;; ;; 3. Modified to work with also with older Emacs versions.
7784;;; ;;
7785;;; (defun dired-hide-subdir (arg &optional next)
7786;;; "Hide or unhide the current directory.
7787;;; Unlike `diredp-hide-subdir-goto-next', this does not advance the
7788;;; cursor to the next directory header line.
7789;;;
7790;;; With a plain prefix arg (`C-u'), invoke `dired-hide-all' to hide or
7791;;; show everything.
7792;;; With a numeric prefix arg N, hide this subdirectory and the next N-1
7793;;; subdirectories."
7794;;; (interactive "P")
7795;;; (dired-hide-check)
7796;;; (if (consp arg)
7797;;; (dired-hide-all 'IGNORED) ; Arg needed for older Emacs versions.
7798;;; (setq arg (prefix-numeric-value arg))
7799;;; (let ((modflag (buffer-modified-p)))
7800;;; (while (>= (setq arg (1- arg)) 0)
7801;;; (let* ((cur-dir (dired-current-directory))
7802;;; (hidden-p (dired-subdir-hidden-p cur-dir))
7803;;; (elt (assoc cur-dir dired-subdir-alist))
7804;;; (end-pos (1- (dired-get-subdir-max elt)))
7805;;; buffer-read-only)
7806;;; (goto-char (dired-get-subdir-min elt)) ; Keep header line visible, hide rest
7807;;; (skip-chars-forward "^\n\r")
7808;;; (if hidden-p
7809;;; (subst-char-in-region (point) end-pos ?\r ?\n)
7810;;; (subst-char-in-region (point) end-pos ?\n ?\r)))
7811;;; (when next (dired-next-subdir 1 t)))
7812;;; (if (fboundp 'restore-buffer-modified-p)
7813;;; (restore-buffer-modified-p modflag)
7814;;; (set-buffer-modified-p modflag)))))
7815;;;
7816;;; (defun diredp-hide-subdir-goto-next (arg)
7817;;; "Hide or unhide current directory and move to next directory header line."
7818;;; (interactive "P")
7819;;; (dired-hide-subdir arg 'NEXT))
7820;;; ----------------------
7821
7822
7823;; REPLACE ORIGINAL in `dired-x.el'.
7824;;
7825;; Fix the `interactive' spec. This is the Emacs 24+ version, provided for earlier versions.
7826;;
7827(unless (> emacs-major-version 23)
7828 (defun dired-mark-unmarked-files (regexp msg &optional unflag-p localp)
7829 "Mark unmarked files matching REGEXP, displaying MSG.
7830REGEXP is matched against the entire file name. When called
7831interactively, prompt for REGEXP.
7832With prefix argument, unflag all those files.
7833
7834Non-interactively:
7835 Returns t if any work was done, nil otherwise.
7836 Optional fourth argument LOCALP is as in `dired-get-filename'."
7837 (interactive (list (diredp-read-regexp "Mark unmarked files matching regexp (default all): ")
7838 nil
7839 current-prefix-arg
7840 nil))
7841 (let ((dired-marker-char (if unflag-p ?\ dired-marker-char)))
7842 (diredp-mark-if (and (diredp-looking-at-p " ") ; Not already marked
7843 (let ((fn (dired-get-filename localp 'NO-ERROR))) ; Uninteresting
7844 (and fn (diredp-string-match-p regexp fn))))
7845 msg))))
7846
7847
7848;; REPLACE ORIGINAL in `dired-x.el'.
7849;;
7850;; 1. Call `dired-get-marked-files' with original ARG, to get its multi-`C-u' behavior.
7851;; 2. Doc string updated to reflect change to `dired-simultaneous-find-file'.
7852;; 3. Added optional arg INTERACTIVEP.
7853;; 4. Do not raise error if no files when not INTERACTIVEP.
7854;;
7855;;;###autoload
7856(defun dired-do-find-marked-files (&optional arg interactivep) ; Bound to `F'
7857 "Find marked files, displaying all of them simultaneously.
7858With no prefix argument:
7859
7860* If `pop-up-frames' is nil then split the current window across all
7861 marked files, as evenly as possible. Remaining lines go to the
7862 bottom-most window. The number of files that can be displayed this
7863 way is restricted by the height of the current window and
7864 `window-min-height'.
7865
7866* If `pop-up-frames' is non-nil then show each marked file in a
7867 separate frame (not window).
7868
7869With a prefix argument:
7870
7871* One or more plain `C-u' behaves as for `dired-get-marked-files'.
7872 In particular, `C-u C-u' means ignore any markings and operate on
7873 ALL files and directories (except `.' and `..') in the Dired buffer.
7874
7875* A numeric prefix arg >= 0 means just find (visit) the marked files -
7876 do not show them.
7877
7878* A numeric prefix arg < 0 means show each marked file in a separate
7879 frame (not window). (This is the same behavior as no prefix arg
7880 with non-nil `pop-up-frames'.)
7881
7882Note that a numeric prefix argument acts differently with this command
7883than it does with other `dired-do-*' commands: it does NOT act on the
7884next or previous (abs ARG) files, ignoring markings.
7885
7886To keep the Dired buffer displayed, split the window (e.g., `C-x 2')
7887first. To show only the marked files, type `\\[delete-other-windows]' first.
7888
7889When invoked interactively, raise an error if no files are marked."
7890 (interactive "P\np")
7891 (dired-simultaneous-find-file
7892 (dired-get-marked-files nil (and (consp arg) arg) nil nil interactivep)
7893 (and arg (prefix-numeric-value arg))))
7894
7895
7896;; REPLACE ORIGINAL in `dired-x.el'.
7897;;
7898;; Use separate frames instead of windows if `pop-up-frames' is non-nil,
7899;; or if prefix arg is negative.
7900;;
7901(defun dired-simultaneous-find-file (file-list option)
7902 "Visit all files in list FILE-LIST and display them simultaneously.
7903With non-nil OPTION >= 0, the files are found (visited) but not shown.
7904
7905If `pop-up-frames' is non-nil or if OPTION < 0, use a separate frame
7906for each file. (See also option `diredp-max-frames'.)
7907
7908Otherwise, the current window is split across all files in FILE-LIST,
7909as evenly as possible. Remaining lines go to the bottom-most window.
7910The number of files that can be displayed this way is restricted by
7911the height of the current window and the value of variable
7912`window-min-height'."
7913 ;; This is not interactive because it is usually too clumsy to specify FILE-LIST interactively unless via dired.
7914 (let (size)
7915 (cond ((and option (natnump option))
7916 (while file-list (find-file-noselect (car file-list)) (pop file-list)))
7917 ((or pop-up-frames option)
7918 (let ((nb-files (length file-list)))
7919 (when (and (> nb-files diredp-max-frames)
7920 (not (y-or-n-p (format "Really show %d files in separate frames? " nb-files))))
7921 (error "OK, canceled"))
7922 (while file-list (find-file-other-frame (car file-list)) (pop file-list))))
7923 (t
7924 (setq size (/ (window-height) (length file-list)))
7925 (when (> window-min-height size) (error "Too many files to show simultaneously"))
7926 (find-file (car file-list))
7927 (pop file-list)
7928 (while file-list
7929 ;; Vertically split off a window of desired size. Upper window will have SIZE lines.
7930 ;; Select lower (larger) window. We split it again.
7931 (select-window (split-window nil size))
7932 (find-file (car file-list))
7933 (pop file-list))))))
7934
7935
7936;;;;;; REPLACE ORIGINAL in both `dired.el' and `dired-x.el':
7937;;;;;;
7938;;;;;; 1. This incorporates the `dired-x.el' change to the `dired.el'
7939;;;;;; definition. This version works with or without using dired-x.
7940;;;;;; The `dired-x.el' version respects the var `dired-find-subdir'.
7941;;;;;; When `dired-find-subdir' is non-nil, this version is the same
7942;;;;;; as the `dired-x.el' version, except that a bug is corrected:
7943;;;;;; Whenever the argument to `dired-find-buffer-nocreate' is a cons,
7944;;;;;; the call to `dired-buffers-for-dir' gave a wrong type error.
7945;;;;;; This has been avoided by not respecting `dired-find-subdir'
7946;;;;;; whenever `dired-find-buffer-nocreate' is a cons.
7947;;;;;; For the case when `dired-find-subdir' is nil, see #2, below.
7948;;;;;;
7949;;;;;; 2. Unless `dired-find-subdir' is bound and non-nil:
7950;;;;;; If both DIRNAME and `dired-directory' are conses, then only
7951;;;;;; compare their cars (directories), not their explicit file lists
7952;;;;;; too. If equal, then update `dired-directory's file list to that
7953;;;;;; of DIRNAME.
7954;;;;;;
7955;;;;;; This prevents `dired-internal-noselect' (which is currently
7956;;;;;; `dired-find-buffer-nocreate's only caller) from creating a new
7957;;;;;; buffer in this case whenever a different set of files is present
7958;;;;;; in the cdr of DIRNAME and DIRNAME represents the same buffer as
7959;;;;;; `dired-directory'.
7960;;;;;;
7961;;;;;; If only one of DIRNAME and `dired-directory' is a cons, then
7962;;;;;; this returns nil.
7963;;;;;;;###autoload
7964;;;;(defun dired-find-buffer-nocreate (dirname &optional mode)
7965;;;; (let ((atomic-dirname-p (atom dirname)))
7966;;;; (if (and (boundp 'dired-find-subdir) dired-find-subdir atomic-dirname-p)
7967;;;; ;; This is the `dired-x.el' change:
7968;;;; (let* ((cur-buf (current-buffer))
7969;;;; (buffers (nreverse (dired-buffers-for-dir dirname)))
7970;;;; (cur-buf-matches (and (memq cur-buf buffers)
7971;;;; ;; Files list (wildcards) must match, too:
7972;;;; (equal dired-directory dirname))))
7973;;;; (setq buffers (delq cur-buf buffers)) ; Avoid using same buffer---
7974;;;; (or (car (sort buffers (function dired-buffer-more-recently-used-p)))
7975;;;; (and cur-buf-matches cur-buf))) ; ---unless no other possibility.
7976;;;; ;; Comment from `dired.el':
7977;;;; ;; This differs from `dired-buffers-for-dir' in that it doesn't consider
7978;;;; ;; subdirs of `default-directory' and searches for the first match only.
7979;;;; (let ((blist dired-buffers) ; was (buffer-list)
7980;;;; found)
7981;;;; (or mode (setq mode 'dired-mode))
7982;;;; (while blist
7983;;;; (if (null (buffer-name (cdr (car blist))))
7984;;;; (setq blist (cdr blist))
7985;;;; (save-excursion
7986;;;; (set-buffer (cdr (car blist)))
7987;;;; (if (not (and (eq major-mode mode)
7988;;;; ;; DIRNAME and `dired-directory' have the same dir,
7989;;;; ;; and if either of them has an explicit file list,
7990;;;; ;; then both of them do. In that case, update
7991;;;; ;; `dired-directory's file list from DIRNAME.
7992;;;; (if atomic-dirname-p
7993;;;; (and (atom dired-directory) ; Both are atoms.
7994;;;; (string= (file-truename dirname)
7995;;;; (file-truename dired-directory)))
7996;;;; (and (consp dired-directory) ; Both are conses.
7997;;;; (string=
7998;;;; (file-truename (car dirname))
7999;;;; (file-truename (car dired-directory)))
8000;;;; ;; Update `dired-directory's file list.
8001;;;; (setq dired-directory dirname)))))
8002;;;; (setq blist (cdr blist))
8003;;;; (setq found (cdr (car blist)))
8004;;;; (setq blist nil)))))
8005;;;; found))))
8006
8007
8008;; REPLACE ORIGINAL in `dired-x.el'.
8009;;
8010;; Require confirmation. Fixes Emacs bug #13561.
8011;;
8012(defun dired-do-run-mail ()
8013 "If `dired-bind-vm' is non-nil, call `dired-vm', else call `dired-rmail'."
8014 (interactive)
8015 (unless (y-or-n-p "Read all marked mail folders? ") (error "OK, canceled"))
8016 (if dired-bind-vm
8017 ;; Read mail folder using vm.
8018 (dired-vm)
8019 ;; Read mail folder using rmail.
8020 (dired-rmail)))
8021
8022
8023;; REPLACE ORIGINAL in `dired.el'.
8024;;
8025;; 1. Put `mouse-face' on whole line, not just file name.
8026;; 2. Add text property `dired-filename' to only the file name.
8027;; 3. Show image-file preview on mouseover, if `tooltip-mode'
8028;; and if `diredp-image-preview-in-tooltip'.
8029;;
8030(defun dired-insert-set-properties (beg end)
8031 "Add various text properties to the lines in the region.
8032Highlight entire line upon mouseover.
8033Add text property `dired-filename' to the file name.
8034Handle `dired-hide-details-mode' invisibility spec (Emacs 24.4+)."
8035 (let ((inhibit-field-text-motion t)) ; Just in case.
8036 (save-excursion
8037 (goto-char beg)
8038 (while (< (point) end)
8039 (condition-case nil
8040 (cond ((dired-move-to-filename)
8041 (add-text-properties (line-beginning-position) (line-end-position)
8042 '(mouse-face highlight help-echo diredp-mouseover-help))
8043 (put-text-property
8044 (point) (save-excursion (dired-move-to-end-of-filename) (point))
8045 'dired-filename t)
8046 (when (fboundp 'dired-hide-details-mode) ; Emacs 24.4+
8047 (put-text-property (+ (line-beginning-position) 1) (1- (point))
8048 'invisible 'dired-hide-details-detail)
8049 (dired-move-to-end-of-filename)
8050 (when (< (+ (point) 4) (line-end-position))
8051 (put-text-property (+ (point) 4) (line-end-position)
8052 'invisible 'dired-hide-details-link))))
8053 ((fboundp 'dired-hide-details-mode) ; Emacs 24.4+
8054 (unless (or (diredp-looking-at-p "^$") (diredp-looking-at-p dired-subdir-regexp))
8055 (put-text-property (line-beginning-position) (1+ (line-end-position))
8056 'invisible 'dired-hide-details-information))))
8057 (error nil))
8058 (forward-line 1)))))
8059
8060(defun diredp-mouseover-help (window buffer pos)
8061 "Show `help-echo' help for a file name, in Dired.
8062If `tooltip-mode' is on and `diredp-image-preview-in-tooltip' says to
8063show an image preview, then do so. Otherwise, show text help."
8064 (let ((image-dired-thumb-width (or (and (wholenump diredp-image-preview-in-tooltip)
8065 diredp-image-preview-in-tooltip)
8066 image-dired-thumb-width))
8067 (image-dired-thumb-height (or (and (wholenump diredp-image-preview-in-tooltip)
8068 diredp-image-preview-in-tooltip)
8069 image-dired-thumb-height))
8070 file)
8071 (or (and (boundp 'tooltip-mode) tooltip-mode
8072 (fboundp 'image-file-name-regexp) ; Emacs 22+, `image-file.el'.
8073 diredp-image-preview-in-tooltip
8074 (condition-case nil
8075 (and (with-current-buffer buffer
8076 (save-excursion (goto-char pos)
8077 (diredp-string-match-p
8078 (image-file-name-regexp)
8079 (setq file (if (derived-mode-p 'dired-mode)
8080 (dired-get-filename nil 'NO-ERROR)
8081 ;; Make it work also for `diredp-list-files' listings.
8082 (buffer-substring-no-properties (line-beginning-position)
8083 (line-end-position)))))))
8084 (or (not diredp-auto-focus-frame-for-thumbnail-tooltip-flag)
8085 (progn (select-frame-set-input-focus (window-frame window)) t))
8086 (let ((img-file (if (eq 'full diredp-image-preview-in-tooltip)
8087 file
8088 (diredp-image-dired-create-thumb file))))
8089 (propertize " " 'display (create-image img-file))))
8090 (error nil)))
8091 (if (fboundp 'describe-file) ; Library `help-fns+.el'
8092 "mouse-2: visit in another window, C-h RET: describe"
8093 "mouse-2: visit this file/dir in another window"))))
8094
8095;; `dired-hide-details-mode' enhancements.
8096(when (fboundp 'dired-hide-details-mode) ; Emacs 24.4+
8097
8098 (defun diredp-hide-details-if-dired ()
8099 "In Dired mode hide details. Outside Dired, do nothing."
8100 (when (derived-mode-p 'dired-mode) (dired-hide-details-mode 1)))
8101
8102 ;; Use `eval' of list so file byte-compiled in Emacs 20 will be OK in later versions.
8103 (eval '(define-globalized-minor-mode global-dired-hide-details-mode
8104 dired-hide-details-mode diredp-hide-details-if-dired))
8105
8106 (eval '(define-minor-mode dired-hide-details-mode
8107 "Hide details in Dired mode."
8108 (and diredp-hide-details-propagate-flag diredp-hide-details-last-state)
8109 :group 'dired
8110 (unless (derived-mode-p 'dired-mode) (error "Not a Dired buffer"))
8111 (dired-hide-details-update-invisibility-spec)
8112 (setq diredp-hide-details-toggled t)
8113 (when diredp-hide-details-propagate-flag
8114 (setq diredp-hide-details-last-state dired-hide-details-mode))
8115 (if dired-hide-details-mode
8116 (add-hook 'wdired-mode-hook 'dired-hide-details-update-invisibility-spec nil t)
8117 (remove-hook 'wdired-mode-hook 'dired-hide-details-update-invisibility-spec t))))
8118
8119 (defun diredp-hide/show-details ()
8120 "Hide/show details according to user options.
8121If `diredp-hide-details-propagate-flag' is non-nil and details have
8122never been hidden in the buffer, then hide/show according to your last
8123hide/show choice in any other Dired buffer or, if no last choice,
8124according to option `diredp-hide-details-initially-flag'."
8125 (unless (or diredp-hide-details-toggled ; No op if hide/show already set.
8126 (buffer-narrowed-p)) ; No-op when showing just newly copied file etc.
8127 (cond (diredp-hide-details-propagate-flag
8128 (dired-hide-details-mode (if diredp-hide-details-last-state 1 -1)))
8129 (diredp-hide-details-initially-flag
8130 (dired-hide-details-mode 1)))))
8131
8132 (add-hook 'dired-after-readin-hook #'diredp-hide/show-details)
8133
8134 (defun diredp-fit-frame-unless-buffer-narrowed ()
8135 "Fit frame unless Dired buffer is narrowed.
8136Requires library `autofit-frame.el'."
8137 (when (and (get-buffer-window (current-buffer)) (not (buffer-narrowed-p)))
8138 (fit-frame-if-one-window)))
8139
8140 ;; Fit frame only if not narrowed. Put it on this hook because `dired-hide-details-mode' is
8141 ;; invoked from `dired-after-readin-hook' via `diredp-hide/show-details', even for an update
8142 ;; such as copying a file, where buffer is narrowed when invoked.
8143 (when (fboundp 'fit-frame-if-one-window) ; In `autofit-frame.el'.
8144 (add-hook 'dired-hide-details-mode-hook #'diredp-fit-frame-unless-buffer-narrowed)))
8145
8146
8147;; REPLACE ORIGINAL in `dired.el'.
8148;;
8149;; Reset `mode-line-process' to nil.
8150;;
8151(when (< emacs-major-version 21)
8152 (or (fboundp 'old-dired-revert) (fset 'old-dired-revert (symbol-function 'dired-revert)))
8153 (defun dired-revert (&optional arg noconfirm)
8154 (setq mode-line-process nil) ; Set by, e.g., `find-dired'.
8155 (old-dired-revert arg noconfirm)))
8156
8157;; Like `dired-up-directory', but go up to MS Windows drive if in top-level directory.
8158;;
8159;;;###autoload
8160(defun diredp-up-directory (&optional other-window) ; Bound to `^'
8161 "Run Dired on parent directory of current directory.
8162Find the parent directory either in this buffer or another buffer.
8163Creates a buffer if necessary.
8164
8165With a prefix arg, Dired the parent directory in another window.
8166
8167On MS Windows, if you are already at the root directory, invoke
8168`diredp-w32-drives' to visit a navigable list of Windows drives."
8169 (interactive "P")
8170 (let* ((dir (dired-current-directory))
8171 (up (file-name-directory (directory-file-name dir))))
8172 (or (dired-goto-file (directory-file-name dir))
8173 ;; Only try `dired-goto-subdir' if buffer has more than one dir.
8174 (and (cdr dired-subdir-alist) (dired-goto-subdir up))
8175 (progn (if other-window (dired-other-window up) (dired up))
8176 (dired-goto-file dir))
8177 (and (memq system-type '(windows-nt ms-dos)) (diredp-w32-drives other-window)))))
8178
8179;;;###autoload
8180(defun diredp-up-directory-reuse-dir-buffer (&optional other-window) ; Not bound
8181 "Like `diredp-up-directory', but reuse Dired buffers.
8182With a prefix arg, Dired the parent directory in another window.
8183
8184On MS Windows, moving up from a root Dired buffer does not kill that
8185buffer (the Windows drives buffer is not really a Dired buffer)."
8186 (interactive "P")
8187 (let* ((dir (dired-current-directory))
8188 (dirfile (directory-file-name dir))
8189 (up (file-name-directory dirfile)))
8190 (or (dired-goto-file dirfile)
8191 ;; Only try `dired-goto-subdir' if buffer has more than one dir.
8192 (and (cdr dired-subdir-alist) (dired-goto-subdir up)) ; It is a subdir inserted in current Dired.
8193 (progn (diredp--reuse-dir-buffer-helper up nil nil other-window)
8194 (dired-goto-file dir))
8195 (and (memq system-type '(windows-nt ms-dos)) (diredp-w32-drives other-window)))))
8196
8197;; Differs from `dired-next-line' in both wraparound and respect of `goal-column'.
8198;;
8199;;;###autoload
8200(defun diredp-next-line (arg) ; Bound to `SPC', `n', `C-n', `down'
8201 "Move down lines then position cursor at filename.
8202If `goal-column' is non-nil then put the cursor at that column.
8203Optional prefix ARG says how many lines to move; default is one line.
8204
8205If `diredp-wrap-around-flag' is non-nil then wrap around if none is
8206found before the buffer end (buffer beginning, if ARG is negative).
8207Otherwise, just move to the buffer limit."
8208 (interactive (let ((narg (prefix-numeric-value current-prefix-arg)))
8209 (when (and (boundp 'shift-select-mode) shift-select-mode) (handle-shift-selection)) ; Emacs 23+
8210 (list narg))) ; Equivalent to "^p"
8211 (let* ((line-move-visual nil)
8212 ;; (goal-column nil)
8213
8214 ;; Use `condition-case' and `(progn... t)' because Emacs < 22 `line-move' has no
8215 ;; NO-ERROR arg and it always returns nil.
8216 (no-more (or (not (condition-case nil (progn (line-move arg) t) (error nil)))
8217 (if (< arg 0) (bobp) (eobp)))))
8218 (when (and diredp-wrap-around-flag no-more)
8219 (let ((diredp-wrap-around-flag nil))
8220 (goto-char (if (< arg 0) (point-max) (point-min)))
8221 (diredp-next-line arg)))
8222 ;; We never want to move point into an invisible line.
8223 (while (and (fboundp 'invisible-p) ; Emacs 22+
8224 (invisible-p (point))
8225 (not (if (and arg (< arg 0)) (bobp) (eobp))))
8226 (forward-char (if (and arg (< arg 0)) -1 1)))
8227 (unless goal-column (dired-move-to-filename))))
8228
8229;; In Emacs < 22, `C-p' does not wrap around, because it never moves to the first header line.
8230;;;###autoload
8231(defun diredp-previous-line (arg) ; Bound to `p', `C-p', `up'
8232 "Move up lines then position cursor at filename.
8233If `goal-column' is non-nil then put the cursor at that column.
8234Optional prefix ARG says how many lines to move; default is one line.
8235
8236If `diredp-wrap-around-flag' is non-nil then wrap around if none is
8237found before the buffer beginning (buffer end, if ARG is negative).
8238Otherwise, just move to the buffer limit."
8239 (interactive (let ((narg (prefix-numeric-value current-prefix-arg)))
8240 (when (and (boundp 'shift-select-mode) shift-select-mode) (handle-shift-selection)) ; Emacs 23+
8241 (list narg))) ; Equivalent to "^p"
8242 (diredp-next-line (- (or arg 1))))
8243
8244;;;###autoload
8245(defun diredp-next-dirline (arg &optional opoint) ; Bound to `>'
8246 "Goto ARGth next directory file line.
8247If `diredp-wrap-around-flag' is non-nil then wrap around if none is
8248found before the buffer beginning (buffer end, if ARG is negative).
8249Otherwise, raise an error or, if NO-ERROR-IF-NOT-FOUND is nil, return
8250nil."
8251 (interactive (let ((narg (prefix-numeric-value current-prefix-arg)))
8252 (when (and (boundp 'shift-select-mode) shift-select-mode) (handle-shift-selection)) ; Emacs 23+
8253 (list narg))) ; Equivalent to "^p"
8254 (or opoint (setq opoint (point)))
8255 (if (if (> arg 0)
8256 (re-search-forward dired-re-dir nil t arg)
8257 (beginning-of-line)
8258 (re-search-backward dired-re-dir nil t (- arg)))
8259 (dired-move-to-filename) ; user may type `i' or `f'
8260 (if diredp-wrap-around-flag
8261 (let ((diredp-wrap-around-flag nil))
8262 (goto-char (if (< arg 0) (point-max) (point-min)))
8263 (diredp-next-dirline arg opoint))
8264 (goto-char opoint)
8265 (error "No more subdirectories"))))
8266
8267;;;###autoload
8268(defun diredp-prev-dirline (arg) ; Bound to `<'
8269 "Goto ARGth previous directory file line."
8270 (interactive (let ((narg (prefix-numeric-value current-prefix-arg)))
8271 (when (and (boundp 'shift-select-mode) shift-select-mode) (handle-shift-selection)) ; Emacs 23+
8272 (list narg))) ; Equivalent to "^p"
8273 (diredp-next-dirline (- arg)))
8274
8275;;;###autoload
8276(defun diredp-next-subdir (arg &optional no-error-if-not-found no-skip) ; Bound to `C-M-n'
8277 "Go to the next subdirectory, regardless of level.
8278If ARG = 0 then go to this directory's header line.
8279
8280If `diredp-wrap-around-flag' is non-nil then wrap around if none is
8281found before the buffer end (buffer beginning, if ARG is negative).
8282Otherwise, raise an error or, if NO-ERROR-IF-NOT-FOUND is nil, return
8283nil.
8284
8285Non-nil NO-SKIP means do not move to end of header line, and return
8286the position moved to so far."
8287 (interactive (let ((narg (prefix-numeric-value current-prefix-arg)))
8288 (when (and (boundp 'shift-select-mode) shift-select-mode) (handle-shift-selection)) ; Emacs 23+
8289 (list narg))) ; Equivalent to "^p"
8290 (let ((this-dir (dired-current-directory))
8291 pos index)
8292 ;; `nth' with negative arg does not return nil but the first element
8293 (setq index (if diredp-wrap-around-flag
8294 (mod (- (dired-subdir-index this-dir) arg) (length dired-subdir-alist))
8295 (- (dired-subdir-index this-dir) arg))
8296 pos (and (>= index 0) (dired-get-subdir-min (nth index dired-subdir-alist))))
8297 (if pos
8298 (progn (goto-char pos)
8299 (or no-skip (skip-chars-forward "^\n\r"))
8300 (point))
8301 (if no-error-if-not-found
8302 nil ; Return nil if not found
8303 (error "%s directory" (if (> arg 0) "Last" "First"))))))
8304
8305;;;###autoload
8306(defun diredp-prev-subdir (arg &optional no-error-if-not-found no-skip) ; Bound to `C-M-p'
8307 "Go to the previous subdirectory, regardless of level.
8308When called interactively and not on a subdir line, go to this subdir's line.
8309Otherwise, this is a mirror image of `diredp-next-subdir'."
8310 ;;(interactive "^p")
8311 (interactive
8312 (list (if current-prefix-arg
8313 (let ((narg (prefix-numeric-value current-prefix-arg)))
8314 (when (and (boundp 'shift-select-mode) shift-select-mode) (handle-shift-selection)) ; Emacs 23+
8315 narg) ; Equivalent to "^p"
8316 ;; If on subdir start already then do not stay there.
8317 (if (dired-get-subdir) 1 0))))
8318 (diredp-next-subdir (- arg) no-error-if-not-found no-skip))
8319
8320
8321;; REPLACE ORIGINAL in `dired.el'.
8322;;
8323;; 1. Test also ./ and ../, in addition to . and .., for error "Cannot operate on `.' or `..'".
8324;; 2. Hack for Emacs 20-22, to expand `~/...'.
8325;;
8326(defun dired-get-filename (&optional localp no-error-if-not-filep)
8327 "In Dired, return name of file mentioned on this line.
8328Value returned normally includes the directory name.
8329
8330Optional arg LOCALP:
8331 `no-dir' means do not include directory name in result.
8332 `verbatim' means return the name exactly as it occurs in the buffer.
8333 Any other non-nil value means construct the name relative to
8334 `default-directory', which still might contain slashes if point is
8335 in a subdirectory.
8336
8337Non-nil optional arg NO-ERROR-IF-NOT-FILEP means treat `.' and `..' as
8338regular filenames and return nil if there is no filename on this line.
8339Otherwise, an error occurs in these cases."
8340 (let ((case-fold-search nil)
8341 (already-absolute nil)
8342 file p1 p2)
8343 (save-excursion (when (setq p1 (dired-move-to-filename (not no-error-if-not-filep)))
8344 (setq p2 (dired-move-to-end-of-filename no-error-if-not-filep))))
8345 ;; nil if no file on this line but `no-error-if-not-filep' is t:
8346 (when (setq file (and p1 p2 (buffer-substring p1 p2)))
8347 ;; Get rid of the mouse-face property that file names have.
8348 (set-text-properties 0 (length file) nil file)
8349
8350 ;; Unquote names quoted by `ls' or by `dired-insert-directory'.
8351 ;; Prior to Emacs 23.3, this code was written using `read' (see commented code below),
8352 ;; because that is faster than substituting \007 (4 chars) -> ^G (1 char) etc. in a loop.
8353 ;; Unfortunately, that implementation required hacks such as dealing with filenames
8354 ;; with quotation marks in their names.
8355 (while (string-match (if (> emacs-major-version 21)
8356 "\\(?:[^\\]\\|\\`\\)\\(\"\\)" ; Shy group: Emacs 22+.
8357 "\\([^\\]\\|\\`\\)\\(\"\\)")
8358 file)
8359 (setq file (replace-match "\\\"" nil t file 1)))
8360
8361 ;; $$$ This was the code for that unquoting prior to Emacs 23.3:
8362 ;; (setq file (read (concat "\"" ; Some `ls -b' do not escape quotes. But GNU `ls' is OK.
8363 ;; (or (dired-string-replace-match
8364 ;; "\\([^\\]\\|\\`\\)\"" file "\\1\\\\\"" nil t)
8365 ;; file)
8366 ;; "\"")))
8367
8368 ;; This sexp was added by Emacs 24, to fix bug #10469:
8369 ;; Unescape any spaces escaped by `ls -b'.
8370 ;; Other `-b' quotes, such as \t and \n, work transparently.
8371 (when (dired-switches-escape-p dired-actual-switches)
8372 (let ((start 0)
8373 (rep "")
8374 (shift -1))
8375 (when (eq localp 'verbatim) (setq rep "\\\\"
8376 shift +1))
8377 (while (string-match "\\(\\\\\\) " file start)
8378 (setq file (replace-match rep nil t file 1)
8379 start (+ shift (match-end 0))))))
8380
8381 ;; $$$ This sexp was added by Emacs 23.3.
8382 (when (memq system-type '(windows-nt ms-dos))
8383 (save-match-data
8384 (let ((start 0))
8385 (while (string-match "\\\\" file start)
8386 (aset file (match-beginning 0) ?/)
8387 (setq start (match-end 0))))))
8388
8389 ;; $$$ This sexp was added by Emacs 23.3.
8390 ;; Hence we don't need to worry about converting `\\' back to `\'.
8391 (setq file (read (concat "\"" file "\"")))
8392
8393 ;; Above `read' returns a unibyte string if FILE contains eight-bit-control/graphic chars.
8394 (when (and (fboundp 'string-to-multibyte) ; Emacs 22
8395 enable-multibyte-characters
8396 (not (multibyte-string-p file)))
8397 (setq file (string-to-multibyte file))))
8398 (and file
8399 (file-name-absolute-p file)
8400 ;; A relative file name can start with ~. Do not treat it as absolute in this context.
8401 (not (eq (aref file 0) ?~))
8402 (setq already-absolute t))
8403 (cond ((null file) nil)
8404 ((eq localp 'verbatim) file)
8405 ;; This is the essential `Dired+' change: Added ./ and ../, not just . and ..
8406 ((and (not no-error-if-not-filep) (member file '("." ".." "./" "../")))
8407 (error "Cannot operate on `.' or `..'"))
8408 ((and (eq localp 'no-dir) already-absolute)
8409 (file-name-nondirectory file))
8410 (already-absolute
8411 (let ((handler (find-file-name-handler file nil)))
8412 ;; check for safe-magic property so that we won't
8413 ;; put /: for names that don't really need them.
8414 ;; For instance, .gz files when auto-compression-mode is on.
8415 (if (and handler (not (get handler 'safe-magic)))
8416 (concat "/:" file)
8417 file)))
8418 ((eq localp 'no-dir) file)
8419 ((equal (dired-current-directory) "/")
8420 (setq file (concat (dired-current-directory localp) file))
8421 (let ((handler (find-file-name-handler file nil)))
8422 ;; check for safe-magic property so that we won't
8423 ;; put /: for names that don't really need them.
8424 ;; For instance, .gz files when auto-compression-mode is on.
8425 (if (and handler (not (get handler 'safe-magic)))
8426 (concat "/:" file)
8427 file)))
8428 ;; Ugly hack for Emacs < 23, for which `ls-lisp-insert-directory' can insert a subdir
8429 ;; using `~/...'. Expand `~/' for return value.
8430 ((and (< emacs-major-version 23) file (file-name-absolute-p file)
8431 (eq (aref file 0) ?~))
8432 (expand-file-name file))
8433 (t
8434 (concat (dired-current-directory localp) file)))))
8435
8436
8437;; REPLACE ORIGINAL in `dired.el'.
8438;;
8439;; 1. Fixes Emacs bug #7126: Did not work with arbitrary file list (cons arg to `dired').
8440;; 2. Remove `/' from directory name before comparing with BASE.
8441;;
8442(when (< emacs-major-version 24)
8443 (defun dired-goto-file (file) ; Bound to `j'
8444 "Go to line describing file FILE in this Dired buffer.
8445FILE must be an absolute file name.
8446Return buffer position on success, else nil."
8447 ;; Loses if FILE contains control chars like "\007" for which `ls' inserts "?" or "\\007"
8448 ;; into the buffer, so we won't find it in the buffer.
8449 (interactive (prog1 ; Let push-mark display its message
8450 (list (expand-file-name (read-file-name "Goto file: " (dired-current-directory))))
8451 (push-mark)))
8452 (unless (file-name-absolute-p file) (error "File name `%s' is not absolute" file))
8453 (setq file (directory-file-name file)) ; does no harm if no directory
8454 (let* ((case-fold-search nil)
8455 (dir (file-name-directory file))
8456 (found nil))
8457 ;; `Dired+': Added this sexp.
8458 (save-excursion
8459 (goto-char (point-min))
8460 (let ((search-string (replace-regexp-in-string "\^m" "\\^m" file nil t))
8461 (here nil))
8462 (setq search-string (replace-regexp-in-string "\\\\" "\\\\" search-string nil t))
8463
8464 ;; Escape whitespace. Added per Emacs 24 addition in `unless' code below:
8465 (when (and (dired-switches-escape-p dired-actual-switches)
8466 (diredp-string-match-p "[ \t\n]" search-string))
8467 ;; FIXME: fix this for all possible file names (embedded control chars etc).
8468 ;; Need to escape everything that `ls -b' escapes.
8469 (setq search-string (replace-regexp-in-string " " "\\ " search-string nil t)
8470 search-string (replace-regexp-in-string "\t" "\\t" search-string nil t)
8471 search-string (replace-regexp-in-string "\n" "\\n" search-string nil t)))
8472
8473 ;; Use HERE to ensure we do not keep searching for a directory entry.
8474 (while (and (not (eobp)) (not found) (not (equal here (point))))
8475 (setq here (point))
8476 (if (search-forward (concat " " search-string) nil 'NO-ERROR)
8477 ;; Must move to filename since an (actually correct) match could have been
8478 ;; elsewhere on the line (e.g. "-" would match somewhere in permission bits).
8479 (setq found (dired-move-to-filename))
8480 ;; If this isn't the right line, move forward to avoid trying this line again.
8481 (forward-line 1)))))
8482
8483 (unless found
8484 (save-excursion
8485 ;; The difficulty here is to get the result of `dired-goto-subdir' without really
8486 ;; calling it, if we don't have any subdirs.
8487 (when (if (string= dir (expand-file-name default-directory))
8488 (goto-char (point-min))
8489 (and (cdr dired-subdir-alist) (dired-goto-subdir dir)))
8490 (let ((base (file-name-nondirectory file))
8491 (boundary (dired-subdir-max))
8492 search-string)
8493 (setq search-string (replace-regexp-in-string "\^m" "\\^m" base nil t)
8494 search-string (replace-regexp-in-string "\\\\" "\\\\" search-string nil t))
8495
8496 ;; Escape whitespace. Sexp added by Emacs 24:
8497 (when (and (dired-switches-escape-p dired-actual-switches)
8498 (diredp-string-match-p "[ \t\n]" search-string))
8499 ;; FIXME: fix this for all possible file names (embedded control chars etc).
8500 ;; Need to escape everything that `ls -b' escapes.
8501 (setq search-string (replace-regexp-in-string " " "\\ " search-string nil t)
8502 search-string (replace-regexp-in-string "\t" "\\t" search-string nil t)
8503 search-string (replace-regexp-in-string "\n" "\\n" search-string nil t)))
8504 (while (and (not found)
8505 ;; Filenames are preceded by SPC. This makes the search faster
8506 ;; (e.g. for the filename "-"!).
8507 (search-forward (concat " " search-string) boundary 'move))
8508 ;; `Dired+': Remove `/' from filename, then compare with BASE.
8509 ;; Match could have BASE just as initial substring or
8510 ;; or in permission bits or date or not be a proper filename at all.
8511 (if (and (dired-get-filename 'no-dir t)
8512 (equal base (directory-file-name (dired-get-filename 'no-dir t))))
8513 ;; Must move to filename since an (actually correct) match could have been
8514 ;; elsewhere on the line (e.g. "-" would match somewhere in permission bits).
8515 (setq found (dired-move-to-filename))
8516 ;; If this is not the right line, move forward to avoid trying this line again.
8517 (forward-line 1)))))))
8518 (and found (goto-char found))))) ; Return buffer position, or nil if not found.
8519
8520
8521;; REPLACE ORIGINAL in `dired.el'.
8522;;
8523;; If destination is in a hidden dir listing, open that listing and move to destination in it.
8524;;
8525(unless (< emacs-major-version 24)
8526 (defun dired-goto-file (file)
8527 "Go to line describing file FILE in this Dired buffer.
8528FILE must be an absolute file name.
8529Return buffer position on success, else nil."
8530 ;; Loses if FILE contains control chars like "\007" for which `ls' inserts "?" or "\\007"
8531 ;; into the buffer, so we won't find it in the buffer.
8532 (interactive (prog1 (list (expand-file-name (read-file-name "Goto file: " (dired-current-directory))))
8533 (push-mark))) ; Let push-mark display its message.
8534 (unless (file-name-absolute-p file) (error "File name `%s' is not absolute" file))
8535 (setq file (directory-file-name file)) ; Does no harm if not a directory
8536 (let* ((case-fold-search nil)
8537 (dir (file-name-directory file))
8538 (found
8539 (or
8540 ;; First, look for a listing under the absolute name.
8541 (save-excursion (goto-char (point-min)) (dired-goto-file-1 file file (point-max)))
8542 ;; Else look for it as a relative name. The difficulty is to get the result
8543 ;; of `dired-goto-subdir' without calling it, if we don't have any subdirs.
8544 (save-excursion
8545 (when (if (string= dir (expand-file-name default-directory))
8546 (goto-char (point-min))
8547 (and (cdr dired-subdir-alist) (dired-goto-subdir dir)))
8548 (when (dired-subdir-hidden-p (dired-current-directory))
8549 (diredp-hide-subdir-nomove 1)) ; Open hidden parent directory.
8550 (dired-goto-file-1 (file-name-nondirectory file) file (dired-subdir-max)))))))
8551 (and found (goto-char found))))) ; Return buffer position, or nil if not found.
8552
8553
8554;; REPLACE ORIGINAL in `dired.el':
8555;;
8556;; 1. Display a message to warn that flagged, not marked, files will be deleted.
8557;; 2. Use `diredp-internal-do-deletions', so it works with all Emacs versions.
8558;;
8559;;;###autoload
8560(defun dired-do-flagged-delete (&optional no-msg) ; Bound to `x'
8561 "In Dired, delete the files flagged for deletion.
8562NOTE: This deletes flagged, not marked, files.
8563If arg NO-MSG is non-nil, no message is displayed.
8564
8565User option `dired-recursive-deletes' controls whether deletion of
8566non-empty directories is allowed."
8567 (interactive)
8568 (unless no-msg
8569 (ding)
8570 (message "NOTE: Deletion of files flagged `%c' (not those marked `%c')"
8571 dired-del-marker dired-marker-char)
8572 ;; Too slow/annoying, but without it the message is never seen: (sit-for 2)
8573 )
8574 (let* ((dired-marker-char dired-del-marker)
8575 (regexp (dired-marker-regexp))
8576 (case-fold-search nil))
8577 (if (save-excursion (goto-char (point-min)) (re-search-forward regexp nil t))
8578 (diredp-internal-do-deletions
8579 ;; This cannot move point since last arg is nil.
8580 (dired-map-over-marks (cons (dired-get-filename) (point)) nil)
8581 nil
8582 'USE-TRASH-CAN) ; This arg is for Emacs 24+ only.
8583 (unless no-msg (message "(No deletions requested.)")))))
8584
8585
8586;; REPLACE ORIGINAL in `dired.el':
8587;;
8588;; 1. Display a message to warn that marked, not flagged, files will be deleted.
8589;; 2. Use `diredp-internal-do-deletions', so it works with all Emacs versions.
8590;;
8591;;;###autoload
8592(defun dired-do-delete (&optional arg) ; Bound to `D'
8593 "Delete all marked (or next ARG) files.
8594NOTE: This deletes marked, not flagged, files.
8595`dired-recursive-deletes' controls whether deletion of
8596non-empty directories is allowed."
8597 (interactive "P")
8598 ;; This is more consistent with the file-marking feature than
8599 ;; `dired-do-flagged-delete'. But it can be confusing to the user,
8600 ;; especially since this is usually bound to `D', which is also the
8601 ;; `dired-del-marker'. So offer this warning message:
8602 (unless arg
8603 (ding)
8604 (message "NOTE: Deletion of files marked `%c' (not those flagged `%c')."
8605 dired-marker-char dired-del-marker))
8606 (diredp-internal-do-deletions
8607 ;; This can move point if ARG is an integer.
8608 (dired-map-over-marks (cons (dired-get-filename) (point)) arg)
8609 arg
8610 'USE-TRASH-CAN)) ; This arg is for Emacs 24+ only.
8611
8612(defun diredp-internal-do-deletions (file-alist arg &optional trash)
8613 "`dired-internal-do-deletions', but for any Emacs version.
8614FILE-ALIST is an alist of files to delete, with their buffer positions.
8615ARG is the prefix arg. Filenames are absolute.
8616Non-nil TRASH means use the trash can."
8617 ;; \(car FILE-ALIST) *must* be the *last* (bottommost) file in the dired
8618 ;; buffer. That way as changes are made in the buffer they do not shift
8619 ;; the lines still to be changed, so the (point) values in FILE-ALIST
8620 ;; stay valid. Also, for subdirs in natural order, a subdir's files are
8621 ;; deleted before the subdir itself - the other way around would not work."
8622 (setq file-alist (delq nil file-alist)) ; nils could come from `dired-map-over-marks'.
8623 (if (> emacs-major-version 23)
8624 (dired-internal-do-deletions file-alist arg trash)
8625 (dired-internal-do-deletions file-alist arg)))
8626
8627
8628;; REPLACE ORIGINAL in `dired.el':
8629;;
8630;; Put window point at bob. Fixes bug #12281.
8631;;
8632(when (and (> emacs-major-version 22) (or (< emacs-major-version 24)
8633 (and (= emacs-major-version 24) (= emacs-minor-version 1))))
8634 (defun dired-pop-to-buffer (buf)
8635 "Pop up buffer BUF in a way suitable for Dired."
8636 (let ((split-window-preferred-function
8637 (lambda (window)
8638 (or (and (let ((split-height-threshold 0)) (window-splittable-p (selected-window)))
8639 ;; Try to split the selected window vertically if that's possible. (Bug#1806)
8640 (if (fboundp 'split-window-below) (split-window-below) (split-window-vertically)))
8641 (split-window-sensibly window))))
8642 pop-up-frames)
8643 (pop-to-buffer (get-buffer-create buf)))
8644 (set-window-start (selected-window) (point-min))
8645 (when dired-shrink-to-fit
8646 ;; Try to not delete window when we want to display less than `window-min-height' lines.
8647 (fit-window-to-buffer (get-buffer-window buf) nil 1))))
8648
8649
8650;; REPLACE ORIGINAL in `dired.el':
8651;;
8652;; 1. Delete the window or frame popped up, afterward, and bury its buffer.
8653;; Fixes Emacs bug #7533.
8654;;
8655;; 2, If buffer is shown in a separate frame, do not show a menu bar for that frame.
8656;;
8657(defun dired-mark-pop-up (buffer-or-name op-symbol files function &rest args)
8658 "Return FUNCTION's result on ARGS after showing which files are marked.
8659Displays the file names in a buffer named BUFFER-OR-NAME, the default
8660name being \" *Marked Files*\". The buffer is not shown if there is
8661just one file, `dired-no-confirm' is t, or OP-SYMBOL is a member of
8662the list in `dired-no-confirm'. Uses function `dired-pop-to-buffer'
8663to show the buffer.
8664
8665The window is not shown if there is just one file, `dired-no-confirm'
8666is `t', or OP-SYMBOL is a member of `dired-no-confirm'.
8667
8668FILES is the list of marked files. It can also be (t FILENAME)
8669in the case of one marked file, to distinguish that from using
8670just the current file.
8671
8672FUNCTION should not manipulate the files. It should just read input
8673\(an argument or confirmation)."
8674 (unless buffer-or-name (setq buffer-or-name " *Marked Files*"))
8675 (let (result)
8676 (if (or (eq dired-no-confirm t)
8677 (memq op-symbol dired-no-confirm)
8678 ;; If FILES defaulted to the current line's file.
8679 (= (length files) 1))
8680 (setq result (apply function args))
8681 (with-current-buffer (get-buffer-create buffer-or-name)
8682 (erase-buffer)
8683 ;; Handle (t FILE) just like (FILE), here. That value is used (only in some cases),
8684 ;; to mean just one file that was marked, rather than the current-line file.
8685 (dired-format-columns-of-files (if (eq (car files) t) (cdr files) files))
8686 (remove-text-properties (point-min) (point-max)
8687 '(mouse-face nil help-echo nil)))
8688 (unwind-protect
8689 (save-window-excursion
8690 ;; Do not show menu bar, if buffer is popped up in a separate frame.
8691 (let ((special-display-frame-alist (cons '(menu-bar-lines . 0)
8692 special-display-frame-alist))
8693 (default-frame-alist (cons '(menu-bar-lines . 0)
8694 default-frame-alist)))
8695 (dired-pop-to-buffer buffer-or-name)
8696 (goto-char (point-min)))
8697 (setq result (apply function args)))
8698 (save-excursion
8699 (condition-case nil ; Ignore error if user already deleted window.
8700 (progn (select-window (get-buffer-window buffer-or-name 0))
8701 (if (one-window-p) (delete-frame) (delete-window)))
8702 (error nil)))
8703 (bury-buffer buffer-or-name)))
8704 result))
8705
8706
8707;; REPLACE ORIGINAL in `dired.el':
8708;;
8709;; 1. Prefix arg has more possibilities.
8710;; 2, Added optional arg LOCALP, so you can mark/unmark matching different file-name forms.
8711;; 3. Push REGEXP onto `regexp-search-ring'.
8712;;
8713;;;###autoload
8714(defun dired-mark-files-regexp (regexp &optional marker-char localp)
8715 "Mark all file names matching REGEXP for use in later commands.
8716`.' and `..' are never marked or unmarked by this command.
8717
8718Whether to mark or unmark, and what form of file name to match, are
8719governed by the prefix argument. For this, a plain (`C-u') or a
8720double-plain (`C-u C-u') prefix arg is considered only as such - it is
8721not considered numerically.
8722
8723Whether to mark or unmark:
8724
8725 - No prefix arg, a positive arg, or a negative arg means mark.
8726
8727 - Plain (`C-u'), double-plain (`C-u C-u'), or zero (e.g. `M-0' means
8728 unmark.
8729
8730The form of a file name used for matching:
8731
8732 - No prefix arg (to mark) or a plain prefix arg (`C-u', to unmark)
8733 means use the relative file name (no directory part).
8734
8735 - A negative arg (e.g. `M--', to mark) or a zero arg (e.g. `M-0', to
8736 unmark) means use the absolute file name, that is, including all
8737 directory components.
8738
8739 - A positive arg (e.g. `M-+', to mark) or a double plain arg (`C-u
8740 C-u', to unmark) means construct the name relative to
8741 `default-directory'. For an entry in an inserted subdir listing,
8742 this means prefix the relative file name (no directory part) with
8743 the subdir name relative to `default-directory'.
8744
8745Note that the default matching behavior of this command is different
8746for Dired+ than it is for vanilla Emacs. Using a positive prefix arg
8747or a double plain prefix arg (`C-u C-u') gives you the same behavior
8748as vanilla Emacs (marking or unmarking, respectively): matching
8749against names that are relative to the `default-directory'.
8750
8751What Dired+ offers in addition is the possibility to match against
8752names that are relative (have no directory part - no prefix arg or
8753`C-u' to mark and unmark, respectively) or absolute (`M--' or `M-0',
8754respectively). The default behavior uses relative names because this
8755is likely to be the more common use case. But matching against
8756absolute names gives you more flexibility.
8757
8758REGEXP is an Emacs regexp, not a shell wildcard. Thus, use `\\.o$'
8759for object files--just `.o' might mark more than you might expect.
8760
8761REGEXP is added to `regexp-search-ring', for regexp search.
8762
8763Non-interactively:
8764 MARKER-CHAR is the marker character - used for `dired-marker-char'.
8765 LOCALP is passed to `dired-get-filename'. It determines the form of
8766 filename that is matched against REGEXP."
8767 (interactive (let* ((raw current-prefix-arg)
8768 (C-u (and (consp raw) (= 4 (car raw))))
8769 (C-u-C-u (and (consp raw) (= 16 (car raw))))
8770 (num (and raw (prefix-numeric-value raw))))
8771 (list (diredp-read-regexp (concat (if (or (consp raw) (and num (zerop num)))
8772 "UNmark"
8773 "Mark")
8774 " files (regexp): "))
8775 (and raw (or C-u C-u-C-u (zerop num)) ?\040)
8776 (cond ((or (not raw) C-u) t) ; none, `C-u'
8777 ((> num 0) nil) ; `M-+', `C-u C-u'
8778 (t 'no-dir))))) ; `M--', `M-0'
8779 (add-to-list 'regexp-search-ring regexp) ; Add REGEXP to `regexp-search-ring'.
8780 (let ((dired-marker-char (or marker-char dired-marker-char)))
8781 (diredp-mark-if (and (not (diredp-looking-at-p dired-re-dot))
8782 (not (eolp)) ; Empty line
8783 (let ((fn (dired-get-filename localp t)))
8784 (and fn (diredp-string-match-p regexp fn))))
8785 "file")))
8786
8787
8788;; REPLACE ORIGINAL in `dired.el':
8789;;
8790;; Use `diredp-mark-if', not `dired-mark-if'.
8791;;
8792;;;###autoload
8793(defun dired-mark-files-containing-regexp (regexp &optional marker-char)
8794 "Mark files with contents containing a REGEXP match.
8795A prefix argument means unmark them instead.
8796`.' and `..' are never marked.
8797
8798If a file is visited in a buffer and `dired-always-read-filesystem' is
8799nil, this looks in the buffer without revisiting the file, so the
8800results might be inconsistent with the file on disk if its contents
8801have changed since it was last visited."
8802 (interactive
8803 (list (diredp-read-regexp (concat (if current-prefix-arg "Unmark" "Mark") " files containing (regexp): ")
8804 nil 'dired-regexp-history)
8805 (and current-prefix-arg ?\040)))
8806 (let ((dired-marker-char (or marker-char dired-marker-char)))
8807 (diredp-mark-if (and (not (diredp-looking-at-p dired-re-dot))
8808 (not (eolp))
8809 (let ((fname (dired-get-filename nil t)))
8810 (when (and fname (file-readable-p fname) (not (file-directory-p fname)))
8811 (let ((prebuf (get-file-buffer fname)))
8812 (message "Checking %s" fname)
8813 ;; For now, do it inside Emacs. Grep might be better if there are lots of files.
8814 (if (and prebuf (or (not (boundp 'dired-always-read-filesystem))
8815 (not dired-always-read-filesystem))) ; Emacs 26+
8816 (with-current-buffer prebuf
8817 (save-excursion (goto-char (point-min)) (re-search-forward regexp nil t)))
8818 (with-temp-buffer
8819 (insert-file-contents fname)
8820 (goto-char (point-min))
8821 (re-search-forward regexp nil t)))))))
8822 "file")))
8823
8824
8825;; REPLACE ORIGINAL in `dired.el':
8826;;
8827;; Use `diredp-mark-if', not `dired-mark-if'.
8828;;
8829;;;###autoload
8830(defun dired-mark-symlinks (unflag-p)
8831 "Mark all symbolic links.
8832With prefix argument, unmark or unflag all those files."
8833 (interactive "P")
8834 (let ((dired-marker-char (if unflag-p ?\040 dired-marker-char)))
8835 (diredp-mark-if (diredp-looking-at-p dired-re-sym) "symbolic link")))
8836
8837
8838;; REPLACE ORIGINAL in `dired.el':
8839;;
8840;; Use `diredp-mark-if', not `dired-mark-if'.
8841;;
8842;;;###autoload
8843(defun dired-mark-directories (unflag-p)
8844 "Mark all directory file lines except `.' and `..'.
8845With prefix argument, unmark or unflag the files instead."
8846 (interactive "P")
8847 (let ((dired-marker-char (if unflag-p ?\040 dired-marker-char)))
8848 (diredp-mark-if (and (diredp-looking-at-p dired-re-dir) (not (diredp-looking-at-p dired-re-dot)))
8849 "directory" "directories")))
8850
8851
8852;; REPLACE ORIGINAL in `dired.el':
8853;;
8854;; Use `diredp-mark-if', not `dired-mark-if'.
8855;;
8856;;;###autoload
8857(defun dired-mark-executables (unflag-p)
8858 "Mark all executable files.
8859With prefix argument, unmark or unflag the files instead."
8860 (interactive "P")
8861 (let ((dired-marker-char (if unflag-p ?\040 dired-marker-char)))
8862 (diredp-mark-if (diredp-looking-at-p dired-re-exe) "executable file")))
8863
8864
8865;; REPLACE ORIGINAL in `dired.el':
8866;;
8867;; Use `diredp-mark-if', not `dired-mark-if'.
8868;;
8869;;;###autoload
8870(defun dired-flag-auto-save-files (&optional unflag-p)
8871 "Flag for deletion files whose names suggest they are auto save files.
8872A prefix argument says to unmark or unflag the files instead."
8873 (interactive "P")
8874 (let ((dired-marker-char (if unflag-p ?\040 dired-del-marker)))
8875 (diredp-mark-if
8876 ;; It is less than general to check for # here, but it's the only way this runs fast enough.
8877 (and (save-excursion (end-of-line)
8878 (or (eq (preceding-char) ?#)
8879 ;; Handle executables in case of -F option. Need not worry about the other kinds
8880 ;; of markings that -F makes, since they won't appear on real auto-save files.
8881 (and (eq (preceding-char) ?*)
8882 (progn (forward-char -1) (eq (preceding-char) ?#)))))
8883 (not (diredp-looking-at-p dired-re-dir))
8884 (let ((fname (dired-get-filename t t)))
8885 (and fname (auto-save-file-name-p (file-name-nondirectory fname)))))
8886 "auto-save file")))
8887
8888;;;###autoload
8889(defun diredp-capitalize (&optional arg) ; Bound to `% c'
8890 "Rename all marked (or next ARG) files by capitalizing them.
8891Makes the first char of the name uppercase and the others lowercase."
8892 (interactive "P")
8893 (dired-rename-non-directory #'capitalize "Rename by capitalizing:" arg))
8894
8895;; This is more useful than a single-file version of `dired-do-delete'.
8896;;;###autoload
8897(defun diredp-delete-this-file (&optional use-trash-can) ; Bound to `C-k', `delete'
8898 "In Dired, delete the file on the cursor line, upon confirmation.
8899This uses `delete-file'.
8900If the file is a symlink, remove the symlink. If the file has
8901multiple names, it continues to exist with the other names.
8902
8903For Emacs 24 and later, a prefix arg means that if
8904`delete-by-moving-to-trash' is non-nil then trash the file instead of
8905deleting it."
8906 (interactive "P")
8907 (let ((file (dired-get-filename)))
8908 (if (not (yes-or-no-p (format "%s file `%s'? " (if (and use-trash-can delete-by-moving-to-trash)
8909 "Trash"
8910 "Permanently delete")
8911 file)))
8912 (message "OK - canceled")
8913 (if (> emacs-major-version 23) (delete-file file use-trash-can) (delete-file file))
8914 (revert-buffer))))
8915
8916;;; Versions of `dired-do-*' commands for just this line's file.
8917;;;###autoload
8918(defun diredp-capitalize-this-file () ; Bound to `M-c'
8919 "In Dired, rename the file on the cursor line by capitalizing it.
8920Makes the first char of the name uppercase and the others lowercase."
8921 (interactive) (diredp-capitalize 1))
8922
8923;;;###autoload
8924(defun diredp-downcase-this-file () ; Bound to `M-l'
8925 "In Dired, rename the file on the cursor line to lower case."
8926 (interactive) (dired-downcase 1))
8927
8928;;;###autoload
8929(defun diredp-upcase-this-file () ; Bound to `M-u'
8930 "In Dired, rename the file on the cursor line to upper case."
8931 (interactive) (dired-upcase 1))
8932
8933;;;###autoload
8934(defun diredp-rename-this-file () ; Bound to `r'
8935 "In Dired, rename the file on the cursor line."
8936 (interactive)
8937 (let ((use-file-dialog nil)) (dired-do-rename 1)))
8938
8939(when (fboundp 'epa-dired-do-encrypt) ; Emacs 23+
8940 (defun diredp-decrypt-this-file ()
8941 "In Dired, decrypt the file on the cursor line."
8942 (interactive)
8943 (let ((use-file-dialog nil)) (epa-dired-do-decrypt 1)))
8944
8945 (defun diredp-encrypt-this-file ()
8946 "In Dired, encrypt the file on the cursor line."
8947 (interactive)
8948 (let ((use-file-dialog nil)) (epa-dired-do-encrypt 1)))
8949
8950 (defun diredp-verify-this-file ()
8951 "In Dired, verify the file on the cursor line."
8952 (interactive)
8953 (let ((use-file-dialog nil)) (epa-dired-do-verify 1)))
8954
8955 (defun diredp-sign-this-file ()
8956 "In Dired, sign the file on the cursor line."
8957 (interactive)
8958 (let ((use-file-dialog nil)) (epa-dired-do-sign 1))))
8959
8960;;;###autoload
8961(defun diredp-copy-this-file () ; Not bound
8962 "In Dired, copy the file on the cursor line."
8963 (interactive)
8964 (let ((use-file-dialog nil)) (dired-do-copy 1)))
8965
8966;;;###autoload
8967(defun diredp-relsymlink-this-file () ; Bound to `y'
8968 "In Dired, make a relative symbolic link to file on cursor line."
8969 (interactive)
8970 (let ((use-file-dialog nil)) (and (fboundp 'dired-do-relsymlink) (dired-do-relsymlink 1))))
8971
8972;;;###autoload
8973(defun diredp-symlink-this-file () ; Not bound
8974 "In Dired, make a symbolic link to the file on the cursor line."
8975 (interactive)
8976 (let ((use-file-dialog nil)) (dired-do-symlink 1)))
8977
8978;;;###autoload
8979(defun diredp-hardlink-this-file () ; Not bound
8980 "In Dired, add a name (hard link) to the file on the cursor line."
8981 (interactive)
8982 (let ((use-file-dialog nil)) (dired-do-hardlink 1)))
8983
8984;;;###autoload
8985(defun diredp-print-this-file () ; Bound to `M-p'
8986 "In Dired, print the file on the cursor line."
8987 (interactive) (dired-do-print 1))
8988
8989;;;###autoload
8990(defun diredp-grep-this-file () ; Not bound
8991 "In Dired, grep the file on the cursor line."
8992 (interactive)
8993 (unless (and grep-command (or (< emacs-major-version 22)
8994 (not grep-use-null-device)
8995 (eq grep-use-null-device t)))
8996 (grep-compute-defaults))
8997 (grep (diredp-do-grep-1 (list (dired-get-filename t)))))
8998
8999;;;###autoload
9000(defun diredp-compress-this-file () ; Bound to `z'
9001 "In Dired, compress or uncompress the file on the cursor line."
9002 (interactive) (dired-do-compress 1))
9003
9004;;;###autoload
9005(defun diredp-async-shell-command-this-file (command filelist) ; Not bound
9006 "Run a shell COMMAND asynchronously on the file on the Dired cursor line.
9007Like `diredp-shell-command-this-file', but adds `&' at the end of
9008COMMAND to execute it asynchronously. The command output appears in
9009buffer `*Async Shell Command*'."
9010 (interactive (list (dired-read-shell-command (concat "& on " "%s: ") 1 (list (dired-get-filename t)))
9011 (list (dired-get-filename t))))
9012 (unless (diredp-string-match-p "&[ \t]*\\'" command) (setq command (concat command " &")))
9013 (dired-do-shell-command command 1 filelist))
9014
9015;;;###autoload
9016(defun diredp-shell-command-this-file (command filelist) ; Not bound
9017 "In Dired, run a shell COMMAND on the file on the cursor line."
9018 (interactive (list (dired-read-shell-command (concat "! on " "%s: ") 1 (list (dired-get-filename t)))
9019 (list (dired-get-filename t))))
9020 (dired-do-shell-command command 1 filelist))
9021
9022;;;###autoload
9023(defun diredp-bookmark-this-file (&optional prefix) ; Bound to `C-B' (`C-S-b')
9024 "In Dired, bookmark the file on the cursor line.
9025See `diredp-do-bookmark'."
9026 (interactive (progn (diredp-ensure-mode)
9027 (list (and diredp-prompt-for-bookmark-prefix-flag
9028 (read-string "Prefix for bookmark name: ")))))
9029 (diredp-do-bookmark prefix 1))
9030
9031;;;###autoload
9032(defun diredp-tag-this-file (tags &optional prefix) ; Bound to `T +'
9033 "In Dired, add some tags to the file on the cursor line.
9034You need library `bookmark+.el' to use this command."
9035 (interactive (progn (diredp-ensure-bookmark+)
9036 (diredp-ensure-mode)
9037 (list (bmkp-read-tags-completing)
9038 (and diredp-prompt-for-bookmark-prefix-flag
9039 (read-string "Prefix for bookmark name: ")))))
9040 (diredp-do-tag tags prefix 1))
9041
9042;;;###autoload
9043(defun diredp-untag-this-file (tags &optional prefix arg) ; Bound to `T -'
9044 "In Dired, remove some tags from the file on the cursor line.
9045With a prefix arg, remove all tags from the file.
9046You need library `bookmark+.el' to use this command."
9047 (interactive (progn (diredp-ensure-bookmark+)
9048 (diredp-ensure-mode)
9049 (let* ((pref (and diredp-prompt-for-bookmark-prefix-flag
9050 (read-string "Prefix for bookmark name: ")))
9051 (bmk (bmkp-get-autofile-bookmark (dired-get-filename) nil pref))
9052 (btgs (and bmk (bmkp-get-tags bmk))))
9053 (unless btgs (error "File has no tags to remove"))
9054 (list (if current-prefix-arg btgs (bmkp-read-tags-completing btgs))
9055 pref
9056 current-prefix-arg))))
9057 (diredp-do-untag tags prefix 1))
9058
9059;;;###autoload
9060(defun diredp-remove-all-tags-this-file (&optional prefix msgp) ; Bound to `T 0'
9061 "In Dired, remove all tags from this file.
9062You need library `bookmark+.el' to use this command."
9063 (interactive (progn (diredp-ensure-bookmark+)
9064 (diredp-ensure-mode)
9065 (list (and diredp-prompt-for-bookmark-prefix-flag
9066 (read-string "Prefix for bookmark name: "))
9067 'MSG)))
9068 (bookmark-maybe-load-default-file)
9069 (diredp-do-remove-all-tags prefix 1))
9070
9071;;;###autoload
9072(defun diredp-paste-add-tags-this-file (&optional prefix msgp) ; Bound to `T p', `T C-y'
9073 "In Dired, add previously copied tags to this file.
9074See `diredp-paste-add-tags'.
9075You need library `bookmark+.el' to use this command."
9076 (interactive (progn (diredp-ensure-bookmark+)
9077 (diredp-ensure-mode)
9078 (list (and diredp-prompt-for-bookmark-prefix-flag
9079 (read-string "Prefix for bookmark name: "))
9080 'MSG)))
9081 (bookmark-maybe-load-default-file)
9082 (diredp-do-paste-add-tags prefix 1))
9083
9084;;;###autoload
9085(defun diredp-paste-replace-tags-this-file (&optional prefix msgp) ; Bound to `T q'
9086 "In Dired, replace tags for this file with previously copied tags.
9087See `diredp-paste-replace-tags'.
9088You need library `bookmark+.el' to use this command."
9089 (interactive (progn (diredp-ensure-bookmark+)
9090 (diredp-ensure-mode)
9091 (list (and diredp-prompt-for-bookmark-prefix-flag
9092 (read-string "Prefix for bookmark name: "))
9093 'MSG)))
9094 (bookmark-maybe-load-default-file)
9095 (diredp-do-paste-add-tags prefix 1))
9096
9097;;;###autoload
9098(defun diredp-set-tag-value-this-file (tag value &optional prefix msgp) ; Bound to `T v'
9099 "In Dired, Set value of TAG to VALUE for this file.
9100See `diredp-set-tag-value'.
9101You need library `bookmark+.el' to use this command."
9102 (interactive (progn (diredp-ensure-bookmark+)
9103 (diredp-ensure-mode)
9104 (list (bmkp-read-tag-completing)
9105 (read (read-string "Value: "))
9106 (and diredp-prompt-for-bookmark-prefix-flag
9107 (read-string "Prefix for bookmark name: "))
9108 'MSG)))
9109 (bookmark-maybe-load-default-file)
9110 (diredp-do-set-tag-value tag value prefix 1))
9111
9112;;;###autoload
9113(defun diredp-copy-tags-this-file (&optional prefix msgp) ; Bound to `T c', `T M-w'
9114 "In Dired, copy the tags from this file, so you can paste them to another.
9115See `diredp-copy-tags'.
9116You need library `bookmark+.el' to use this command."
9117 (interactive (progn (diredp-ensure-bookmark+)
9118 (diredp-ensure-mode)
9119 (list (and diredp-prompt-for-bookmark-prefix-flag
9120 (read-string "Prefix for bookmark name: "))
9121 'MSG)))
9122 (bookmark-maybe-load-default-file)
9123 (let ((bmk (bmkp-get-autofile-bookmark (dired-get-filename) nil prefix)))
9124 (and bmk (bmkp-copy-tags bmk msgp))))
9125
9126;;;###autoload
9127(defun diredp-mouse-copy-tags (event) ; Not bound
9128 "In Dired, copy the tags from this file, so you can paste them to another.
9129You need library `bookmark+.el' to use this command."
9130 (interactive "e")
9131 (let ((mouse-pos (event-start event))
9132 (dired-no-confirm t)
9133 (prefix (and diredp-prompt-for-bookmark-prefix-flag
9134 (read-string "Prefix for bookmark name: "))))
9135 (select-window (posn-window mouse-pos))
9136 (goto-char (posn-point mouse-pos))
9137 (diredp-copy-tags-this-file prefix 'MSG))
9138 (diredp-previous-line 1))
9139
9140(when (fboundp 'describe-file) ; In `help-fns+.el' or `help+20.el'.
9141 (defun diredp-describe-file (&optional internal-form-p) ; Bound to `C-h RET', `C-h C-RET'
9142 "In Dired, describe this file or directory.
9143You need library `help-fns+.el' to use this command.
9144If the file has an autofile bookmark and you use library `Bookmark+',
9145then show also the bookmark information (tags etc.). In this case, a
9146prefix arg shows the internal form of the bookmark."
9147 (interactive "P")
9148 (describe-file (dired-get-filename nil t) internal-form-p))
9149
9150 (defun diredp-mouse-describe-file (event &optional internal-form-p) ; Not bound
9151 "Describe the clicked file.
9152You need library `help-fns+.el' to use this command.
9153If the file has an autofile bookmark and you use library `Bookmark+',
9154then show also the bookmark information (tags etc.). In this case, a
9155prefix arg shows the internal form of the bookmark."
9156 (interactive "e\nP")
9157 (let (file)
9158 (with-current-buffer (window-buffer (posn-window (event-end event)))
9159 (save-excursion (goto-char (posn-point (event-end event)))
9160 (setq file (dired-get-filename nil t))))
9161 (describe-file file internal-form-p))))
9162
9163;; Define these even if `Bookmark+' is not loaded.
9164;;;###autoload
9165(defalias 'diredp-show-metadata 'diredp-describe-autofile)
9166;;;###autoload
9167(defun diredp-describe-autofile (&optional internal-form-p)
9168 "Show the metadata for the file of the current line.
9169The file must name an autofile bookmark. The metadata is the bookmark
9170information.
9171
9172With a prefix argument, show the internal definition of the bookmark.
9173
9174You need library `bookmark+.el' for this command."
9175 (interactive "P")
9176 (diredp-ensure-bookmark+)
9177 (diredp-ensure-mode)
9178 (let ((bmk (save-match-data
9179 (bmkp-get-autofile-bookmark (dired-get-filename nil t)))))
9180 (unless bmk (error "Not on an autofile bookmark"))
9181 (save-selected-window (if internal-form-p
9182 (bmkp-describe-bookmark-internals bmk)
9183 (bmkp-describe-bookmark bmk)))))
9184
9185(defun diredp-mouse-describe-autofile (event &optional internal-form-p) ; Not bound
9186 "Show the metadata for the file whose name you click.
9187The file must name an autofile bookmark. The metadata is the bookmark
9188information.
9189
9190With a prefix argument, show the internal definition of the bookmark.
9191
9192You need library `bookmark+.el' for this command."
9193 (interactive "e\nP")
9194 (diredp-ensure-bookmark+)
9195 (let (file)
9196 (with-current-buffer (window-buffer (posn-window (event-end event)))
9197 (diredp-ensure-mode)
9198 (save-excursion (goto-char (posn-point (event-end event)))
9199 (setq file (dired-get-filename nil t))))
9200 (let ((bmk (save-match-data (bmkp-get-autofile-bookmark file))))
9201 (unless bmk (error "Not an autofile bookmark"))
9202 (save-selected-window (if internal-form-p
9203 (bmkp-describe-bookmark-internals bmk)
9204 (bmkp-describe-bookmark bmk))))))
9205
9206;;;###autoload
9207(defalias 'diredp-show-metadata-for-marked 'diredp-describe-marked-autofiles)
9208;;;###autoload
9209(defun diredp-describe-marked-autofiles (&optional internal-form-p interactivep)
9210 "Show metadata for the marked files.
9211If no file is marked, describe ALL autofiles in this directory.
9212With a prefix argument, show the internal (Lisp) form of the metadata.
9213When invoked interactively, raise an error if no files are marked.
9214You need library `bookmark+.el' for this command."
9215 (interactive "P\np")
9216 (diredp-ensure-bookmark+)
9217 (let ((help-xref-following nil))
9218 (help-setup-xref (list `(lambda (_buf)
9219 (with-current-buffer ,(current-buffer) (diredp-describe-marked-autofiles)))
9220 internal-form-p)
9221 (if (or (> emacs-major-version 23)
9222 (and (= emacs-major-version 23) (> emacs-minor-version 1)))
9223 (called-interactively-p 'interactive)
9224 (interactive-p))))
9225 (diredp-with-help-window "*Help*"
9226 (let ((marked (dired-get-marked-files nil nil nil 'DISTINGUISH-ONE-MARKED interactivep)))
9227 (unless (cdr marked)
9228 (message "Describing ALL autofiles here (none are marked)...")
9229 (setq marked (diredp-get-files 'IGNORE-MARKS-P)))
9230 (if (eq t (car marked))
9231 (diredp-describe-autofile internal-form-p)
9232 (dolist (bmk (delq nil (mapcar #'bmkp-get-autofile-bookmark marked)))
9233 (if internal-form-p
9234 (let* ((bname (bmkp-bookmark-name-from-record bmk))
9235 (help-text (format "%s\n%s\n\n%s"
9236 bname (make-string (length bname) ?-) (pp-to-string bmk))))
9237 (princ help-text) (terpri))
9238 (princ (bmkp-bookmark-description bmk)) (terpri)))))))
9239
9240;;;###autoload
9241(defun diredp-byte-compile-this-file () ; Bound to `b'
9242 "In Dired, byte compile the (Lisp source) file on the cursor line."
9243 (interactive) (dired-do-byte-compile 1))
9244
9245;;;###autoload
9246(defun diredp-load-this-file () ; Not bound
9247 "In Dired, load the file on the cursor line."
9248 (interactive) (dired-do-load 1))
9249
9250;;;###autoload
9251(defun diredp-chmod-this-file () ; Bound to `M-m'
9252 "In Dired, change the mode of the file on the cursor line."
9253 (interactive) (dired-do-chmod 1))
9254
9255(unless (memq system-type '(windows-nt ms-dos))
9256 (defun diredp-chgrp-this-file () ; Not bound
9257 "In Dired, change the group of the file on the cursor line."
9258 (interactive) (dired-do-chgrp 1)))
9259
9260(unless (memq system-type '(windows-nt ms-dos))
9261 (defun diredp-chown-this-file () ; Not bound
9262 "In Dired, change the owner of the file on the cursor line."
9263 (interactive) (dired-do-chown 1)))
9264
9265(when (fboundp 'dired-do-touch)
9266 (defun diredp-touch-this-file () ; Not bound
9267 "In Dired, `touch' (change the timestamp of) the file on the cursor line."
9268 (interactive) (dired-do-touch 1)))
9269
9270
9271;; REPLACE ORIGINAL in `dired-x.el'.
9272;;
9273;; 1. Variable (symbol) `s' -> `blks'.
9274;; 2. Fixes to remove leading space from `uid' and allow `.' in `gid'.
9275;; 3. Cleaned up doc string and code a bit.
9276;;
9277;;;###autoload
9278(defun dired-mark-sexp (predicate &optional unmark-p) ; Bound to `M-(', `* ('
9279 "Mark files for which PREDICATE returns non-nil.
9280With a prefix arg, unmark or unflag those files instead.
9281
9282PREDICATE is a lisp sexp that can refer to the following symbols as
9283variables:
9284
9285 `mode' [string] file permission bits, e.g. \"-rw-r--r--\"
9286 `nlink' [integer] number of links to file
9287 `size' [integer] file size in bytes
9288 `uid' [string] owner
9289 `gid' [string] group (If the gid is not displayed by `ls',
9290 this will still be set (to the same as uid))
9291 `time' [string] the time that `ls' displays, e.g. \"Feb 12 14:17\"
9292 `name' [string] the name of the file
9293 `sym' [string] if file is a symbolic link, the linked-to name,
9294 else \"\"
9295 `inode' [integer] the inode of the file (only for `ls -i' output)
9296 `blks' [integer] the size of the file for `ls -s' output
9297 (ususally in blocks or, with `-k', in Kbytes)
9298Examples:
9299 Mark zero-length files: `(equal 0 size)'
9300 Mark files last modified on Feb 2: `(string-match \"Feb 2\" time)'
9301 Mark uncompiled Emacs Lisp files (`.el' file without a `.elc' file):
9302 First, Dired just the source files: `dired *.el'.
9303 Then, use \\[dired-mark-sexp] with this sexp:
9304 (not (file-exists-p (concat name \"c\")))
9305
9306There's an ambiguity when a single integer not followed by a unit
9307prefix precedes the file mode: It is then parsed as inode number
9308and not as block size (this always works for GNU coreutils ls).
9309
9310Another limitation is that the uid field is needed for the
9311function to work correctly. In particular, the field is not
9312present for some values of `ls-lisp-emulation'.
9313
9314This function operates only on the Dired buffer content. It does not
9315refer at all to the underlying file system. Contrast this with
9316`find-dired', which might be preferable for the task at hand."
9317 ;; Using `sym' = "", instead of nil, for non-linked files avoids the trap of
9318 ;; (string-match "foo" sym) into which a user would soon fall.
9319 ;; Use `equal' instead of `=' in the example, as it works on integers and strings.
9320 (interactive "xMark if (vars: inode,blks,mode,nlink,uid,gid,size,time,name,sym): \nP")
9321 (message "%s" predicate)
9322 (let ((dired-marker-char (if unmark-p ?\040 dired-marker-char))
9323 (inode nil)
9324 (blks ())
9325 mode nlink uid gid size time name sym)
9326 (diredp-mark-if
9327 (save-excursion
9328 (and
9329 ;; Sets vars INODE BLKS MODE NLINK UID GID SIZE TIME NAME and SYM
9330 ;; according to current file line. Returns `t' for success, nil if
9331 ;; there is no file line. Upon success, these vars are set, to either
9332 ;; nil or the appropriate value, so they need not be initialized.
9333 ;; Moves point within the current line.
9334 (dired-move-to-filename)
9335 (let ((mode-len 10) ; Length of mode string.
9336 ;; As in `dired.el', but with subexpressions \1=inode, \2=blks:
9337 ;; GNU `ls -hs' suffixes the block count with a unit and prints it as a float; FreeBSD does neither.
9338 ;; $$$$$$ (dired-re-inode-size "\\s *\\([0-9]*\\)\\s *\\([0-9]*\\) ?")
9339 (dired-re-inode-size (if (> emacs-major-version 24)
9340 "\\=\\s *\\([0-9]+\\s +\\)?\
9341\\(?:\\([0-9]+\\(?:\\.[0-9]*\\)?[BkKMGTPEZY]?\\)? ?\\)"
9342 "\\s *\\([0-9]*\\)\\s *\\([0-9]*\\) ?"))
9343 pos)
9344 (beginning-of-line)
9345 (forward-char 2)
9346 (search-forward-regexp dired-re-inode-size nil t)
9347 ;; XXX Might be a size not followed by a unit prefix. Could set `blks' to `inode' if it were otherwise
9348 ;; nil, with similar reasoning as for setting `gid' to `uid', but it would be even more whimsical.
9349 (setq inode (and (match-string 1) (string-to-number (match-string 1))))
9350 (setq blks (and (match-string 2) (if (fboundp 'dired-x--string-to-number)
9351 (dired-x--string-to-number (match-string 2)) ; Emacs 25+
9352 (string-to-number (match-string 2)))))
9353 (setq mode (buffer-substring (point) (+ mode-len (point))))
9354 (forward-char mode-len)
9355 (unless (diredp-looking-at-p " ") (forward-char 1)) ; Skip any extended attributes marker ("." or "+").
9356 (setq nlink (read (current-buffer)))
9357 ;; Karsten Wenger <kw@cis.uni-muenchen.de> fixed uid.
9358
9359 ;; Another issue is that GNU `ls -n' right-justifies numerical UIDs and GIDs, while FreeBSD
9360 ;; left-justifies them, so do not rely on a specific whitespace layout. Both of them right-justify all
9361 ;; other numbers, though.
9362 ;; XXX Return a number if the `uid' or `gid' seems to be numerical?
9363 ;; $$$$$$ (setq uid (buffer-substring (+ (point) 1) (progn (forward-word 1) (point))))
9364 (setq uid (buffer-substring (progn (skip-chars-forward " \t") (point))
9365 (progn (skip-chars-forward "^ \t") (point))))
9366 (cond ((> emacs-major-version 24)
9367 (dired-move-to-filename)
9368 (save-excursion
9369 (setq time
9370 ;; The regexp below tries to match from the last digit of the size field through a
9371 ;; space after the date. Also, dates may have different formats depending on file age,
9372 ;; so the date column need not be aligned to the right.
9373 (buffer-substring (save-excursion (skip-chars-backward " \t") (point))
9374 (progn (re-search-backward directory-listing-before-filename-regexp)
9375 (skip-chars-forward "^ \t")
9376 (1+ (point))))
9377 size
9378 (dired-x--string-to-number
9379 ;; We know that there's some kind of number before point because the regexp search
9380 ;; above succeeded. Not worth doing an extra check for leading garbage.
9381 (buffer-substring (point) (progn (skip-chars-backward "^ \t") (point))))
9382 ;; If no `gid' is displayed, `gid' will be set to `uid' but user will then not reference
9383 ;; it anyway in PREDICATE.
9384 gid
9385 (buffer-substring (progn (skip-chars-backward " \t") (point))
9386 (progn (skip-chars-backward "^ \t") (point)))))
9387 (setq name (buffer-substring (point) (or (dired-move-to-end-of-filename t) (point)))
9388 sym (if (diredp-looking-at-p " -> ")
9389 (buffer-substring (progn (forward-char 4) (point)) (line-end-position))
9390 "")))
9391 (t
9392 (re-search-forward
9393 (if (< emacs-major-version 20)
9394 "\\(Jan\\|Feb\\|Mar\\|Apr\\|May\\|Jun\\|Jul\\|Aug\\|Sep\\|Oct\\|Nov\\|Dec\\)"
9395 dired-move-to-filename-regexp))
9396 (goto-char (match-beginning 1))
9397 (forward-char -1)
9398 (setq size (string-to-number (buffer-substring (save-excursion (backward-word 1)
9399 (setq pos (point)))
9400 (point))))
9401 (goto-char pos)
9402 (backward-word 1)
9403 ;; if no `gid' is displayed, `gid' will be set to `uid' but user will then not reference
9404 ;; it anyway in PREDICATE.
9405 (setq gid (buffer-substring (save-excursion (forward-word 1) (point)) (point))
9406 time (buffer-substring (match-beginning 1) (1- (dired-move-to-filename)))
9407 name (buffer-substring (point) (or (dired-move-to-end-of-filename t) (point)))
9408 sym (if (diredp-looking-at-p " -> ")
9409 (buffer-substring (progn (forward-char 4) (point)) (line-end-position))
9410 "")))))
9411 ;; Vanilla Emacs uses `lexical-binding' = t, and it passes bindings to `eval' as a second arg.
9412 ;; We use `lexical-binding' = nil, and anyway there should be no need to pass the bindings.
9413 (eval predicate)))
9414 (format "'%s file" predicate))))
9415
9416(defun diredp-this-file-marked-p (&optional mark-char)
9417 "Return non-nil if the file on this line is marked.
9418Optional arg MARK-CHAR is the type of mark to check.
9419 If nil, then if the file has any mark, including `D', it is marked."
9420 (and (dired-get-filename t t) (save-excursion
9421 (beginning-of-line)
9422 (if mark-char
9423 (diredp-looking-at-p (concat "^" (char-to-string mark-char)))
9424 (not (diredp-looking-at-p "^ "))))))
9425
9426(defun diredp-this-file-unmarked-p (&optional mark-char)
9427 "Return non-nil if the file on this line is unmarked.
9428Optional arg MARK-CHAR is the type of mark to check.
9429 If nil, then if the file has no mark, including `D', it is unmarked.
9430 If non-nil, then it is unmarked for MARK-CHAR if it has no mark or
9431 it has any mark except MARK-CHAR."
9432 (and (dired-get-filename t t) (save-excursion
9433 (beginning-of-line)
9434 (if mark-char
9435 (not (diredp-looking-at-p (concat "^" (char-to-string mark-char))))
9436 (diredp-looking-at-p "^ ")))))
9437
9438;;;###autoload
9439(defun diredp-mark-region-files (&optional unmark-p) ; Not bound
9440 "Mark all of the files in the current region (if it is active).
9441With non-nil prefix arg, unmark them instead."
9442 (interactive "P")
9443 (let ((beg (min (point) (mark)))
9444 (end (max (point) (mark)))
9445 (inhibit-field-text-motion t)) ; Just in case.
9446 (setq beg (save-excursion (goto-char beg) (line-beginning-position))
9447 end (save-excursion (goto-char end) (line-end-position)))
9448 (let ((dired-marker-char (if unmark-p ?\040 dired-marker-char)))
9449 (diredp-mark-if (and (<= (point) end) (>= (point) beg) (diredp-this-file-unmarked-p)) "region file"))))
9450
9451;;;###autoload
9452(defun diredp-unmark-region-files (&optional mark-p) ; Not bound
9453 "Unmark all of the files in the current region (if it is active).
9454With non-nil prefix arg, mark them instead."
9455 (interactive "P")
9456 (let ((beg (min (point) (mark)))
9457 (end (max (point) (mark)))
9458 (inhibit-field-text-motion t)) ; Just in case.
9459 (setq beg (save-excursion (goto-char beg) (line-beginning-position))
9460 end (save-excursion (goto-char end) (line-end-position)))
9461 (let ((dired-marker-char (if mark-p dired-marker-char ?\040)))
9462 (diredp-mark-if (and (<= (point) end) (>= (point) beg) (diredp-this-file-marked-p)) "region file"))))
9463
9464;;;###autoload
9465(defun diredp-flag-region-files-for-deletion () ; Not bound
9466 "Flag all of the files in the current region (if it is active) for deletion."
9467 (interactive)
9468 (let ((beg (min (point) (mark)))
9469 (end (max (point) (mark)))
9470 (inhibit-field-text-motion t)) ; Just in case.
9471 (setq beg (save-excursion (goto-char beg) (line-beginning-position))
9472 end (save-excursion (goto-char end) (line-end-position)))
9473 (let ((dired-marker-char dired-del-marker))
9474 (diredp-mark-if (and (<= (point) end) (>= (point) beg) (diredp-this-file-unmarked-p ?\D))
9475 "region file"))))
9476
9477;;;###autoload
9478(defun diredp-toggle-marks-in-region (start end) ; Not bound
9479 "Toggle marks in the region."
9480 (interactive "r")
9481 (save-excursion
9482 (save-restriction
9483 (if (not (fboundp 'dired-toggle-marks))
9484 ;; Pre-Emacs 22. Use bol, eol. If details hidden, show first.
9485 (let ((details-hidden-p (and (boundp 'dired-details-state) (eq 'hidden dired-details-state))))
9486 (widen)
9487 (when details-hidden-p (dired-details-show))
9488 (goto-char start)
9489 (setq start (line-beginning-position))
9490 (goto-char end)
9491 (setq end (line-end-position))
9492 (narrow-to-region start end)
9493 (dired-toggle-marks)
9494 (when details-hidden-p (dired-details-hide)))
9495 (narrow-to-region start end)
9496 (dired-toggle-marks))))
9497 (when (and (get-buffer-window (current-buffer)) (fboundp 'fit-frame-if-one-window))
9498 (fit-frame-if-one-window)))
9499
9500
9501;;; Mouse 3 menu.
9502;;;;;;;;;;;;;;;;;
9503
9504(defvar diredp-file-line-overlay nil)
9505
9506;;;###autoload
9507(defun diredp-mouse-3-menu (event) ; Bound to `mouse-3'
9508 "Dired pop-up `mouse-3' menu, for files in selection or current line."
9509 (interactive "e")
9510 (if (not (and (fboundp 'mouse3-dired-use-menu) (diredp-nonempty-region-p)))
9511 ;; No `mouse3.el' or no region.
9512 (if (diredp-nonempty-region-p)
9513 ;; Region
9514 (let ((reg-choice (x-popup-menu
9515 event
9516 (list "Files in Region"
9517 (list ""
9518 '("Mark" . diredp-mark-region-files)
9519 '("Unmark" . diredp-unmark-region-files)
9520 '("Toggle Marked/Unmarked" .
9521 diredp-toggle-marks-in-region)
9522 '("Flag for Deletion" .
9523 diredp-flag-region-files-for-deletion))))))
9524 (when reg-choice (call-interactively reg-choice)))
9525 ;; Single file/dir (no region).
9526 (let ((mouse-pos (event-start event))
9527 ;; Do not use `save-excursion', because some commands will move point on purpose.
9528 ;; Just save original point and return to it unless MOVEP is set to non-nil.
9529 (opoint (point))
9530 (movep nil)
9531 (inhibit-field-text-motion t) ; Just in case.
9532 choice bol eol file/dir-name)
9533 (with-current-buffer (window-buffer (posn-window mouse-pos))
9534 (goto-char (posn-point mouse-pos))
9535 (setq bol (line-beginning-position)
9536 eol (line-end-position))
9537 (unwind-protect
9538 (when (setq file/dir-name (and (not (eobp)) (dired-get-filename nil t)))
9539 (if diredp-file-line-overlay ; Don't re-create if exists.
9540 (move-overlay diredp-file-line-overlay bol eol (current-buffer))
9541 (setq diredp-file-line-overlay (make-overlay bol eol))
9542 (overlay-put diredp-file-line-overlay 'face 'region))
9543 (sit-for 0)
9544 (let ((map
9545 (easy-menu-create-menu
9546 "This File"
9547 `(
9548 ("Bookmark" :visible (featurep 'bookmark+)
9549 ["Bookmark..." diredp-bookmark-this-file]
9550 ["Add Tags..." diredp-tag-this-file
9551 :visible (featurep 'bookmark+)]
9552 ["Remove Tags..." diredp-untag-this-file
9553 :visible (featurep 'bookmark+)]
9554 ["Remove All Tags" diredp-remove-all-tags-this-file
9555 :visible (featurep 'bookmark+)]
9556 ["Copy Tags" diredp-copy-tags-this-file
9557 :visible (featurep 'bookmark+)]
9558 ["Paste Tags (Add)" diredp-paste-add-tags-this-file
9559 :visible (featurep 'bookmark+)]
9560 ["Paste Tags (Replace)" diredp-paste-replace-tags-this-file
9561 :visible (featurep 'bookmark+)]
9562 ["Set Tag Value..." diredp-set-tag-value-this-file
9563 :visible (featurep 'bookmark+)]
9564 )
9565 ["Describe" ',(if (if (> emacs-major-version 21)
9566 (require 'help-fns+ nil t)
9567 (require 'help+20 nil t))
9568 'diredp-describe-file
9569 'diredp-describe-autofile)] ; Requires `bookmark+.el'
9570 ;; Stuff from `Marks' menu.
9571 ["Mark" dired-mark
9572 :visible (not (eql (dired-file-marker file/dir-name)
9573 dired-marker-char))]
9574 ["Unmark" dired-unmark
9575 :visible (dired-file-marker file/dir-name)]
9576 ["Flag for Deletion" dired-flag-file-deletion
9577 :visible (not (eql (dired-file-marker file/dir-name)
9578 dired-del-marker))]
9579 ["Delete..." diredp-delete-this-file]
9580 "--" ; ------------------------------------------------------
9581 ;; Stuff from `Single' / `Multiple' menus.
9582 ["Open" dired-find-file]
9583 ["Open in Other Window" dired-find-file-other-window]
9584 ["Open in Other Frame" diredp-find-file-other-frame]
9585 ["Open Associated Windows App" dired-w32-browser
9586 :visible (featurep 'w32-browser)]
9587 ["Open in Windows Explorer" dired-w32explore
9588 :visible (featurep 'w32-browser)]
9589 ["View (Read Only)" dired-view-file]
9590 ["--" 'ignore ; -------------------------------------------------
9591 :visible (or (atom (diredp-this-subdir)) ; Subdir line.
9592 (not (equal (expand-file-name (dired-current-directory))
9593 (expand-file-name default-directory))))] ; Not top.
9594 ["Insert This Subdir"
9595 (lambda () (interactive)
9596 (call-interactively #'dired-maybe-insert-subdir)
9597 (setq movep t))
9598 :visible (and (atom (diredp-this-subdir))
9599 (not (assoc (file-name-as-directory (diredp-this-subdir))
9600 dired-subdir-alist)))
9601 :enable (atom (diredp-this-subdir))]
9602 ["Go To Inserted Subdir"
9603 (lambda () (interactive)
9604 (call-interactively #'dired-maybe-insert-subdir)
9605 (setq movep t))
9606 :visible (and (atom (diredp-this-subdir))
9607 (assoc (file-name-as-directory (diredp-this-subdir))
9608 dired-subdir-alist))
9609 :enable (atom (diredp-this-subdir))
9610 :keys "i"]
9611 ["Remove This Inserted Subdir" dired-kill-subdir
9612 :visible (not (equal
9613 (expand-file-name (dired-current-directory))
9614 (expand-file-name default-directory)))] ; In subdir, not top.
9615 ["Remove This Inserted Subdir and Lower" diredp-kill-this-tree
9616 :visible (and (fboundp 'diredp-kill-this-tree)
9617 (not (equal
9618 (expand-file-name (dired-current-directory))
9619 (expand-file-name default-directory))))] ; In subdir, not top.
9620 ["Dired This Inserted Subdir (Tear Off)"
9621 (lambda () (interactive) (diredp-dired-this-subdir t))
9622 :visible (not (equal (expand-file-name (dired-current-directory))
9623 (expand-file-name default-directory)))] ; In subdir, not top.
9624 "--" ; ------------------------------------------------------
9625 ["Compare..." diredp-ediff]
9626 ["Diff..." dired-diff]
9627 ["Diff with Backup" dired-backup-diff]
9628
9629 ["Bookmark..." diredp-bookmark-this-file
9630 :visible (not (featurep 'bookmark+))]
9631 "--" ; ------------------------------------------------------
9632 ["Rename to..." diredp-rename-this-file]
9633 ["Capitalize" diredp-capitalize-this-file]
9634 ["Upcase" diredp-upcase-this-file]
9635 ["Downcase" diredp-downcase-this-file]
9636 "--" ; ------------------------------------------------------
9637 ["Copy to..." diredp-copy-this-file]
9638 ["Symlink to (Relative)..." diredp-relsymlink-this-file
9639 :visible (fboundp 'dired-do-relsymlink)] ; In `dired-x.el'.
9640 ["Symlink to..." diredp-symlink-this-file]
9641 ["Hardlink to..." diredp-hardlink-this-file]
9642 "--" ; ------------------------------------------------------
9643 ["Shell Command..." diredp-shell-command-this-file]
9644 ["Asynchronous Shell Command..."
9645 diredp-async-shell-command-this-file]
9646 ["Print..." diredp-print-this-file]
9647 ["Grep" diredp-grep-this-file]
9648 ["Compress/Uncompress" diredp-compress-this-file]
9649 ["Byte-Compile" diredp-byte-compile-this-file]
9650 ["Load" diredp-load-this-file]
9651 "--" ; ------------------------------------------------------
9652 ["Change Timestamp..." diredp-touch-this-file]
9653 ["Change Mode..." diredp-chmod-this-file]
9654 ["Change Group..." diredp-chgrp-this-file
9655 :visible (fboundp 'diredp-chgrp-this-file)]
9656 ["Change Owner..." diredp-chown-this-file
9657 :visible (fboundp 'diredp-chown-this-file)]))))
9658 (when diredp-file-line-overlay
9659 (delete-overlay diredp-file-line-overlay))
9660 (setq choice (x-popup-menu event map))
9661 (when choice (call-interactively (lookup-key map (apply 'vector choice))))))
9662 (unless movep (goto-char opoint))))))
9663 ;; `mouse3.el' and active region.
9664 (unless (eq mouse3-dired-function 'mouse3-dired-use-menu)
9665 (funcall #'mouse3-dired-use-menu)
9666 (revert-buffer))
9667 (let ((last-command 'mouse-save-then-kill)) (mouse-save-then-kill event))))
9668
9669
9670;; REPLACE ORIGINAL in `dired.el' for Emacs 20.
9671;;
9672;; Allow `.' and `..', by using non-nil second arg to `dired-get-filename'.
9673;;
9674(when (< emacs-major-version 21)
9675 (defun dired-find-file () ; Bound to `RET'
9676 "In Dired, visit the file or directory named on this line."
9677 (interactive)
9678 (let* ((dgf-result (or (dired-get-filename nil t) (error "No file on this line")))
9679 (file-name (file-name-sans-versions dgf-result t)))
9680 (if (file-exists-p file-name)
9681 (find-file file-name)
9682 (if (file-symlink-p file-name)
9683 (error "File is a symlink to a nonexistent target")
9684 (error "File no longer exists; type `g' to update Dired buffer"))))))
9685
9686;;;###autoload
9687(defun diredp-find-file-other-frame () ; Bound to `C-o'
9688 "In Dired, visit this file or directory in another frame."
9689 (interactive)
9690 (find-file-other-frame (file-name-sans-versions (dired-get-filename nil t) t)))
9691
9692;;;###autoload
9693(defun diredp-mouse-find-file-other-frame (event) ; Bound to `M-mouse-2'
9694 "In Dired, visit file or directory clicked on in another frame."
9695 (interactive "e")
9696 (let ((pop-up-frames t)) (dired-mouse-find-file-other-window event)))
9697
9698
9699;; REPLACE ORIGINAL in `dired.el'.
9700;;
9701;; Allow `.' and `..', by using non-nil second arg to `dired-get-filename'.
9702;;
9703;;;###autoload
9704(defun dired-mouse-find-file-other-window (event) ; Bound to `mouse-2'
9705 "In Dired, visit the file or directory name you click on."
9706 (interactive "e")
9707 (let (file)
9708 (with-current-buffer (window-buffer (posn-window (event-end event)))
9709 (save-excursion (goto-char (posn-point (event-end event)))
9710 (setq file (dired-get-filename nil t))))
9711 (unless (stringp file) (error "No file here"))
9712 (select-window (posn-window (event-end event)))
9713 (find-file-other-window (file-name-sans-versions file t))))
9714
9715;;;###autoload
9716(defun diredp-mouse-view-file (event) ; Not bound
9717 "Examine this file in view mode, returning to Dired when done.
9718When file is a directory, show it in this buffer if it is inserted;
9719otherwise, display it in another buffer."
9720 (interactive "e")
9721 (let (file)
9722 (with-current-buffer (window-buffer (posn-window (event-end event)))
9723 (save-excursion (goto-char (posn-point (event-end event)))
9724 (setq file (dired-get-filename nil t))))
9725 (select-window (posn-window (event-end event)))
9726 (if (file-directory-p file)
9727 (or (and (cdr dired-subdir-alist) (dired-goto-subdir file)) (dired file))
9728 (view-file file)))) ; In `view.el'.
9729
9730;;;###autoload
9731(defun diredp-mouse-ediff (event) ; Not bound
9732 "Compare this file (pointed by mouse) with file FILE2 using `ediff'.
9733FILE2 defaults to this file as well. If you enter just a directory
9734name for FILE2, then this file is compared with a file of the same
9735name in that directory. FILE2 is the second file given to `ediff';
9736this file is the first given to it."
9737 (interactive "e")
9738 (require 'ediff)
9739 (let ((mouse-pos (event-start event)))
9740 (select-window (posn-window mouse-pos))
9741 (goto-char (posn-point mouse-pos))
9742 (call-interactively 'diredp-ediff)))
9743
9744;;;###autoload
9745(defun diredp-mouse-diff (event &optional switches) ; Not bound
9746 "Compare this file (pointed by mouse) with file FILE2 using `diff'.
9747FILE2 defaults to the file at the mark. This file is the first file
9748given to `diff'. With prefix arg, prompt for second arg SWITCHES,
9749which are options for `diff'."
9750 (interactive "e")
9751 (let ((default (and (mark t) (save-excursion (goto-char (mark t))
9752 (dired-get-filename t t))))
9753 (mouse-pos (event-start event)))
9754 (require 'diff)
9755 (select-window (posn-window mouse-pos))
9756 (goto-char (posn-point mouse-pos))
9757 (let ((file2 (read-file-name (format "Diff %s with: %s"
9758 (dired-get-filename t)
9759 (if default (concat "(default " default ") ") ""))
9760 (dired-current-directory) default t)))
9761 (setq switches (and current-prefix-arg
9762 (if (fboundp 'icicle-read-string-completing) ; In `icicles-fn.el'
9763 (icicle-read-string-completing "Options for diff: "
9764 (if (stringp diff-switches)
9765 diff-switches
9766 (mapconcat #'identity diff-switches " "))
9767 (lambda (c)
9768 (diredp-string-match-p "switches"
9769 (symbol-name c))))
9770 (read-string "Options for diff: " (if (stringp diff-switches)
9771 diff-switches
9772 (mapconcat #'identity diff-switches " "))))))
9773 (diff file2 (dired-get-filename t) switches))))
9774
9775;;;###autoload
9776(defun diredp-mouse-backup-diff (event) ; Not bound
9777 "Diff this file with its backup file or vice versa.
9778Use the latest backup, if there are several numerical backups.
9779If this file is a backup, diff it with its original.
9780The backup file is the first file given to `diff'.
9781With prefix arg, prompt for SWITCHES which are the options for `diff'."
9782 (interactive "e")
9783 (let ((switches (and current-prefix-arg
9784 (if (fboundp 'icicle-read-string-completing) ; In `icicles-fn.el'
9785 (icicle-read-string-completing "Options for diff: "
9786 (if (stringp diff-switches)
9787 diff-switches
9788 (mapconcat #'identity diff-switches " "))
9789 (lambda (c)
9790 (diredp-string-match-p "switches"
9791 (symbol-name c))))
9792 (read-string "Options for diff: " (if (stringp diff-switches)
9793 diff-switches
9794 (mapconcat #'identity diff-switches " "))))))
9795 (mouse-pos (event-start event)))
9796 (select-window (posn-window mouse-pos))
9797 (goto-char (posn-point mouse-pos))
9798 (diff-backup (dired-get-filename) switches)))
9799
9800;;;###autoload
9801(defun diredp-mouse-mark (event) ; Not bound
9802 "In Dired, mark this file.
9803If on a subdir headerline, mark all its files except `.' and `..'.
9804
9805Use \\[dired-unmark-all-files] to remove all marks,
9806and \\[dired-unmark] on a subdir to remove the marks in this subdir."
9807 (interactive "e")
9808 (let ((mouse-pos (event-start event)))
9809 (select-window (posn-window mouse-pos))
9810 (goto-char (posn-point mouse-pos)))
9811 (if (and (cdr dired-subdir-alist) (dired-get-subdir))
9812 (save-excursion (dired-mark-subdir-files))
9813 (let ((buffer-read-only nil))
9814 (dired-repeat-over-lines 1 #'(lambda () (delete-char 1) (insert dired-marker-char)))
9815 (diredp-previous-line 1))))
9816
9817;;;###autoload
9818(defun diredp-mouse-unmark (event) ; Not bound
9819 "In Dired, unmark this file.
9820If looking at a subdir, unmark all its files except `.' and `..'."
9821 (interactive "e")
9822 (let ((mouse-pos (event-start event)))
9823 (select-window (posn-window mouse-pos))
9824 (goto-char (posn-point mouse-pos)))
9825 (let ((dired-marker-char ?\040)) (dired-mark nil))
9826 (diredp-previous-line 1))
9827
9828;;; This can be bound to [C-down-mouse-1] to give behavior similar to Windows Explorer.
9829;;; However, Emacs generally uses [C-down-mouse-1] for `mouse-buffer-menu'.
9830;;;###autoload
9831(defun diredp-mouse-mark/unmark (event) ; Not bound
9832 "Mark/unmark file or directory at mouse EVENT."
9833 (interactive "e")
9834 (let* ((mouse-pos (event-start event))
9835 (inhibit-field-text-motion t) ; Just in case.
9836 (file/dir-name (with-current-buffer (window-buffer (posn-window mouse-pos))
9837 (save-excursion
9838 (goto-char (posn-point mouse-pos))
9839 (and (not (eobp)) (dired-get-filename nil t))))))
9840 ;; Return nil iff not on a file or directory name.
9841 (and file/dir-name (cond ((dired-file-marker file/dir-name)
9842 (diredp-mouse-unmark event)
9843 (message "Unmarked: %s" file/dir-name))
9844 (t
9845 (diredp-mouse-mark event)
9846 (message "Marked: %s" file/dir-name))))))
9847
9848;; This can be bound to [S-mouse-1] to give behavior similar to Windows Explorer.
9849;; If you do that, consider binding `diredp-mouse-mark/unmark' to `C-mouse-1'.
9850;; Alternatively, just bind `diredp-mouse-mark/unmark-mark-region-files' to [S-mouse-1].
9851;;;###autoload
9852(defun diredp-mouse-mark-region-files (event) ; Bound to `S-mouse-1'
9853 "Mark files between point and the mouse."
9854 (interactive "e")
9855 (call-interactively 'mouse-save-then-kill)
9856 (diredp-mark-region-files))
9857
9858;; This can be bound to [S-mouse-1] to give behavior similar to Windows Explorer.
9859;; If you don't bind `diredp-mouse-mark/unmark' to, for instance, `C-mouse-1', then
9860;; Consider binding this to [S-mouse-1].
9861;;;###autoload
9862(defun diredp-mouse-mark/unmark-mark-region-files (event) ; Not bound
9863 "Mark/unmark file or mark files in region.
9864If the file the cursor is on is marked, then mark all files between it
9865 and the line clicked (included).
9866Otherwise (cursor's file is unmarked):
9867 If the file clicked is marked, then unmark it.
9868 If it is unmarked, then mark it."
9869 (interactive "e")
9870 (let ((mouse-pos (event-start event)))
9871 ;; If same click same line as cursor, or cursor's line is marked,
9872 ;; Then toggle the clicked line's mark.
9873 ;; Else mark all files in region between point and clicked line (included).
9874 (if (or (eq (count-lines (point-min) (posn-point mouse-pos))
9875 (count-lines (point-min) (point)))
9876 (equal dired-marker-char (dired-file-marker (dired-get-filename nil t))))
9877 (diredp-mouse-mark/unmark event)
9878 (call-interactively 'mouse-save-then-kill)
9879 (diredp-mark-region-files))))
9880
9881;;;###autoload
9882(defun diredp-mouse-flag-file-deletion (event) ; Not bound
9883 "In Dired, flag this file for deletion.
9884If on a subdir headerline, mark all its files except `.' and `..'."
9885 (interactive "e")
9886 (let ((mouse-pos (event-start event)))
9887 (select-window (posn-window mouse-pos))
9888 (goto-char (posn-point mouse-pos)))
9889 (let ((dired-marker-char dired-del-marker)) (dired-mark 1))
9890 (diredp-previous-line 1))
9891
9892;;;###autoload
9893(defun diredp-mouse-do-copy (event) ; Not bound
9894 "In Dired, copy this file.
9895This normally preserves the last-modified date when copying."
9896 (interactive "e")
9897 (let ((mouse-pos (event-start event)))
9898 (select-window (posn-window mouse-pos))
9899 (goto-char (posn-point mouse-pos)))
9900 (dired-do-create-files 'copy #'dired-copy-file (if dired-copy-preserve-time "Copy [-p]" "Copy")
9901 1 dired-keep-marker-copy))
9902
9903;;;###autoload
9904(defun diredp-mouse-do-rename (event) ; Not bound
9905 "In Dired, rename this file."
9906 (interactive "e")
9907 (let ((mouse-pos (event-start event)))
9908 (select-window (posn-window mouse-pos))
9909 (goto-char (posn-point mouse-pos)))
9910 (dired-do-create-files 'move #'dired-rename-file "Move" 1 dired-keep-marker-rename "Rename"))
9911
9912;;;###autoload
9913(defun diredp-mouse-upcase (event) ; Not bound
9914 "In Dired, rename this file to upper case."
9915 (interactive "e")
9916 (let ((mouse-pos (event-start event)))
9917 (select-window (posn-window mouse-pos))
9918 (goto-char (posn-point mouse-pos)))
9919 (dired-rename-non-directory #'upcase "Rename to uppercase:" nil))
9920
9921;;;###autoload
9922(defun diredp-mouse-downcase (event) ; Not bound
9923 "In Dired, rename this file to lower case."
9924 (interactive "e")
9925 (let ((mouse-pos (event-start event)))
9926 (select-window (posn-window mouse-pos))
9927 (goto-char (posn-point mouse-pos)))
9928 (dired-rename-non-directory #'downcase "Rename to lowercase:" nil))
9929
9930;;;###autoload
9931(defun diredp-mouse-do-delete (event) ; Not bound
9932 "In Dired, delete this file, upon confirmation."
9933 (interactive "e")
9934 (let ((mouse-pos (event-start event)))
9935 (select-window (posn-window mouse-pos))
9936 (goto-char (posn-point mouse-pos)))
9937 (diredp-internal-do-deletions (dired-map-over-marks (cons (dired-get-filename) (point)) 1)
9938 1
9939 'USE-TRASH-CAN) ; This arg is for Emacs 24+ only.
9940 (diredp-previous-line 1))
9941
9942;;;###autoload
9943(defun diredp-mouse-do-shell-command (event) ; Not bound
9944 "Run a shell COMMAND on this file.
9945If there is output, it goes to a separate buffer.
9946
9947No automatic redisplay of Dired buffers is attempted, as there's no
9948telling what files the command may have changed. Type
9949\\[dired-do-redisplay] to redisplay.
9950
9951The shell command has the top level directory as working directory, so
9952output files usually are created there instead of in a subdir."
9953 ;;Functions dired-run-shell-command and dired-shell-stuff-it do the
9954 ;;actual work and can be redefined for customization.
9955 (interactive "e")
9956 (lexical-let ((mouse-pos (event-start event))
9957 (command (dired-read-shell-command "! on %s: " nil (dired-get-marked-files t nil))))
9958 (select-window (posn-window mouse-pos))
9959 (goto-char (posn-point mouse-pos))
9960 (dired-bunch-files (- 10000 (length command))
9961 (lambda (&rest files) (dired-run-shell-command (dired-shell-stuff-it command files t 1)))
9962 nil
9963 (dired-get-marked-files t 1))))
9964
9965;;;###autoload
9966(defun diredp-mouse-do-symlink (event) ; Not bound
9967 "Make symbolic link to this file."
9968 (interactive "e")
9969 (let ((mouse-pos (event-start event)))
9970 (select-window (posn-window mouse-pos))
9971 (goto-char (posn-point mouse-pos)))
9972 (dired-do-create-files 'symlink #'make-symbolic-link "Symlink" 1 dired-keep-marker-symlink))
9973
9974;;;###autoload
9975(defun diredp-mouse-do-hardlink (event) ; Not bound
9976 "Make hard link (alias) to this file."
9977 (interactive "e")
9978 (let ((mouse-pos (event-start event)))
9979 (select-window (posn-window mouse-pos))
9980 (goto-char (posn-point mouse-pos)))
9981 (dired-do-create-files 'hardlink #'add-name-to-file "Hardlink" 1 dired-keep-marker-hardlink))
9982
9983;;;###autoload
9984(defun diredp-mouse-do-print (event) ; Not bound
9985 "Print this file.
9986Uses the shell command coming from variables `lpr-command' and
9987`lpr-switches' as default."
9988 (interactive "e")
9989 (let ((mouse-pos (event-start event)))
9990 (select-window (posn-window mouse-pos))
9991 (goto-char (posn-point mouse-pos)))
9992 (let* ((file (dired-get-filename))
9993 (command (dired-mark-read-string "Print %s with: "
9994 (apply 'concat lpr-command " " lpr-switches)
9995 'print 1 (list file))))
9996 (dired-run-shell-command (dired-shell-stuff-it command (list file) nil))))
9997
9998;;;###autoload
9999(defun diredp-mouse-do-grep (event) ; Not bound
10000 "Run grep against this file."
10001 (interactive "e")
10002 (let ((mouse-pos (event-start event)))
10003 (select-window (posn-window mouse-pos))
10004 (goto-char (posn-point mouse-pos)))
10005 (unless grep-command (grep-compute-defaults))
10006 (grep (diredp-do-grep-1 (list (dired-get-filename t)))))
10007
10008;;;###autoload
10009(defun diredp-mouse-do-compress (event) ; Not bound
10010 "Compress or uncompress this file."
10011 (interactive "e")
10012 (let ((mouse-pos (event-start event))
10013 (dired-no-confirm t))
10014 (select-window (posn-window mouse-pos))
10015 (goto-char (posn-point mouse-pos))
10016 (dired-map-over-marks-check #'dired-compress 1 'compress t))
10017 (diredp-previous-line 1))
10018
10019;;;###autoload
10020(defun diredp-mouse-do-byte-compile (event) ; Not bound
10021 "Byte compile this file."
10022 (interactive "e")
10023 (let ((mouse-pos (event-start event))
10024 (dired-no-confirm t))
10025 (select-window (posn-window mouse-pos))
10026 (goto-char (posn-point mouse-pos))
10027 (dired-map-over-marks-check #'dired-byte-compile 1 'byte-compile t))
10028 (diredp-previous-line 1))
10029
10030;;;###autoload
10031(defun diredp-mouse-do-load (event) ; Not bound
10032 "Load this Emacs Lisp file."
10033 (interactive "e")
10034 (let ((mouse-pos (event-start event))
10035 (dired-no-confirm t))
10036 (select-window (posn-window mouse-pos))
10037 (goto-char (posn-point mouse-pos))
10038 (dired-map-over-marks-check #'dired-load 1 'load t))
10039 (diredp-previous-line 1))
10040
10041;;;###autoload
10042(defun diredp-mouse-do-chmod (event) ; Not bound
10043 "Change the mode of this file.
10044This calls chmod, so symbolic modes like `g+w' are allowed."
10045 (interactive "e")
10046 (let ((mouse-pos (event-start event)))
10047 (select-window (posn-window mouse-pos))
10048 (goto-char (posn-point mouse-pos)))
10049 (dired-do-chxxx "Mode" "chmod" 'chmod 1)
10050 (diredp-previous-line 1))
10051
10052(unless (memq system-type '(windows-nt ms-dos))
10053 (defun diredp-mouse-do-chgrp (event) ; Not bound
10054 "Change the group of this file."
10055 (interactive "e")
10056 (let ((mouse-pos (event-start event)))
10057 (select-window (posn-window mouse-pos))
10058 (goto-char (posn-point mouse-pos)))
10059 (dired-do-chxxx "Group" "chgrp" 'chgrp 1)
10060 (diredp-previous-line 1)))
10061
10062(unless (memq system-type '(windows-nt ms-dos))
10063 (defun diredp-mouse-do-chown (event) ; Not bound
10064 "Change the owner of this file."
10065 (interactive "e")
10066 (let ((mouse-pos (event-start event)))
10067 (select-window (posn-window mouse-pos))
10068 (goto-char (posn-point mouse-pos)))
10069 (dired-do-chxxx "Owner" dired-chown-program 'chown 1)
10070 (diredp-previous-line 1)))
10071
10072
10073;;; Breadcrumbs
10074
10075(when (fboundp 'define-minor-mode)
10076
10077 ;; Macro `define-minor-mode' is not defined in Emacs 20, so in order to be able to byte-compile
10078 ;; this file in Emacs 20, prohibit byte-compiling of the `define-minor-mode' call.
10079 ;;
10080 (eval '(define-minor-mode diredp-breadcrumbs-in-header-line-mode
10081 "Toggle the use of breadcrumbs in Dired header line.
10082With arg, show breadcrumbs iff arg is positive."
10083 :init-value nil :group 'header-line :group 'Dired-Plus
10084 (unless (derived-mode-p 'dired-mode)
10085 (error "You must be in Dired or a mode derived from it to use this command"))
10086 (if diredp-breadcrumbs-in-header-line-mode
10087 (diredp-set-header-line-breadcrumbs)
10088 (setq header-line-format (default-value 'header-line-format)))))
10089
10090 (defun diredp-set-header-line-breadcrumbs ()
10091 "Show a header line with breadcrumbs to parent directories."
10092 (let ((parent (diredp-parent-dir default-directory))
10093 (dirs ())
10094 (text ""))
10095 (while parent
10096 (push parent dirs)
10097 (setq parent (diredp-parent-dir parent)))
10098 (dolist (dir dirs)
10099 (let* ((crumbs-map (make-sparse-keymap))
10100 (menu-map (make-sparse-keymap "Breadcrumbs in Header Line"))
10101 ;; The next three are for showing the root as absolute and the rest as relative.
10102 (rootp (diredp-root-directory-p dir))
10103 (parent-rootp (and (not rootp) (diredp-root-directory-p (diredp-parent-dir dir))))
10104 (rdir dir))
10105 ;; (define-key crumbs-map [header-line mouse-3] menu-map)
10106 (unless rootp (setq rdir (file-name-nondirectory (directory-file-name dir))))
10107 (when dir
10108 (setq rdir (propertize rdir
10109 'local-map (progn (define-key crumbs-map [header-line mouse-1]
10110 `(lambda () (interactive)
10111 (dired ,dir dired-actual-switches)))
10112 (define-key crumbs-map [header-line mouse-2]
10113 `(lambda () (interactive)
10114 (dired-other-window ,dir dired-actual-switches)))
10115 crumbs-map)
10116 'mouse-face 'mode-line-highlight
10117 ;;'help-echo "mouse-1: Dired; mouse-2: Dired in other window; mouse-3: Menu"))
10118 'help-echo "mouse-1: Dired; mouse-2: Dired in other window"))
10119 (setq text (concat text (if (or rootp parent-rootp) " " " / ") rdir)))))
10120 (make-local-variable 'header-line-format)
10121 (setq header-line-format text)))
10122
10123 ;; Users can do this.
10124 ;;
10125 ;; (add-hook 'dired-before-readin-hook 'diredp-breadcrumbs-in-header-line-mode)
10126
10127 )
10128
10129
10130;;; `Dired+' Help
10131
10132;;;###autoload
10133(defun diredp-describe-mode (&optional buffer)
10134 "Describe Dired mode, including Dired+ features.
10135This is `describe-mode' plus a description of Dired+ features.
10136For just the latter, use \\<dired-mode-map>`\\[diredp-dired-plus-help]'."
10137 (interactive "@")
10138 (unless (derived-mode-p 'dired-mode)
10139 (error "Use `diredp-dired-plus-help' if you want information about Dired+"))
10140 (with-current-buffer (or buffer (current-buffer)) (describe-mode))
10141 (with-current-buffer (get-buffer-create "*Help*")
10142 (save-excursion
10143 (goto-char (point-min))
10144 (diredp-dired-plus-help-link)
10145 (let ((buffer-read-only nil)) (insert "\n"))
10146 (when (re-search-forward "Keybindings:\nkey\\s-+binding\n---\\s-+-------" nil t)
10147 (goto-char (match-beginning 0))
10148 (let ((buffer-read-only nil))
10149 (insert "\f\n")
10150 (diredp-dired-plus-description+links)
10151 (insert "\f\n"))))))
10152
10153;;;###autoload
10154(defun diredp-dired-plus-help ()
10155 "Describe Dired+."
10156 (interactive "@")
10157 (diredp-with-help-window "*Help*" (diredp-dired-plus-description+links)))
10158
10159(defun diredp-dired-plus-description+links ()
10160 "Insert Dired+ help text in `*Help*'."
10161 (with-current-buffer (get-buffer-create "*Help*")
10162 (let ((buffer-read-only nil))
10163 (save-restriction
10164 (narrow-to-region (point) (point))
10165 (diredp-dired-plus-help-link)
10166 (insert (diredp-dired-plus-description))
10167 (goto-char (point-max))
10168 (insert "\n")
10169 (diredp-dired-plus-help-link)))))
10170
10171(when (and (> emacs-major-version 21)
10172 (require 'help-mode nil t)
10173 (get 'help-xref 'button-category-symbol)) ; `button.el'
10174 (define-button-type 'diredp-help-button
10175 :supertype 'help-xref
10176 'help-function #'(lambda () (browse-url "https://www.emacswiki.org/emacs/DiredPlus"))
10177 'help-echo
10178 (purecopy "mouse-2, RET: Dired+ documentation on the Emacs Wiki (requires \
10179Internet access)")))
10180
10181(defun diredp-dired-plus-help-link ()
10182 "Add Web link for Dired+ help, and reminder about sending bug report."
10183 ;; Don't bother to do this for Emacs 21.3. Its `help-insert-xref-button' is different.
10184 (when (and (> emacs-major-version 21)
10185 (require 'help-mode nil t)
10186 (fboundp 'help-insert-xref-button)) ; `help-mode.el'.
10187 (let ((buffer-read-only nil))
10188 (help-insert-xref-button "[Dired+ Help on the Web]" 'diredp-help-button)
10189 (insert (substitute-command-keys
10190 "\t\tSend a Dired+ bug report:\n\t\t\t\t\t`\\[diredp-send-bug-report]'\n")))))
10191
10192(defun diredp-dired-plus-description ()
10193 "Dired+ description."
10194 (substitute-command-keys
10195 (concat
10196 "\\<dired-mode-map>\
10197 Dired+ Features
10198 ---------------
10199
10200To see or customize the Dired+ options or faces, use
10201`M-x customize-option diredp TAB' or `M-x customize-face diredp TAB'.
10202
10203Most keys listed here are in addition to those for vanilla Dired.
10204
10205Menus
10206-----
10207
10208Many Dired+ actions are available from the menu-bar menus and the
10209`mouse-3' context menu. This may include commands shown here as not
10210being bound to keys (i.e., listed as `M-x ...').
10211
10212General Here
10213------------
10214
10215"
10216 (and (fboundp 'diredp-w32-drives)
10217 " \\[diredp-w32-drives]\t\t- Go up to a list of MS Windows drives
10218")
10219 (and (fboundp 'dired-hide-details-mode)
10220 " \\[dired-hide-details-mode]\t\t- Hide/show details
10221")
10222
10223 " \\[revert-buffer]\t\t- Refresh (sync and show all)
10224 \\[diredp-toggle-find-file-reuse-dir]\t- Toggle reusing directories
10225"
10226 " \\[diredp-marked-other-window]\t\t- Open Dired on marked files here
10227 \\[diredp-dired-inserted-subdirs]\t\t- Dired separately each subdir inserted here
10228"
10229 (and (featurep 'bookmark+)
10230 " \\[diredp-highlight-autofiles-mode]\t- Toggle autofile highlighting
10231
10232")
10233
10234 "General Globally
10235----------------
10236
10237\\<global-map>\
10238 \\[diredp-add-to-dired-buffer]\t- Add files to a Dired buffer
10239 \\[diredp-fileset]\t- Open Dired on files in a fileset
10240 \\[diredp-dired-recent-dirs]\t- Open Dired on recently used dirs
10241 \\[diredp-dired-union]\t- Create union of some Dired buffers
10242 \\[diredp-dired-for-files]\t- Open Dired on files located anywhere
10243\\<dired-mode-map>\
10244
10245Mouse
10246-----
10247
10248 \\[diredp-mouse-3-menu]\t- Context-sensitive menu
10249"
10250
10251 (and (where-is-internal 'diredp-mouse-describe-file dired-mode-map)
10252 " \\[diredp-mouse-describe-file]\t- Describe file
10253")
10254
10255 (and (where-is-internal 'diredp-mouse-describe-autofile dired-mode-map)
10256 " \\[diredp-mouse-describe-autofile]\t- Describe autofile
10257")
10258
10259 " \\[diredp-mouse-mark-region-files]\t\t- Mark all in region
10260"
10261
10262 (and (fboundp 'dired-mouse-w32-browser) ; In `w32-browser.el'.
10263 (where-is-internal 'dired-mouse-w32-browser dired-mode-map)
10264 " \\[dired-mouse-w32-browser]\t\t- MS Windows `Open' action
10265")
10266 (and (fboundp 'dired-mouse-w32-browser-reuse-dir-buffer) ; In `w32-browser.el'.
10267 (where-is-internal 'dired-mouse-w32-browser-reuse-dir-buffer dired-mode-map)
10268 " \\[dired-mouse-w32-browser-reuse-dir-buffer]\t- MS Windows `Open' action
10269")
10270
10271 (and (where-is-internal 'dired-mouse-find-file dired-mode-map)
10272 " \\[dired-mouse-find-file]\t- Open in this window
10273")
10274 (and (where-is-internal 'diredp-mouse-find-file-reuse-dir-buffer dired-mode-map)
10275 " \\[diredp-mouse-find-file-reuse-dir-buffer]\t- Open in this window
10276")
10277
10278 (and (where-is-internal 'dired-mouse-find-file-other-window dired-mode-map)
10279 " \\[dired-mouse-find-file-other-window]\t\t- Open in another window
10280")
10281
10282 " \\[diredp-mouse-find-file-other-frame]\t\t- Open in another frame
10283"
10284
10285 "
10286Marking
10287-------
10288
10289 \\[dired-mark]\t\t- Mark this file/dir
10290 \\[dired-unmark]\t\t- Unmark this file/dir
10291 \\[dired-toggle-marks]\t\t- Toggle marked/unmarked
10292 \\[dired-mark-sexp]\t\t- Mark all satisfying a predicate
10293 \\[dired-unmark-all-marks]\t\t- Unmark all
10294 \\[diredp-mark/unmark-extension]\t\t- Mark/unmark all that have a given extension
10295"
10296
10297 (and (fboundp 'dired-mark-omitted) ; In `dired-x.el'
10298 " \\[dired-mark-omitted]\t\t- Mark omitted
10299")
10300
10301 " \\[diredp-mark-files-tagged-regexp]\t\t- Mark those with a tag that matches a regexp
10302 \\[diredp-unmark-files-tagged-regexp]\t\t- Unmark those with a tag that matches a regexp
10303 \\[diredp-mark-files-tagged-all]\t\t- Mark those with all of the given tags
10304 \\[diredp-unmark-files-tagged-all]\t\t- Unmark those with all of the given tags
10305 \\[diredp-mark-files-tagged-some]\t\t- Mark those with some of the given tags
10306 \\[diredp-unmark-files-tagged-some]\t\t- Unmark those with some of the given tags
10307 \\[diredp-mark-files-tagged-not-all]\t- Mark those without some of the given tags
10308 \\[diredp-unmark-files-tagged-not-all]\t- Unmark those without some of the given tags
10309 \\[diredp-mark-files-tagged-none]\t- Mark those with none of the given tags
10310 \\[diredp-unmark-files-tagged-none]\t- Unmark those with none of the given tags
10311"
10312
10313 "
10314Current file/subdir (current line)
10315----------------------------------
10316
10317 \\[diredp-describe-file]\t- Describe
10318 \\[dired-find-file]\t\t- Open
10319"
10320 (and (fboundp 'dired-mouse-w32-browser) ; In `w32-browser.el'.
10321 (where-is-internal 'dired-mouse-w32-browser dired-mode-map)
10322 " \\[dired-mouse-w32-browser]\t- MS Windows `Open' action
10323 \\[dired-w32explore]\t- MS Windows Explorer
10324")
10325
10326 " \\[diredp-byte-compile-this-file]\t\t- Byte-compile
10327 \\[diredp-compress-this-file]\t\t- Compress/uncompress
10328 \\[diredp-print-this-file]\t\t- Print
10329 \\[diredp-relsymlink-this-file]\t\t- Create relative symlink
10330 \\[diredp-delete-this-file]\t\t- Delete (with confirmation)
10331 \\[diredp-rename-this-file]\t\t- Rename
10332 \\[diredp-capitalize-this-file]\t\t- Capitalize (rename)
10333 \\[diredp-upcase-this-file]\t\t- Rename to uppercase
10334 \\[diredp-downcase-this-file]\t\t- Rename to lowercase
10335 \\[diredp-ediff]\t\t- Ediff
10336 \\[diredp-bookmark-this-file]\t\t- Bookmark
10337"
10338 (and (featurep 'bookmark+)
10339 " \\[diredp-tag-this-file]\t\t- Add some tags to this file/dir
10340 \\[diredp-untag-this-file]\t\t- Remove some tags from this file/dir
10341 \\[diredp-remove-all-tags-this-file]\t\t- Remove all tags from this file/dir
10342 \\[diredp-copy-tags-this-file]\t\t- Copy the tags from this file/dir
10343 \\[diredp-paste-add-tags-this-file]\t\t- Paste (add) copied tags to this file/dir
10344 \\[diredp-paste-replace-tags-this-file]\t\t- Paste (replace) tags for this file/dir
10345 \\[diredp-set-tag-value-this-file]\t\t- Set a tag value for this file/dir
10346")
10347
10348 (and (fboundp 'dired-mouse-w32-browser-reuse-dir-buffer) ; In `w32-browser.el'.
10349 (where-is-internal 'dired-mouse-w32-browser-reuse-dir-buffer dired-mode-map)
10350 " \\[dired-mouse-w32-browser-reuse-dir-buffer]\t- MS Windows `Open' action
10351 \\[dired-w32explore]\t- MS Windows Explorer
10352")
10353
10354 "
10355Marked (or next prefix arg) files & subdirs here
10356------------------------------------------------
10357"
10358 (and (fboundp 'dired-multiple-w32-browser) ; In `w32-browser.el'.
10359 "
10360 \\[dired-multiple-w32-browser]\t- MS Windows `Open' action
10361")
10362
10363
10364 " \\[diredp-list-marked]\t\t- List marked files and directories
10365 \\[diredp-insert-subdirs]\t\t- Insert marked subdirectories
10366 \\[dired-copy-filename-as-kill]\t\t- Copy names for pasting
10367 \\[diredp-copy-abs-filenames-as-kill]\t\t- Copy absolute names for pasting
10368 \\[diredp-yank-files]\t\t- Paste files whose absolute names you copied
10369 \\[dired-do-find-marked-files]\t\t- Visit
10370 \\[dired-do-copy]\t\t- Copy
10371 \\[dired-do-rename]\t\t- Rename/move
10372 \\[diredp-do-grep]\t\t- Run `grep'
10373 \\[dired-do-search]\t\t- Search
10374"
10375 (and (fboundp 'dired-do-find-regexp) ; Emacs 25+
10376 " \\[dired-do-find-regexp]\t\t- Search using `find'
10377")
10378
10379 (if (fboundp 'dired-do-query-replace-regexp) ; Emacs 22+
10380 " \\[dired-do-query-replace-regexp]\t\t- Query-replace
10381"
10382 " \\[dired-do-query-replace]\t\t- Query-replace
10383")
10384
10385 (and (fboundp 'dired-do-find-regexp-and-replace)
10386 " \\[dired-do-find-regexp-and-replace]\t\t- Query-replace using `find'
10387")
10388
10389 (and (fboundp 'dired-do-isearch)
10390 " \\[dired-do-isearch]\t- Isearch
10391 \\[dired-do-isearch-regexp]\t- Regexp isearch
10392")
10393
10394 (and (fboundp 'dired-do-async-shell-command)
10395 " \\[dired-do-async-shell-command]\t\t- Run shell command asynchronously
10396")
10397
10398 " \\[dired-do-shell-command]\t\t- Run shell command
10399 \\[diredp-marked-other-window]\t\t- Dired
10400 \\[diredp-do-apply-function]\t\t- Apply Lisp function
10401 \\[dired-do-compress]\t\t- Compress
10402 \\[dired-do-byte-compile]\t\t- Byte-compile
10403 \\[dired-do-load]\t\t- Load (Emacs Lisp)
10404
10405 \\[diredp-omit-marked]\t- Omit
10406 \\[diredp-omit-unmarked]\t- Omit unmarked
10407"
10408
10409 (and (featurep 'bookmark+)
10410 "
10411 \\[diredp-do-tag]\t\t- Add some tags to marked
10412 \\[diredp-do-untag]\t\t- Remove some tags from marked
10413 \\[diredp-do-remove-all-tags]\t\t- Remove all tags from marked
10414 \\[diredp-do-paste-add-tags]\t- Paste (add) copied tags to marked
10415 \\[diredp-do-paste-replace-tags]\t\t- Paste (replace) tags for marked
10416 \\[diredp-do-set-tag-value]\t\t- Set a tag value for marked
10417 \\[diredp-mark-files-tagged-regexp]\t\t- Mark those with a tag that matches a regexp
10418 \\[diredp-mark-files-tagged-all]\t\t- Mark those with all of the given tags
10419 \\[diredp-mark-files-tagged-some]\t\t- Mark those with some of the given tags
10420 \\[diredp-mark-files-tagged-not-all]\t- Mark those without some of the given tags
10421 \\[diredp-mark-files-tagged-none]\t- Mark those with none of the given tags
10422 \\[diredp-unmark-files-tagged-regexp]\t\t- Unmark those with a tag that matches a regexp
10423 \\[diredp-unmark-files-tagged-all]\t\t- Unmark those with all of the given tags
10424 \\[diredp-unmark-files-tagged-some]\t\t- Unmark those with some of the given tags
10425 \\[diredp-unmark-files-tagged-not-all]\t- Unmark those without some of the given tags
10426 \\[diredp-unmark-files-tagged-none]\t- Unmark those with none of the given tags")
10427
10428 "
10429
10430 \\[diredp-do-bookmark]\t\t- Bookmark
10431"
10432
10433 (and (featurep 'bookmark+)
10434 " \\[diredp-set-bookmark-file-bookmark-for-marked]\t\t- \
10435Bookmark and create bookmark-file bookmark
10436 \\[diredp-do-bookmark-in-bookmark-file]\t- Bookmark in specific bookmark file
10437")
10438
10439 "
10440Here and below (in marked subdirs)
10441----------------------------------
10442"
10443 (and (fboundp 'dired-multiple-w32-browser) ; In `w32-browser.el'.
10444 "
10445 \\[diredp-multiple-w32-browser-recursive]\t- MS Windows `Open' action
10446")
10447
10448 " \\[diredp-list-marked-recursive]\t\t- List marked files and directories
10449 \\[diredp-insert-subdirs-recursive]\t\t- Insert marked subdirectories
10450 \\[diredp-copy-filename-as-kill-recursive]\t\t- Copy names for pasting
10451 \\[diredp-do-find-marked-files-recursive]\t\t\t- Visit
10452 \\[diredp-do-print-recursive]\t\t\t- Print
10453 \\[diredp-do-copy-recursive]\t\t\t- Copy
10454 \\[diredp-do-move-recursive]\t\t\t- Move
10455 \\[diredp-do-touch-recursive]\t\t- Touch (update timestamp)
10456 \\[diredp-do-chmod-recursive]\t\t\t- Change mode
10457
10458 \\[diredp-do-symlink-recursive]\t\t\t- Add symbolic links
10459 \\[diredp-do-relsymlink-recursive]\t\t\t- Add relative symbolic links
10460 \\[diredp-do-hardlink-recursive]\t\t\t- Add hard links
10461
10462 \\[diredp-capitalize-recursive]\t\t- Capitalize
10463 \\[diredp-downcase-recursive]\t\t- Downcase
10464 \\[diredp-upcase-recursive]\t\t- Upcase
10465"
10466 (and (fboundp 'epa-dired-do-encrypt) ; Emacs 23+
10467 "
10468 \\[diredp-do-encrypt-recursive]\t\t- Encrypt
10469 \\[diredp-do-decrypt-recursive]\t\t- Decrypt
10470 \\[diredp-do-sign-recursive]\t\t- Sign
10471 \\[diredp-do-verify-recursive]\t\t- Verify
10472")
10473
10474 "
10475 \\[diredp-do-grep-recursive]\t\t- `grep'
10476 \\[diredp-do-search-recursive]\t\t\t- Search
10477 \\[diredp-do-query-replace-regexp-recursive]\t\t\t- Query-replace
10478 \\[diredp-do-isearch-recursive]\t\t- Isearch
10479 \\[diredp-do-isearch-regexp-recursive]\t- Regexp isearch
10480"
10481 (and (fboundp 'diredp-do-async-shell-command-recursive) ; Emacs 23+
10482 "
10483 \\[diredp-do-async-shell-command-recursive]\t\t\t- Run shell command asynchronously
10484")
10485
10486 " \\[diredp-do-shell-command-recursive]\t\t\t- Run shell command
10487 \\[diredp-do-apply-function-recursive]\t\t\t- Apply Lisp function
10488
10489 \\[diredp-marked-recursive-other-window]\t\t- Dired
10490 \\[diredp-list-marked-recursive]\t\t- List
10491
10492 \\[diredp-image-dired-comment-files-recursive]\t\t- Add image comment
10493 \\[diredp-image-dired-display-thumbs-recursive]\t\t- Show thumbnail images
10494 \\[diredp-image-dired-tag-files-recursive]\t\t- Tag images
10495 \\[diredp-image-dired-delete-tag-recursive]\t\t- Delete image tags
10496
10497 \\[diredp-do-bookmark-recursive]\t\t- Bookmark
10498"
10499 (and (featurep 'bookmark+)
10500 " \\[diredp-do-bookmark-in-bookmark-file-recursive]\t\t- Bookmark in bookmark file
10501 \\[diredp-set-bookmark-file-bookmark-for-marked-recursive]\t\t- Create bookmark-file bookmark
10502")
10503
10504 "
10505 \\[diredp-mark-directories-recursive]\t\t- Mark directories
10506 \\[diredp-mark-executables-recursive]\t\t- Mark executables
10507 \\[diredp-mark-symlinks-recursive]\t\t- Mark symbolic links
10508 \\[diredp-mark-files-regexp-recursive]\t\t- Mark regexp matches
10509"
10510 (and (featurep 'bookmark+)
10511 " \\[diredp-mark-autofiles-recursive]\t\t- Mark autofiles
10512")
10513 " \\[diredp-flag-auto-save-files-recursive]\t\t\t- Flag auto-save
10514 \\[diredp-do-delete-recursive]\t\t\t- Delete marked (not flagged)
10515 \\[diredp-change-marks-recursive]\t\t- Change marks
10516 \\[diredp-unmark-all-files-recursive]\t\t- Remove a given mark
10517 \\[diredp-unmark-all-marks-recursive]\t\t\t- Remove all marks
10518"
10519 (and (featurep 'bookmark+)
10520"
10521
10522Tagging
10523-------
10524
10525 \\[diredp-tag-this-file]\t\t- Add some tags to this file/dir
10526 \\[diredp-untag-this-file]\t\t- Remove some tags from this file/dir
10527 \\[diredp-remove-all-tags-this-file]\t\t- Remove all tags from this file/dir
10528 \\[diredp-copy-tags-this-file]\t\t- Copy the tags from this file/dir
10529 \\[diredp-paste-add-tags-this-file]\t\t- Paste (add) copied tags to this file/dir
10530 \\[diredp-paste-replace-tags-this-file]\t\t- Paste (replace) tags for this file/dir
10531 \\[diredp-set-tag-value-this-file]\t\t- Set a tag value for this file/dir
10532 \\[diredp-do-tag]\t\t- Add some tags to marked
10533 \\[diredp-do-untag]\t\t- Remove some tags from marked
10534 \\[diredp-do-remove-all-tags]\t\t- Remove all tags from marked
10535 \\[diredp-do-paste-add-tags]\t- Paste (add) copied tags to marked
10536 \\[diredp-do-paste-replace-tags]\t\t- Paste (replace) tags for marked
10537 \\[diredp-do-set-tag-value]\t\t- Set a tag value for marked
10538 \\[diredp-mark-files-tagged-regexp]\t\t- Mark those with a tag that matches a regexp
10539 \\[diredp-mark-files-tagged-all]\t\t- Mark those with all of the given tags
10540 \\[diredp-mark-files-tagged-some]\t\t- Mark those with some of the given tags
10541 \\[diredp-mark-files-tagged-not-all]\t- Mark those without some of the given tags
10542 \\[diredp-mark-files-tagged-none]\t- Mark those with none of the given tags
10543 \\[diredp-unmark-files-tagged-regexp]\t\t- Unmark those with a tag that matches a regexp
10544 \\[diredp-unmark-files-tagged-all]\t\t- Unmark those with all of the given tags
10545 \\[diredp-unmark-files-tagged-some]\t\t- Unmark those with some of the given tags
10546 \\[diredp-unmark-files-tagged-not-all]\t- Unmark those without some of the given tags
10547 \\[diredp-unmark-files-tagged-none]\t- Unmark those with none of the given tags
10548")
10549
10550 "
10551Bookmarking
10552-----------
10553
10554 \\[diredp-bookmark-this-file]\t\t- Bookmark this file/dir
10555 \\[diredp-do-bookmark]\t\t- Bookmark marked"
10556
10557 (and (featurep 'bookmark+)
10558 "
10559 \\[diredp-set-bookmark-file-bookmark-for-marked]\t\t- \
10560Bookmark marked and create bookmark-file bookmark
10561 \\[diredp-do-bookmark-in-bookmark-file]\t- Bookmark marked, in specific bookmark file
10562")
10563
10564 " \\[diredp-do-bookmark-recursive]\t- Bookmark marked, here and below
10565"
10566 (and (featurep 'bookmark+)
10567 " \\[diredp-do-bookmark-in-bookmark-file-recursive]\t- \
10568Bookmark marked, here and below, in specific file
10569 \\[diredp-set-bookmark-file-bookmark-for-marked-recursive]\t- \
10570Set bookmark-file bookmark for marked here and below
10571")
10572
10573 )))
10574
10575(when (> emacs-major-version 21)
10576 (defun diredp-nb-marked-in-mode-name ()
10577 "Show number of marked, flagged, and current-list lines in mode-line.
10578\(Flagged means flagged for deletion.)
10579If the current line is marked/flagged and there are others
10580marked/flagged after it then show `N/M', where `N' is the number
10581marked/flagged through the current line and `M' is the total number
10582marked/flagged.
10583
10584If the current line is for a file then show `L/T', where `L' is the
10585line number in the current listing and `T' is the number of files in
10586that listing. If option `diredp-count-.-and-..-flag' is non-nil then
10587count also `.' and `..'.
10588
10589Also abbreviate `mode-name', using \"Dired/\" instead of \"Dired by\"."
10590 (let ((mname (format-mode-line mode-name)))
10591 ;; Property `dired+-mode-name' indicates whether `mode-name' has been changed.
10592 (unless (get-text-property 0 'dired+-mode-name mname)
10593 (save-match-data
10594 (setq mode-name
10595 `(,(propertize (if (string-match "^[dD]ired \\(by \\)?\\(.*\\)" mname)
10596 (format "Dired/%s" (match-string 2 mname))
10597 mname)
10598 'dired+-mode-name t)
10599 (:eval (let* ((dired-marker-char (if (eq ?D dired-marker-char)
10600 ?* ; `dired-do-flagged-delete' binds it.
10601 dired-marker-char))
10602 (marked-regexp (dired-marker-regexp))
10603 (nb-marked (count-matches marked-regexp
10604 (point-min) (point-max))))
10605 (if (not (> nb-marked 0))
10606 ""
10607 (propertize
10608 (format " %s%d%c"
10609 (save-excursion
10610 (forward-line 0)
10611 (if (diredp-looking-at-p (concat marked-regexp ".*"))
10612 (format "%d/" (1+ (count-matches
10613 marked-regexp
10614 (point-min) (point))))
10615 ""))
10616 nb-marked dired-marker-char)
10617 'face 'diredp-mode-line-marked 'dired+-mode-name t))))
10618 (:eval (let* ((flagged-regexp (let ((dired-marker-char dired-del-marker))
10619 (dired-marker-regexp)))
10620 (nb-flagged (count-matches flagged-regexp
10621 (point-min) (point-max))))
10622 (if (not (> nb-flagged 0))
10623 ""
10624 (propertize
10625 (format " %s%dD"
10626 (save-excursion
10627 (forward-line 0)
10628 (if (diredp-looking-at-p (concat flagged-regexp ".*"))
10629 (format "%d/" (1+ (count-matches
10630 flagged-regexp
10631 (point-min) (point))))
10632 ""))
10633 nb-flagged)
10634 'face 'diredp-mode-line-flagged))))
10635 (:eval (save-excursion
10636 (let ((this 0)
10637 (total 0)
10638 (o-pt (line-beginning-position))
10639 (e-pt (or (condition-case nil
10640 (let ((diredp-wrap-around-flag nil))
10641 (save-excursion
10642 (diredp-next-subdir 1)
10643 (line-beginning-position)))
10644 (error nil))
10645 (save-excursion (goto-char (point-max)) (line-beginning-position)))))
10646 (when dired-subdir-alist (dired-goto-subdir (dired-current-directory)))
10647 (while (and (<= (point) e-pt)
10648 (< (point) (point-max))) ; Hack to work around Emacs display-engine bug.
10649 (when (condition-case nil
10650 (dired-get-filename nil diredp-count-.-and-..-flag)
10651 (error nil))
10652 (when (<= (line-beginning-position) o-pt) (setq this (1+ this)))
10653 (setq total (1+ total)))
10654 (forward-line 1))
10655 (if (not (> this 0)) (format " %d" total) (format " %d/%d" this total)))))))))))
10656
10657 (add-hook 'dired-after-readin-hook 'diredp-nb-marked-in-mode-name)
10658 ;; This one is needed for `find-dired', because it does not call `dired-readin'.
10659 (add-hook 'dired-mode-hook 'diredp-nb-marked-in-mode-name))
10660
10661;;;###autoload
10662(defun diredp-send-bug-report ()
10663 "Send a bug report about a Dired+ problem."
10664 (interactive)
10665 (browse-url (format (concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\
10666Dired+ bug: \
10667&body=Describe bug below, using a precise recipe that starts with `emacs -Q' or `emacs -q'. \
10668File `dired+.el' has a header `Update #' that you can use to identify it.\
10669%%0A%%0AEmacs version: %s.")
10670 (emacs-version))))
10671
10672(defun diredp-visit-ignore-regexp () ; Taken from `image-file-name-regexp'.
10673 "Return a regular expression matching file names to skip.
10674This is used by `dired-visit-(next|previous)'."
10675 (let ((exts-regexp (and diredp-visit-ignore-extensions
10676 (concat "\\." (regexp-opt (nconc (mapcar #'upcase diredp-visit-ignore-extensions)
10677 diredp-visit-ignore-extensions)
10678 t)
10679 "\\'"))))
10680 (if diredp-visit-ignore-regexps
10681 (mapconcat #'identity (if exts-regexp
10682 (cons exts-regexp diredp-visit-ignore-regexps)
10683 diredp-visit-ignore-regexps)
10684 "\\|")
10685 exts-regexp)))
10686
10687;;;###autoload
10688(defun diredp-visit-next-file (&optional arg) ; Bound to `C-down'
10689 "Move down a line and visit its file in another window.
10690With numeric prefix arg N, move down N-1 lines first.
10691
10692After moving N lines, skip any lines with file names that match either
10693`diredp-visit-ignore-extensions' or `diredp-visit-ignore-regexps'.
10694
10695Kill the last buffer visited by a `dired-visit-*' command."
10696 (interactive "p")
10697 (dired-next-line arg)
10698 (while (diredp-string-match-p (diredp-visit-ignore-regexp) (dired-get-file-for-visit))
10699 (dired-next-line 1))
10700 (diredp-visit-this-file))
10701
10702;;;###autoload
10703(defun diredp-visit-previous-file (&optional arg) ; Bound to `C-up'
10704 "Move up a line and visit its file in another window.
10705With numeric prefix arg N, move up N-1 lines first.
10706
10707After moving N lines, skip any lines with file names that match either
10708`diredp-visit-ignore-extensions' or `diredp-visit-ignore-regexps'.
10709
10710Kill the last buffer visited by a `dired-visit-*' command."
10711 (interactive "p")
10712 (dired-previous-line arg)
10713 (while (diredp-string-match-p (diredp-visit-ignore-regexp) (dired-get-file-for-visit))
10714 (dired-previous-line 1))
10715 (diredp-visit-this-file))
10716
10717;;;###autoload
10718(defun diredp-visit-this-file () ; Bound to `e' (replaces `dired-find-file' binding)
10719 "View the file on this line in another window in the same frame.
10720If it was not already shown there then kill the previous buffer
10721visited by a `dired-visit-*' command.
10722
10723If it was already shown there, and if it and Dired are the only
10724windows there, then delete its window (toggle : show/hide the file)."
10725 (interactive)
10726 (let ((file (dired-get-file-for-visit))
10727 (obuf (current-buffer))
10728 (shown nil)
10729 fwin)
10730 (unless (or (and (fboundp 'window-parent) (window-parent))
10731 (not (one-window-p 'NOMINI)))
10732 (split-window))
10733 (save-selected-window
10734 (other-window 1)
10735 (setq fwin (selected-window))
10736 (unless (or (setq shown (or (equal (current-buffer) (get-file-buffer file))
10737 (memq (current-buffer) (dired-buffers-for-dir file))))
10738 (equal obuf (current-buffer)))
10739 (kill-buffer (current-buffer))))
10740 (if shown
10741 (when (= 2 (count-windows 'NOMINI)) (delete-window fwin))
10742 (set-window-buffer fwin (find-file-noselect file)))))
10743
10744;;; Key Bindings.
10745
10746
10747;; Menu Bar.
10748;; New order is (left -> right):
10749;;
10750;; Dir Regexp Mark Multiple Single
10751
10752;; Get rid of menu bar predefined in `dired.el'.
10753(define-key dired-mode-map [menu-bar] nil)
10754;; Get rid of Edit menu bar menu to save space.
10755(define-key dired-mode-map [menu-bar edit] 'undefined)
10756
10757
10758;; `Single' menu.
10759;;
10760;; REPLACE ORIGINAL `Immediate' menu in `dired.el'.
10761;;
10762(defvar diredp-menu-bar-single-menu (make-sparse-keymap "Single"))
10763(define-key dired-mode-map [menu-bar immediate] (cons "Single" diredp-menu-bar-single-menu))
10764
10765;; We don't use `define-obsolete-variable-alias' so that byte-compilation in older Emacs
10766;; works for newer Emacs too.
10767(when (fboundp 'defvaralias) ; Emacs 22+
10768 (defvaralias 'diredp-menu-bar-immediate-menu 'diredp-menu-bar-single-menu))
10769(make-obsolete-variable 'diredp-menu-bar-immediate-menu 'diredp-menu-bar-single-menu) ; 2017-04-09
10770
10771(if (fboundp 'diredp-describe-file)
10772 (define-key diredp-menu-bar-single-menu [diredp-describe-file]
10773 '(menu-item "Describe" diredp-describe-file
10774 :help "Describe the file or directory at cursor"))
10775 (define-key diredp-menu-bar-single-menu [diredp-describe-autofile]
10776 '(menu-item "Describe" diredp-describe-autofile
10777 :help "Describe the autofile at cursor"
10778 :enable (featurep 'bookmark+))))
10779(define-key diredp-menu-bar-single-menu [separator-describe] '("--")) ; ---------------------
10780
10781(when (fboundp 'diredp-chown-this-file)
10782 (define-key diredp-menu-bar-single-menu [chown]
10783 '(menu-item "Change Owner..." diredp-chown-this-file
10784 :help "Change the owner of file at cursor")))
10785(when (fboundp 'diredp-chgrp-this-file)
10786 (define-key diredp-menu-bar-single-menu [chgrp]
10787 '(menu-item "Change Group..." diredp-chgrp-this-file
10788 :help "Change the group of file at cursor")))
10789(define-key diredp-menu-bar-single-menu [chmod]
10790 '(menu-item "Change Mode..." diredp-chmod-this-file
10791 :help "Change mode (attributes) of file at cursor"))
10792(when (fboundp 'dired-do-touch) ; Emacs 22+
10793 (define-key diredp-menu-bar-single-menu [touch]
10794 '(menu-item "Change Timestamp (`touch')..." diredp-touch-this-file
10795 :help "Change the timestamp of file at cursor, using `touch'")))
10796(define-key diredp-menu-bar-single-menu [separator-change] '("--")) ; -----------------------
10797
10798(define-key diredp-menu-bar-single-menu [load]
10799 '(menu-item "Load" diredp-load-this-file
10800 :help "Load this Emacs Lisp file"))
10801(define-key diredp-menu-bar-single-menu [compile]
10802 '(menu-item "Byte Compile" diredp-byte-compile-this-file
10803 :help "Byte-compile this Emacs Lisp file"))
10804(define-key diredp-menu-bar-single-menu [diredp-async-shell-command-this-file]
10805 '(menu-item "Asynchronous Shell Command..." diredp-async-shell-command-this-file
10806 :help "Run a shell command asynchronously on file at cursor"))
10807(define-key diredp-menu-bar-single-menu [command]
10808 '(menu-item "Shell Command..." diredp-shell-command-this-file
10809 :help "Run a shell command on file at cursor"))
10810(define-key diredp-menu-bar-single-menu [compress]
10811 '(menu-item "Compress/Uncompress" diredp-compress-this-file
10812 :help "Compress/uncompress file at cursor"))
10813(define-key diredp-menu-bar-single-menu [grep]
10814 '(menu-item "Grep..." diredp-grep-this-file :help "Grep file at cursor"))
10815(define-key diredp-menu-bar-single-menu [print]
10816 '(menu-item "Print..." diredp-print-this-file
10817 :help "Print file at cursor, supplying print command"))
10818
10819(when (fboundp 'mkhtml-dired-files) ; In `mkhtml.el'.
10820 (define-key diredp-menu-bar-single-menu [mkhtml-dired-files]
10821 '(menu-item "Create HTML" mkhtml-dired-files
10822 :help "Create an HTML file corresponding to file at cursor")))
10823(define-key diredp-menu-bar-single-menu [separator-misc] '("--")) ; -------------------------
10824
10825(define-key diredp-menu-bar-single-menu [delete]
10826 '(menu-item "Delete" diredp-delete-this-file :help "Delete file at cursor"))
10827(define-key diredp-menu-bar-single-menu [separator-delete] '("--")) ; -----------------------
10828
10829(define-key diredp-menu-bar-single-menu [backup-diff]
10830 '(menu-item "Diff with Backup" dired-backup-diff
10831 :help "Diff file at cursor with its latest backup"))
10832(define-key diredp-menu-bar-single-menu [diff]
10833 '(menu-item "Diff..." dired-diff
10834 :help "Compare file at cursor with another file using `diff'"))
10835(define-key diredp-menu-bar-single-menu [ediff]
10836 '(menu-item "Compare..." diredp-ediff :help "Compare file at cursor with another file"))
10837(define-key diredp-menu-bar-single-menu [separator-diff] '("--")) ; -------------------------
10838
10839(define-key diredp-menu-bar-single-menu [diredp-kill-this-tree]
10840 '(menu-item "Remove This Inserted Subdir and Lower" diredp-kill-this-tree
10841 :visible (and (fboundp 'diredp-kill-this-tree)
10842 (not (equal
10843 (expand-file-name (dired-current-directory))
10844 (expand-file-name default-directory)))))) ; In subdir, not top.
10845(define-key diredp-menu-bar-single-menu [dired-kill-subdir]
10846 '(menu-item "Remove This Inserted Subdir" dired-kill-subdir
10847 :visible (not (equal (expand-file-name (dired-current-directory))
10848 (expand-file-name default-directory))))) ; In subdir, not top.
10849(define-key diredp-menu-bar-single-menu [diredp-dired-this-subdir]
10850 '(menu-item "Dired This Inserted Subdir (Tear Off)"
10851 (lambda () (interactive) (diredp-dired-this-subdir t))
10852 :visible (and (cdr dired-subdir-alist) ; First is current dir. Must have at least one more.
10853 (not (equal (expand-file-name (dired-current-directory))
10854 (expand-file-name default-directory)))) ; Must be sub, not top.
10855 :help "Open Dired for subdir at or above point, tearing it off if inserted"))
10856(define-key diredp-menu-bar-single-menu [insert-subdir]
10857 '(menu-item "Insert This Subdir" dired-maybe-insert-subdir
10858 :visible (and (atom (diredp-this-subdir))
10859 (not (assoc (file-name-as-directory (diredp-this-subdir)) dired-subdir-alist)))
10860 :enable (atom (diredp-this-subdir))
10861 :help "Insert a listing of this subdirectory"))
10862(define-key diredp-menu-bar-single-menu [goto-subdir]
10863 '(menu-item "Go To Inserted Subdir" dired-maybe-insert-subdir
10864 :visible (and (atom (diredp-this-subdir))
10865 (assoc (file-name-as-directory (diredp-this-subdir)) dired-subdir-alist))
10866 :enable (atom (diredp-this-subdir))
10867 :help "Go to the inserted listing of this subdirectory"))
10868(define-key diredp-menu-bar-single-menu [separator-subdir] '("--" ; ------------------------
10869 :visible (or (atom (diredp-this-subdir)) ; Subdir line.
10870 (not (equal (expand-file-name (dired-current-directory))
10871 (expand-file-name default-directory)))))) ; Not top.
10872
10873(define-key diredp-menu-bar-single-menu [view]
10874 '(menu-item "View (Read Only)" dired-view-file
10875 :help "Examine file at cursor in read-only mode"))
10876(define-key diredp-menu-bar-single-menu [display]
10877 '(menu-item "Display in Other Window" dired-display-file
10878 :help "Display file at cursor in a different window"))
10879
10880
10881;; `Single' > `Open' menu.
10882;;
10883(defvar diredp-single-open-menu (make-sparse-keymap "Rename")
10884 "`Open' submenu for Dired menu-bar `Single' menu.")
10885(define-key diredp-menu-bar-single-menu [multiple-open] (cons "Open" diredp-single-open-menu))
10886
10887;; On Windows, bind more.
10888(eval-after-load "w32-browser"
10889 '(progn
10890 (define-key diredp-single-open-menu [dired-w32-browser]
10891 '(menu-item "Open Associated Windows App" dired-w32-browser
10892 :help "Open file using the Windows app associated with its file type"))
10893 (define-key diredp-single-open-menu [dired-w32explore]
10894 '(menu-item "Open in Windows Explorer" dired-w32explore
10895 :help "Open file in Windows Explorer"))))
10896(define-key diredp-single-open-menu [find-file-other-frame]
10897 '(menu-item "Open in Other Frame" diredp-find-file-other-frame
10898 :help "Edit file at cursor in a different frame"))
10899(define-key diredp-single-open-menu [find-file-other-window]
10900 '(menu-item "Open in Other Window" dired-find-file-other-window
10901 :help "Edit file at cursor in a different window"))
10902(define-key diredp-single-open-menu [find-file]
10903 '(menu-item "Open" dired-find-file :help "Edit file at cursor"))
10904
10905
10906;; `Single' > `Rename' menu.
10907;;
10908(defvar diredp-single-rename-menu (make-sparse-keymap "Rename")
10909 "`Rename' submenu for Dired menu-bar `Single' menu.")
10910(define-key diredp-menu-bar-single-menu [multiple-case] (cons "Rename" diredp-single-rename-menu))
10911
10912(define-key diredp-single-rename-menu [single-rename-capitalize]
10913 '(menu-item "Capitalize" diredp-capitalize-this-file
10914 :help "Capitalize (initial caps) name of file at cursor"))
10915(define-key diredp-single-rename-menu [single-rename-downcase]
10916 '(menu-item "Downcase" diredp-downcase-this-file
10917 ;; When running on plain MS-DOS, there is only one letter-case for file names.
10918 :enable (or (not (fboundp 'msdos-long-file-names)) (msdos-long-file-names))
10919 :help "Rename file at cursor to a lower-case name"))
10920(define-key diredp-single-rename-menu [single-rename-upcase]
10921 '(menu-item "Upcase" diredp-upcase-this-file
10922 :enable (or (not (fboundp 'msdos-long-file-names)) (msdos-long-file-names))
10923 :help "Rename file at cursor to an upper-case name"))
10924
10925
10926;; `Single' > `Move / Copy / Link' menu.
10927;;
10928(defvar diredp-single-move-copy-link-menu (make-sparse-keymap "Move / Copy / Link")
10929 "`Move / Copy / Link' submenu for Dired menu-bar `Single' menu.")
10930(define-key diredp-menu-bar-single-menu [multiple-move-copy-link]
10931 (cons "Move / Copy / Link" diredp-single-move-copy-link-menu))
10932
10933(define-key diredp-single-move-copy-link-menu [single-hardlink]
10934 '(menu-item "Hardlink to..." diredp-hardlink-this-file
10935 :help "Make hard links for current or marked files"))
10936(if (not (fboundp 'dired-do-relsymlink))
10937 (define-key diredp-single-move-copy-link-menu [single-symlink]
10938 '(menu-item "Symlink to..." diredp-symlink-this-file
10939 :visible (fboundp 'make-symbolic-link) :help "Make symbolic link for file at cursor"))
10940 (define-key diredp-single-move-copy-link-menu [single-symlink]
10941 '(menu-item "Symlink to (Absolute)..." diredp-symlink-this-file
10942 :help "Make absolute symbolic link for file at cursor"))
10943 (define-key diredp-single-move-copy-link-menu [single-relsymlink]
10944 '(menu-item "Symlink to (Relative)..." diredp-relsymlink-this-file ; In `dired-x.el'.
10945 :help "Make relative symbolic link for file at cursor")))
10946(define-key diredp-single-move-copy-link-menu [single-copy]
10947 '(menu-item "Copy to..." diredp-copy-this-file :help "Copy file at cursor"))
10948(define-key diredp-single-move-copy-link-menu [single-rename]
10949 '(menu-item "Move to..." diredp-rename-this-file
10950 :help "Rename file at cursor, or move it to a different directory"))
10951
10952
10953;; `Single' > `Image' menu.
10954;;
10955(defvar diredp-single-image-menu (make-sparse-keymap "Image"))
10956(defalias 'diredp-single-image-menu diredp-single-image-menu)
10957(define-key diredp-menu-bar-single-menu [image]
10958 '(menu-item "Image" diredp-single-image-menu
10959 :enable (let ((img-file (diredp-get-image-filename 'LOCALP 'NO-ERROR)))
10960 (and (fboundp 'image-dired-dired-display-image) img-file))))
10961
10962(define-key diredp-single-image-menu [diredp-image-dired-display-thumb]
10963 '(menu-item "Go To Thumbnail" diredp-image-dired-display-thumb
10964 :help "Pop to buffer showing the thumbnail of this image file"))
10965(define-key diredp-single-image-menu [diredp-image-dired-create-thumb]
10966 '(menu-item "Create Thumbnail" diredp-image-dired-create-thumb
10967 :help "Create a thumbnail image for this image file"))
10968(define-key diredp-single-image-menu [diredp-image-dired-edit-comment-and-tags]
10969 '(menu-item "Edit Comment and Tags..." diredp-image-dired-edit-comment-and-tags
10970 :help "Edit comment and tags for this image file"))
10971(define-key diredp-single-image-menu [diredp-image-dired-delete-tag]
10972 '(menu-item "Delete Image Tag..." diredp-image-dired-delete-tag
10973 :help "Remove an `image-dired' tag from this image file"))
10974(define-key diredp-single-image-menu [diredp-image-dired-tag-file]
10975 '(menu-item "Add Tags..." diredp-image-dired-tag-file
10976 :help "Add tags to this image file"))
10977(define-key diredp-single-image-menu [diredp-image-dired-comment-file]
10978 '(menu-item "Add Comment..." diredp-image-dired-comment-file
10979 :help "Add a comment to this image file"))
10980(define-key diredp-single-image-menu [diredp-image-dired-copy-with-exif-name]
10981 '(menu-item "Copy with EXIF Name" diredp-image-dired-copy-with-exif-name
10982 :help "Copy this image file to main image dir using EXIF name"))
10983(define-key diredp-single-image-menu [image-dired-dired-display-external]
10984 '(menu-item "Display Externally" image-dired-dired-display-external
10985 :help "Display image using external viewer"))
10986(define-key diredp-single-image-menu [image-dired-dired-display-image]
10987 '(menu-item "Display to Fit Other Window" image-dired-dired-display-image
10988 :help "Display scaled image to fit a separate window"))
10989(define-key diredp-single-image-menu [diredp-image-show-this-file]
10990 '(menu-item "Display Full Size Or Smaller" diredp-image-show-this-file
10991 :help "Display image full size or at least prefix-arg lines high"))
10992(define-key diredp-single-image-menu [dired-find-file]
10993 '(menu-item "Display Full Size" dired-find-file
10994 :help "Display image full size"))
10995
10996
10997;; `Single' > `Encryption' menu.
10998;;
10999(when (fboundp 'epa-dired-do-encrypt) ; Emacs 23+
11000 (defvar diredp-single-encryption-menu (make-sparse-keymap "Encryption"))
11001 (define-key diredp-menu-bar-single-menu [encryption]
11002 (cons "Encryption" diredp-single-encryption-menu))
11003
11004 (define-key diredp-single-encryption-menu [diredp-decrypt-this-file]
11005 '(menu-item "Decrypt..." (lambda ()
11006 (interactive)
11007 (epa-decrypt-file (expand-file-name (dired-get-filename
11008 nil 'NO-ERROR-P))))
11009 :help "Decrypt this file"))
11010 (define-key diredp-single-encryption-menu [diredp-verify-this-file]
11011 '(menu-item "Verify..." (lambda ()
11012 (interactive)
11013 (epa-verify-file (expand-file-name (dired-get-filename
11014 nil 'NO-ERROR-P))))
11015 :help "Verify this file"))
11016 (define-key diredp-single-encryption-menu [diredp-sign-this-file]
11017 '(menu-item "Sign..." (lambda ()
11018 (interactive)
11019 (epa-sign-file (expand-file-name (dired-get-filename
11020 nil 'NO-ERROR-P))
11021 (epa-select-keys (epg-make-context)
11022 "Select keys for signing.
11023If no one is selected, default secret key is used. "
11024 nil t)))
11025 :help "Encrypt this file"))
11026 (define-key diredp-single-encryption-menu [diredp-encrypt-this-file]
11027 '(menu-item "Encrypt..." (lambda ()
11028 (interactive)
11029 (epa-encrypt-file (expand-file-name (dired-get-filename
11030 nil 'NO-ERROR-P))
11031 (epa-select-keys
11032 (epg-make-context)
11033 "Select recipients for encryption.
11034If no one is selected, symmetric encryption will be performed. "
11035 nil t)))
11036 :help "Sign this file")))
11037
11038
11039;; `Single' > `Bookmark' menu.
11040;;
11041(when (require 'bookmark+ nil t)
11042 (defvar diredp-single-bookmarks-menu (make-sparse-keymap "Bookmark"))
11043 (define-key diredp-menu-bar-single-menu [bookmark]
11044 (cons "Bookmark" diredp-single-bookmarks-menu))
11045
11046 (define-key diredp-single-bookmarks-menu [diredp-set-tag-value-this-file]
11047 '(menu-item "Set Tag Value..." diredp-set-tag-value-this-file
11048 :help "Set the value (not the name) of a given tag for this file"))
11049 (define-key diredp-single-bookmarks-menu [diredp-paste-replace-tags-this-file]
11050 '(menu-item "Paste Tags (Replace)" diredp-paste-replace-tags-this-file
11051 :help "Replace tags for this file with previously copied tags"))
11052 (define-key diredp-single-bookmarks-menu [diredp-paste-add-tags-this-file]
11053 '(menu-item "Paste Tags (Add)" diredp-paste-add-tags-this-file
11054 :help "Add previously copied tags to this file"))
11055 (define-key diredp-single-bookmarks-menu [diredp-copy-tags-this-file]
11056 '(menu-item "Copy Tags" diredp-copy-tags-this-file
11057 :help "Copy the tags from this file, so you can paste them to another"))
11058 (define-key diredp-single-bookmarks-menu [diredp-remove-all-tags-this-file]
11059 '(menu-item "Remove All Tags" diredp-remove-all-tags-this-file
11060 :help "Remove all tags from the file at cursor"))
11061 (define-key diredp-single-bookmarks-menu [diredp-untag-this-file]
11062 '(menu-item "Remove Tags..." diredp-untag-this-file
11063 :help "Remove some tags from the file at cursor (`C-u': remove all tags)"))
11064 (define-key diredp-single-bookmarks-menu [diredp-tag-this-file]
11065 '(menu-item "Add Tags..." diredp-tag-this-file :help "Add some tags to the file at cursor"))
11066 (define-key diredp-single-bookmarks-menu [diredp-bookmark-this-file]
11067 '(menu-item "Bookmark..." diredp-bookmark-this-file
11068 :help "Bookmark the file at cursor (create/set autofile)")))
11069
11070
11071;; `Multiple' menu.
11072;;
11073;; REPLACE ORIGINAL "Operate" menu in `dired.el'.
11074;;
11075(defvar diredp-menu-bar-multiple-menu (make-sparse-keymap "Multiple"))
11076(define-key dired-mode-map [menu-bar operate] (cons "Multiple" diredp-menu-bar-multiple-menu))
11077
11078;; We don't use `define-obsolete-variable-alias' so that byte-compilation in older Emacs
11079;; works for newer Emacs too.
11080(when (fboundp 'defvaralias) ; Emacs 22+
11081 (defvaralias 'diredp-menu-bar-operate-menu 'diredp-menu-bar-multiple-menu))
11082(make-obsolete-variable 'diredp-menu-bar-operate-menu 'diredp-menu-bar-multiple-menu) ; 2017-04-09
11083
11084(define-key diredp-menu-bar-multiple-menu [diredp-describe-marked-autofiles]
11085 '(menu-item "Describe Marked Autofiles" diredp-describe-marked-autofiles
11086 :help "Show the metadata for the marked files that are autofiles"
11087 :enable (featurep 'bookmark+)))
11088(define-key diredp-menu-bar-multiple-menu [separator-describe] '("--")) ; -----------------------
11089
11090(unless (memq system-type '(windows-nt ms-dos))
11091 (define-key diredp-menu-bar-multiple-menu [chown]
11092 '(menu-item "Change Owner..." dired-do-chown
11093 :help "Change the owner of marked files")))
11094(unless (memq system-type '(windows-nt ms-dos))
11095 (define-key diredp-menu-bar-multiple-menu [chgrp]
11096 '(menu-item "Change Group..." dired-do-chgrp
11097 :help "Change the owner of marked files")))
11098(define-key diredp-menu-bar-multiple-menu [chmod]
11099 '(menu-item "Change Mode..." dired-do-chmod
11100 :help "Change mode (attributes) of marked files"))
11101(when (fboundp 'dired-do-touch) ; Emacs 22+
11102 (define-key diredp-menu-bar-multiple-menu [touch]
11103 '(menu-item "Change Timestamp (`touch')..." dired-do-touch
11104 :help "Change the timestamp of the marked files, using `touch'")))
11105(define-key diredp-menu-bar-multiple-menu [separator-change] '("--")) ; -------------------------
11106
11107(define-key diredp-menu-bar-multiple-menu [load]
11108 '(menu-item "Load" dired-do-load :help "Load marked Emacs Lisp files"))
11109(define-key diredp-menu-bar-multiple-menu [compile]
11110 '(menu-item "Byte Compile" dired-do-byte-compile :help "Byte-compile marked Emacs Lisp files"))
11111(when (fboundp 'dired-do-async-shell-command) ; Emacs 23+
11112 (define-key diredp-menu-bar-multiple-menu [async-command]
11113 '(menu-item "Asynchronous Shell Command..." dired-do-async-shell-command
11114 :help "Run a shell command asynchronously on each marked file")))
11115(define-key diredp-menu-bar-multiple-menu [command]
11116 '(menu-item "Shell Command..." dired-do-shell-command
11117 :help "Run a shell command on each marked file"))
11118(when (fboundp 'dired-do-compress-to)
11119 (define-key diredp-menu-bar-multiple-menu [compress-to]
11120 '(menu-item "Compress to..." dired-do-compress-to
11121 :help "Compress marked files and dirs together, in the same archive")))
11122(define-key diredp-menu-bar-multiple-menu [compress]
11123 '(menu-item "Compress/Uncompress" dired-do-compress :help "Compress/uncompress marked files"))
11124(define-key diredp-menu-bar-multiple-menu [diredp-do-apply-function]
11125 '(menu-item "Apply Lisp Function..." diredp-do-apply-function
11126 :help "Apply a Lisp function to each marked file name (`C-u': file contents, not name)"))
11127(define-key diredp-menu-bar-multiple-menu [print]
11128 '(menu-item "Print..." dired-do-print :help "Print marked files, supplying print command"))
11129
11130(unless (require 'bookmark+ nil t)
11131 (define-key diredp-menu-bar-multiple-menu [diredp-bookmark-this-file]
11132 '(menu-item "Bookmark..." diredp-bookmark-this-file :help "Bookmark the file at cursor")))
11133(when (fboundp 'mkhtml-dired-files) ; In `mkhtml.el'.
11134 (define-key diredp-menu-bar-multiple-menu [mkhtml-dired-files]
11135 '(menu-item "Create HTML" mkhtml-dired-files
11136 :help "Create HTML files corresponding to marked files")))
11137(define-key diredp-menu-bar-multiple-menu [separator-misc] '("--")) ; ---------------------------
11138
11139(define-key diredp-menu-bar-multiple-menu [diredp-copy-abs-filenames-as-kill]
11140 '(menu-item "Copy Marked Names as Absolute" diredp-copy-abs-filenames-as-kill
11141 :help "Copy absolute names of marked files to the kill ring"
11142 :keys "M-0 w"))
11143(define-key diredp-menu-bar-multiple-menu [kill-ring]
11144 '(menu-item "Copy Marked Names" dired-copy-filename-as-kill
11145 :help "Copy names of marked files to the kill ring, for pasting"))
11146(define-key diredp-menu-bar-multiple-menu [diredp-list-marked]
11147 '(menu-item "List Marked Files" diredp-list-marked
11148 :help "List the files marked here (C-u C-u: all, C-u C-u C-u: all + dirs)"))
11149(define-key diredp-menu-bar-multiple-menu [diredp-insert-subdirs]
11150 '(menu-item "Insert Subdirs" diredp-insert-subdirs
11151 :help "Insert the marked subdirectories - like using `i' at each marked dir"))
11152;; On Windows, bind more.
11153(eval-after-load "w32-browser"
11154 '(define-key diredp-menu-bar-multiple-menu [dired-multiple-w32-browser]
11155 '(menu-item "Open Associated Windows Apps" dired-multiple-w32-browser
11156 :help "Open files using the Windows apps associated with their file types")))
11157(when (fboundp 'dired-do-find-marked-files)
11158 (define-key diredp-menu-bar-multiple-menu [find-files]
11159 '(menu-item "Open" dired-do-find-marked-files ; In `dired-x.el'.
11160 :help "Open each marked file for editing")))
11161
11162
11163;; `Multiple' > `Dired' menu.
11164;;
11165(defvar diredp-multiple-dired-menu (make-sparse-keymap "Dired")
11166 "`Dired' submenu for Dired menu-bar `Multiple' menu.")
11167(define-key diredp-menu-bar-multiple-menu [multiple-dired]
11168 `(menu-item "Dired" ,diredp-multiple-dired-menu
11169 :enable (save-excursion (goto-char (point-min))
11170 (and (re-search-forward (dired-marker-regexp) nil t)
11171 (re-search-forward (dired-marker-regexp) nil t)))
11172 :help "Open Dired on marked files and dirs only"))
11173
11174(define-key diredp-multiple-dired-menu [diredp-marked-other-window]
11175 '(menu-item "Dired Marked in Other Window" diredp-marked-other-window
11176 :enable (save-excursion (goto-char (point-min))
11177 (and (re-search-forward (dired-marker-regexp) nil t)
11178 (re-search-forward (dired-marker-regexp) nil t)))
11179 :help "Open Dired on marked files and dirs only, in other window"))
11180(define-key diredp-multiple-dired-menu [diredp-marked]
11181 '(menu-item "Dired Marked" diredp-marked
11182 :enable (save-excursion (goto-char (point-min))
11183 (and (re-search-forward (dired-marker-regexp) nil t)
11184 (re-search-forward (dired-marker-regexp) nil t)))
11185 :help "Open Dired on marked files and dirs only"))
11186
11187
11188;; `Multiple' > `Omit' menu.
11189;;
11190(defvar diredp-multiple-omit-menu (make-sparse-keymap "Omit")
11191 "`Omit' submenu for Dired menu-bar `Multiple' menu.")
11192(define-key diredp-menu-bar-multiple-menu [multiple-omit] (cons "Omit" diredp-multiple-omit-menu))
11193
11194(define-key diredp-multiple-omit-menu [omit-unmarked]
11195 '(menu-item "Omit Unmarked" diredp-omit-unmarked :help "Hide lines of unmarked files"))
11196(define-key diredp-multiple-omit-menu [omit-marked]
11197 '(menu-item "Omit Marked" diredp-omit-marked :help "Hide lines of marked files"))
11198
11199
11200;; `Multiple' > `Delete' menu.
11201;;
11202(defvar diredp-multiple-delete-menu (make-sparse-keymap "Delete")
11203 "`Delete' submenu for Dired menu-bar `Multiple' menu.")
11204(define-key diredp-menu-bar-multiple-menu [multiple-delete] (cons "Delete" diredp-multiple-delete-menu))
11205
11206(define-key diredp-multiple-delete-menu [delete-flagged]
11207 '(menu-item "Delete Flagged" dired-do-flagged-delete
11208 :help "Delete all files flagged for deletion (D)"))
11209(define-key diredp-multiple-delete-menu [delete]
11210 '(menu-item "Delete Marked (not Flagged)" dired-do-delete
11211 :help "Delete current file or all marked files (not flagged files)"))
11212
11213
11214;; `Multiple' > `Rename' menu.
11215;;
11216(defvar diredp-multiple-rename-menu (make-sparse-keymap "Rename")
11217 "`Rename' submenu for Dired menu-bar `Multiple' menu.")
11218(define-key diredp-menu-bar-multiple-menu [multiple-case] (cons "Rename" diredp-multiple-rename-menu))
11219
11220(define-key diredp-multiple-rename-menu [multiple-rename-rename]
11221 '(menu-item "Move to Dir... / Rename This..." dired-do-rename
11222 :help "Move marked (or next N) files, or rename current file"))
11223
11224(define-key diredp-multiple-rename-menu [multiple-rename-capitalize]
11225 '(menu-item "Capitalize" diredp-capitalize
11226 :help "Capitalize (initial caps) the names of all marked files"))
11227(define-key diredp-multiple-rename-menu [multiple-rename-downcase]
11228 '(menu-item "Downcase" dired-downcase
11229 :enable (or (not (fboundp 'msdos-long-file-names)) (msdos-long-file-names))
11230 :help "Rename marked files to lowercase names"))
11231(define-key diredp-multiple-rename-menu [multiple-rename-upcase]
11232 '(menu-item "Upcase" dired-upcase
11233 :enable (or (not (fboundp 'msdos-long-file-names)) (msdos-long-file-names))
11234 :help "Rename marked files to uppercase names"))
11235
11236
11237;; `Multiple' > `Move / Copy / Link' menu.
11238;;
11239(defvar diredp-multiple-move-copy-link-menu (make-sparse-keymap "Move / Copy / Link")
11240 "`Move / Copy / Link' submenu for Dired menu-bar `Multiple' menu.")
11241(define-key diredp-menu-bar-multiple-menu [multiple-move-copy-link]
11242 (cons "Move / Copy / Link" diredp-multiple-move-copy-link-menu))
11243
11244(define-key diredp-multiple-move-copy-link-menu [multiple-move-copy-link-hardlink]
11245 '(menu-item "Hardlink to..." dired-do-hardlink
11246 :help "Make hard links for current or marked files"))
11247(if (not (fboundp 'dired-do-relsymlink))
11248 (define-key diredp-multiple-move-copy-link-menu [multiple-move-copy-link-symlink]
11249 '(menu-item "Symlink to..." dired-do-symlink
11250 :visible (fboundp 'make-symbolic-link)
11251 :help "Make symbolic links for current or marked files"))
11252 (define-key diredp-multiple-move-copy-link-menu [multiple-move-copy-link-symlink]
11253 '(menu-item "Symlink to (Absolute)..." dired-do-symlink
11254 :help "Make absolute symbolic links for current or marked files"))
11255 (define-key diredp-multiple-move-copy-link-menu [multiple-move-copy-link-relsymlink] ; In `dired-x.el'.
11256 '(menu-item "Symlink to (Relative)..." dired-do-relsymlink
11257 :help "Make relative symbolic links for current or marked files")))
11258(define-key diredp-multiple-move-copy-link-menu [multiple-move-copy-link-copy]
11259 '(menu-item "Copy to..." dired-do-copy :help "Copy current file or all marked files"))
11260(define-key diredp-multiple-move-copy-link-menu [multiple-move-copy-link-rename]
11261 '(menu-item "Move to..." dired-do-rename :help "Rename current file or move marked files"))
11262
11263
11264;; `Multiple' > `Images' menu.
11265;;
11266(defvar diredp-multiple-images-menu (make-sparse-keymap "Images"))
11267(defalias 'diredp-multiple-images-menu diredp-multiple-images-menu)
11268(define-key diredp-menu-bar-multiple-menu [images]
11269 '(menu-item "Images" diredp-multiple-images-menu
11270 :enable (fboundp 'image-dired-display-thumbs)))
11271
11272;; We don't use `define-obsolete-variable-alias' so that byte-compilation in older Emacs
11273;; works for newer Emacs too.
11274(when (fboundp 'defvaralias) ; Emacs 22+
11275 (defvaralias 'diredp-menu-bar-images-menu 'diredp-multiple-images-menu))
11276(make-obsolete-variable 'diredp-menu-bar-images-menu 'diredp-multiple-images-menu) ; 2017-04-09
11277
11278;; Remove the items from `Multiple' menu.
11279(define-key diredp-menu-bar-multiple-menu [image-dired-delete-tag] nil)
11280(define-key diredp-menu-bar-multiple-menu [image-dired-tag-files] nil)
11281(define-key diredp-menu-bar-multiple-menu [image-dired-dired-comment-files] nil)
11282(define-key diredp-menu-bar-multiple-menu [image-dired-display-thumbs] nil)
11283
11284;; Add them to `Multiple' > `Images' menu.
11285(define-key diredp-multiple-images-menu [image-dired-delete-tag]
11286 '(menu-item "Delete Tag..." image-dired-delete-tag
11287 :help "Delete tag from marked image files"))
11288(define-key diredp-multiple-images-menu [image-dired-tag-files]
11289 '(menu-item "Add Tags..." image-dired-tag-files
11290 :help "Add tags to marked image files"))
11291(define-key diredp-multiple-images-menu [image-dired-dired-comment-files]
11292 '(menu-item "Add Comment..." image-dired-dired-comment-files
11293 :help "Add comment to marked image files"))
11294(define-key diredp-multiple-images-menu [image-dired-display-thumbs]
11295 '(menu-item "Display Thumbnails" image-dired-display-thumbs
11296 :help "Display thumbnails for marked image files"))
11297(define-key diredp-multiple-images-menu [diredp-do-display-images]
11298 '(menu-item "Display" diredp-do-display-images
11299 :help "Display the marked image files"))
11300
11301
11302;; `Multiple' > `Encryption' menu.
11303;;
11304(when (fboundp 'epa-dired-do-encrypt) ; Emacs 23+
11305 (defvar diredp-multiple-encryption-menu (make-sparse-keymap "Encryption"))
11306 (define-key diredp-menu-bar-multiple-menu [encryption]
11307 (cons "Encryption" diredp-multiple-encryption-menu))
11308
11309 ;; We don't use `define-obsolete-variable-alias' so that byte-compilation in older Emacs
11310 ;; works for newer Emacs too.
11311 (when (fboundp 'defvaralias) ; Emacs 22+
11312 (defvaralias 'diredp-menu-bar-encryption-menu 'diredp-multiple-encryption-menu))
11313 (make-obsolete-variable 'diredp-menu-bar-encryption-menu 'diredp-multiple-encryption-menu) ; 2017-04-09
11314
11315 (when (boundp 'diredp-menu-bar-encryption-menu)
11316 (defalias 'diredp-menu-bar-encryption-menu diredp-menu-bar-encryption-menu))
11317 (make-obsolete 'diredp-menu-bar-encryption-menu 'diredp-multiple-encryption-menu) ; 2017-04-09
11318
11319 ;; Remove the items from `Multiple' menu.
11320 (define-key diredp-menu-bar-multiple-menu [epa-dired-do-decrypt] nil)
11321 (define-key diredp-menu-bar-multiple-menu [epa-dired-do-verify] nil)
11322 (define-key diredp-menu-bar-multiple-menu [epa-dired-do-sign] nil)
11323 (define-key diredp-menu-bar-multiple-menu [epa-dired-do-encrypt] nil)
11324
11325 ;; Add them to `Multiple' > `Encryption' menu.
11326 (define-key diredp-multiple-encryption-menu [epa-dired-do-decrypt]
11327 '(menu-item "Decrypt..." epa-dired-do-decrypt :help "Decrypt the marked files"))
11328 (define-key diredp-multiple-encryption-menu [epa-dired-do-verify]
11329 '(menu-item "Verify..." epa-dired-do-verify :help "Verify the marked files"))
11330 (define-key diredp-multiple-encryption-menu [epa-dired-do-sign]
11331 '(menu-item "Sign..." epa-dired-do-sign :help "Sign the marked files"))
11332 (define-key diredp-multiple-encryption-menu [epa-dired-do-encrypt]
11333 '(menu-item "Encrypt..." epa-dired-do-encrypt :help "Encrypt the marked files")))
11334
11335
11336;; `Multiple' > `Search' menu.
11337;;
11338(defvar diredp-multiple-search-menu (make-sparse-keymap "Search"))
11339(define-key diredp-menu-bar-multiple-menu [search]
11340 (cons "Search" diredp-multiple-search-menu))
11341
11342;; We don't use `define-obsolete-variable-alias' so that byte-compilation in older Emacs
11343;; works for newer Emacs too.
11344(when (fboundp 'defvaralias) ; Emacs 22+
11345 (defvaralias 'diredp-menu-bar-operate-search-menu 'diredp-multiple-search-menu))
11346(make-obsolete-variable 'diredp-menu-bar-operate-search-menu 'diredp-multiple-search-menu) ; 2017-04-09
11347
11348(when (fboundp 'dired-do-isearch-regexp) ; Emacs 23+
11349 (define-key diredp-multiple-search-menu [isearch-regexp]
11350 '(menu-item "Isearch Regexp Files..." dired-do-isearch-regexp
11351 :help "Incrementally search marked files for regexp"))
11352 (define-key diredp-multiple-search-menu [isearch]
11353 '(menu-item "Isearch Files..." dired-do-isearch
11354 :help "Incrementally search marked files for string")))
11355(when (fboundp 'dired-do-find-regexp-and-replace)
11356 (define-key diredp-multiple-search-menu [find-query-replace]
11357 '(menu-item "Query Replace using `find'..." dired-do-find-regexp-and-replace
11358 :help "Replace regexp in marked files using `find'")))
11359(define-key diredp-multiple-search-menu [query-replace]
11360 (if (< emacs-major-version 21)
11361 '(menu-item "Query Replace..." dired-do-query-replace)
11362 '(menu-item "Query Replace..." dired-do-query-replace-regexp
11363 :help "Replace regexp in marked files")))
11364(when (fboundp 'dired-do-find-regexp)
11365 (define-key diredp-multiple-search-menu [find-regexp]
11366 '(menu-item "Search Files using `find'..." dired-do-find-regexp
11367 :help "Search marked files for regexp using `find'")))
11368(define-key diredp-multiple-search-menu [search]
11369 '(menu-item "Search Files..." dired-do-search :help "Search marked files for regexp"))
11370(define-key diredp-multiple-search-menu [grep]
11371 '(menu-item "Grep..." diredp-do-grep :help "Grep marked, next N, or all files shown"))
11372
11373
11374;; `Multiple' > `Bookmark' menu.
11375;;
11376(defvar diredp-multiple-bookmarks-menu (make-sparse-keymap "Bookmark"))
11377(define-key diredp-menu-bar-multiple-menu [bookmark]
11378 (cons "Bookmark" diredp-multiple-bookmarks-menu))
11379
11380;; We don't use `define-obsolete-variable-alias' so that byte-compilation in older Emacs
11381;; works for newer Emacs too.
11382(when (fboundp 'defvaralias) ; Emacs 22+
11383 (defvaralias 'diredp-menu-bar-operate-bookmarks-menu 'diredp-multiple-bookmarks-menu))
11384(make-obsolete-variable 'diredp-menu-bar-operate-bookmarks-menu 'diredp-multiple-bookmarks-menu) ; 2017-04-09
11385
11386(when (require 'bookmark+ nil t)
11387 (define-key diredp-multiple-bookmarks-menu [diredp-do-set-tag-value]
11388 '(menu-item "Set Tag Value..." diredp-do-set-tag-value
11389 :help "Set the value of a given tag for the marked or next N files"))
11390 (define-key diredp-multiple-bookmarks-menu [diredp-do-paste-replace-tags]
11391 '(menu-item "Paste Tags (Replace)" diredp-do-paste-replace-tags
11392 :help "Replace tags for the marked or next N files with copied tags"))
11393 (define-key diredp-multiple-bookmarks-menu [diredp-do-paste-add-tags]
11394 '(menu-item "Paste Tags (Add)" diredp-do-paste-add-tags
11395 :help "Add previously copied tags to the marked or next N files"))
11396 (define-key diredp-multiple-bookmarks-menu [diredp-do-remove-all-tags]
11397 '(menu-item "Remove All Tags" diredp-do-remove-all-tags
11398 :help "Remove all tags from the marked or next N files"))
11399 (define-key diredp-multiple-bookmarks-menu [diredp-do-untag]
11400 '(menu-item "Remove Tags..." diredp-do-untag
11401 :help "Remove some tags from the marked or next N files"))
11402 (define-key diredp-multiple-bookmarks-menu [diredp-do-tag]
11403 '(menu-item "Add Tags..." diredp-do-tag
11404 :help "Add some tags to the marked or next N files"))
11405 (define-key diredp-multiple-bookmarks-menu [separator-book-2] '("--"))) ; ------------
11406
11407(define-key diredp-multiple-bookmarks-menu
11408 [diredp-do-bookmark-in-bookmark-file-recursive]
11409 '(menu-item "Bookmark in Bookmark File (Here and Below)..."
11410 diredp-do-bookmark-in-bookmark-file-recursive
11411 :help "Bookmark marked files (including in marked subdirs) in bookmark file and save it"))
11412(define-key diredp-multiple-bookmarks-menu
11413 [diredp-set-bookmark-file-bookmark-for-marked-recursive]
11414 '(menu-item "Create Bookmark-File Bookmark (Here and Below)..."
11415 diredp-set-bookmark-file-bookmark-for-marked-recursive
11416 :help "Create a bookmark-file bookmark for marked files, including in marked subdirs"))
11417(define-key diredp-multiple-bookmarks-menu [diredp-do-bookmark-dirs-recursive]
11418 '(menu-item "Bookmark Dirs (Here and Below)..." diredp-do-bookmark-dirs-recursive
11419 :help "Bookmark this Dired buffer and marked subdirectory Dired buffers, recursively."))
11420(define-key diredp-multiple-bookmarks-menu [diredp-do-bookmark-recursive]
11421 '(menu-item "Bookmark (Here and Below)..." diredp-do-bookmark-recursive
11422 :help "Bookmark the marked files, including those in marked subdirs"))
11423(define-key diredp-multiple-bookmarks-menu [separator-book-1] '("--")) ; ---------------
11424
11425(define-key diredp-multiple-bookmarks-menu [diredp-do-bookmark-in-bookmark-file]
11426 '(menu-item "Bookmark in Bookmark File..." diredp-do-bookmark-in-bookmark-file
11427 :help "Bookmark the marked files in BOOKMARK-FILE and save BOOKMARK-FILE"))
11428(define-key diredp-multiple-bookmarks-menu [diredp-set-bookmark-file-bookmark-for-marked]
11429 '(menu-item "Create Bookmark-File Bookmark..." diredp-set-bookmark-file-bookmark-for-marked
11430 :help "Create a bookmark-file bookmark, and bookmark the marked files in it"))
11431(define-key diredp-multiple-bookmarks-menu [diredp-do-bookmark]
11432 '(menu-item "Bookmark..." diredp-do-bookmark :help "Bookmark the marked or next N files"))
11433
11434
11435;; `Multiple' > `Marked Here and Below' menu.
11436;;
11437(defvar diredp-multiple-recursive-menu (make-sparse-keymap "Marked Here and Below"))
11438(define-key diredp-menu-bar-multiple-menu [operate-recursive]
11439 (cons "Marked Here and Below" diredp-multiple-recursive-menu))
11440
11441;; We don't use `define-obsolete-variable-alias' so that byte-compilation in older Emacs
11442;; works for newer Emacs too.
11443(when (fboundp 'defvaralias) ; Emacs 22+
11444 (defvaralias 'diredp-menu-bar-operate-recursive-menu 'diredp-multiple-recursive-menu))
11445(make-obsolete-variable 'diredp-menu-bar-operate-recursive-menu 'diredp-multiple-recursive-menu) ; 2017-04-09
11446
11447(when (fboundp 'diredp-do-chown-recursive)
11448 (define-key diredp-multiple-recursive-menu [chown]
11449 '(menu-item "Change Owner..." diredp-do-chown-recursive
11450 :help "Change the owner of marked files, including those in marked subdirs")))
11451(when (fboundp 'diredp-do-chgrp-recursive)
11452 (define-key diredp-multiple-recursive-menu [chgrp]
11453 '(menu-item "Change Group..." diredp-do-chgrp-recursive
11454 :help "Change the owner of marked files, including those in marked subdirs")))
11455(define-key diredp-multiple-recursive-menu [chmod]
11456 '(menu-item "Change Mode..." diredp-do-chmod-recursive
11457 :help "Change mode (attributes) of marked files, including those in marked subdirs"))
11458(when (fboundp 'dired-do-touch) ; Emacs 22+
11459 (define-key diredp-multiple-recursive-menu [touch]
11460 '(menu-item "Change Timestamp (`touch')..." diredp-do-touch-recursive
11461 :help "Change timestamp of marked files, including those in marked subdirs")))
11462(define-key diredp-multiple-recursive-menu [separator-change] '("--")) ; ----------------
11463
11464(when (fboundp 'dired-do-async-shell-command) ; Emacs 23+
11465 (define-key diredp-multiple-recursive-menu [diredp-do-async-shell-command-recursive]
11466 '(menu-item "Asynchronous Shell Command..." diredp-do-async-shell-command-recursive
11467 :help "Run shell command asynchronously on marked files, including in marked subdirs")))
11468(define-key diredp-multiple-recursive-menu [diredp-do-shell-command-recursive]
11469 '(menu-item "Shell Command..." diredp-do-shell-command-recursive
11470 :help "Run shell command on the marked files, including those in marked subdirs"))
11471(define-key diredp-multiple-recursive-menu [diredp-do-apply-function-recursive]
11472 '(menu-item "Apply Lisp Function..." diredp-do-apply-function-recursive
11473 :help "Apply a Lisp function to the marked files, including those in marked subdirs"))
11474(define-key diredp-multiple-recursive-menu [diredp-do-print-recursive]
11475 '(menu-item "Print..." diredp-do-print-recursive
11476 :help "Print the marked files, including those in marked subdirs"))
11477
11478(when (fboundp 'diredp-unmark-all-marks-recursive) ; Emacs 22+
11479 (define-key diredp-multiple-recursive-menu [separator-1] '("--")) ; ------------
11480 (define-key diredp-multiple-recursive-menu [diredp-change-marks-recursive]
11481 '(menu-item "Change Mark..." diredp-change-marks-recursive
11482 :help "Change all OLD marks to NEW marks, including those in marked subdirs"))
11483 (define-key diredp-multiple-recursive-menu [diredp-unmark-all-files-recursive]
11484 '(menu-item "Unmark Marked-With..." diredp-unmark-all-files-recursive
11485 :help "Remove a given mark everywhere, including in marked subdirs"))
11486 (define-key diredp-multiple-recursive-menu [diredp-unmark-all-marks-recursive]
11487 '(menu-item "Unmark All..." diredp-unmark-all-marks-recursive
11488 :help "Remove ALL marks everywhere, including in marked subdirs")))
11489
11490(define-key diredp-multiple-recursive-menu [separator-misc] '("--")) ; ------------------
11491
11492(define-key diredp-multiple-recursive-menu [diredp-do-delete-recursive]
11493 '(menu-item "Delete Marked (not Flagged)" diredp-do-delete-recursive
11494 :help "Delete marked (not flagged) files, including in marked subdirs"))
11495(define-key diredp-multiple-recursive-menu [separator-delete] '("--")) ; ----------------
11496
11497(define-key diredp-multiple-recursive-menu [diredp-do-hardlink-recursive]
11498 '(menu-item "Hardlink to..." diredp-do-hardlink-recursive
11499 :help "Make hard links for marked files, including those in marked subdirs"))
11500(if (not (fboundp 'dired-do-relsymlink))
11501 (define-key diredp-multiple-recursive-menu [diredp-do-symlink-recursive]
11502 '(menu-item "Symlink to..." diredp-do-symlink-recursive
11503 :visible (fboundp 'make-symbolic-link)
11504 :help "Make symbolic links for marked files, including those in marked subdirs"))
11505 (define-key diredp-multiple-recursive-menu [diredp-do-symlink-recursive]
11506 '(menu-item "Symlink to (Absolute)..." diredp-do-symlink-recursive
11507 :help "Make absolute symbolic links for marked files, including those in marked subdirs"))
11508 (define-key diredp-multiple-recursive-menu [diredp-do-relsymlink-recursive]
11509 '(menu-item "Symlink to (Relative)..." diredp-do-relsymlink-recursive
11510 :help "Make relative symbolic links for marked files, including those in marked subdirs")))
11511(define-key diredp-multiple-recursive-menu [diredp-do-copy-recursive]
11512 '(menu-item "Copy to..." diredp-do-copy-recursive
11513 :help "Copy marked files, including in marked subdirs, to a given directory"))
11514(define-key diredp-multiple-recursive-menu [diredp-do-move-recursive]
11515 '(menu-item "Move to..." diredp-do-move-recursive
11516 :help "Move marked files, including in marked subdirs, to a given directory"))
11517(define-key diredp-multiple-recursive-menu [separator-copy-move] '("--")) ; -------------
11518
11519(define-key diredp-multiple-recursive-menu [diredp-capitalize-recursive]
11520 '(menu-item "Capitalize" diredp-capitalize-recursive
11521 :enable (or (not (fboundp 'msdos-long-file-names)) (msdos-long-file-names))
11522 :help "Capitalize the names of all marked files, including in marked subdirs"))
11523(define-key diredp-multiple-recursive-menu [diredp-downcase-recursive]
11524 '(menu-item "Downcase" diredp-downcase-recursive
11525 :enable (or (not (fboundp 'msdos-long-file-names)) (msdos-long-file-names))
11526 :help "Rename marked files, including in marked subdirs, to lowercase names"))
11527(define-key diredp-multiple-recursive-menu [diredp-upcase-recursive]
11528 '(menu-item "Upcase" diredp-upcase-recursive
11529 :enable (or (not (fboundp 'msdos-long-file-names)) (msdos-long-file-names))
11530 :help "Rename marked files, including in marked subdirs, to uppercase names"))
11531(define-key diredp-multiple-recursive-menu [separator-lettercase] '("--")) ; ------------
11532
11533(define-key diredp-multiple-recursive-menu [diredp-list-marked-recursive]
11534 '(menu-item "List Marked Files" diredp-list-marked-recursive
11535 :help "List the files marked here and in marked subdirs, recursively"))
11536(define-key diredp-multiple-recursive-menu [diredp-copy-filename-as-kill-recursive]
11537 '(menu-item "Copy File Names (to Paste)" diredp-copy-filename-as-kill-recursive
11538 :help "Copy names of files marked here and in marked subdirs, to `kill-ring'"))
11539(define-key diredp-multiple-recursive-menu [diredp-insert-subdirs-recursive]
11540 '(menu-item "Insert Subdirs" diredp-insert-subdirs-recursive
11541 :help "Insert the marked subdirectories, gathered recursively"))
11542(define-key diredp-multiple-recursive-menu [separator-dirs] '("--")) ; ------------------
11543
11544(define-key diredp-multiple-recursive-menu [diredp-marked-recursive-other-window]
11545 '(menu-item "Dired (Marked) in Other Window" diredp-marked-recursive-other-window
11546 :help "Open Dired (in other window) on marked files, including those in marked subdirs"))
11547(define-key diredp-multiple-recursive-menu [diredp-marked-recursive]
11548 '(menu-item "Dired (Marked)" diredp-marked-recursive
11549 :help "Open Dired on marked files, including those in marked subdirs"))
11550;; On Windows, bind more.
11551(eval-after-load "w32-browser"
11552 '(define-key diredp-multiple-recursive-menu [diredp-multiple-w32-browser-recursive]
11553 '(menu-item "Open Associated Windows Apps" diredp-multiple-w32-browser-recursive
11554 :help "Run Windows apps for with marked files, including those in marked subdirs")))
11555(define-key diredp-multiple-recursive-menu [diredp-do-find-marked-files-recursive]
11556 '(menu-item "Open" diredp-do-find-marked-files-recursive
11557 :help "Find marked files simultaneously, including those in marked subdirs"))
11558
11559
11560;; `Multiple' > `Marked Here and Below' > `Images' menu.
11561;;
11562(defvar diredp-images-recursive-menu (make-sparse-keymap "Images"))
11563(defalias 'diredp-images-recursive-menu diredp-images-recursive-menu)
11564
11565;; We don't use `define-obsolete-variable-alias' so that byte-compilation in older Emacs
11566;; works for newer Emacs too.
11567(when (fboundp 'defvaralias) ; Emacs 22+
11568 (defvaralias 'diredp-menu-bar-images-recursive-menu 'diredp-images-recursive-menu))
11569(make-obsolete-variable 'diredp-menu-bar-images-recursive-menu 'diredp-images-recursive-menu) ; 2017-04-09
11570
11571(when (boundp 'diredp-menu-bar-images-recursive-menu)
11572 (defalias 'diredp-menu-bar-images-recursive-menu diredp-menu-bar-images-recursive-menu))
11573(make-obsolete 'diredp-menu-bar-images-recursive-menu 'diredp-images-recursive-menu) ; 2017-04-09
11574
11575(define-key diredp-multiple-recursive-menu [images]
11576 '(menu-item "Images" diredp-images-recursive-menu
11577 :enable (fboundp 'image-dired-delete-tag)))
11578(define-key diredp-images-recursive-menu [diredp-image-dired-delete-tag-recursive]
11579 '(menu-item "Delete Image Tag..." diredp-image-dired-delete-tag-recursive
11580 :help "Remove an `image-dired' tag from marked files, including those in marked subdirs"))
11581(define-key diredp-images-recursive-menu [diredp-image-dired-tag-files-recursive]
11582 '(menu-item "Add Image Tags..." diredp-image-dired-tag-files-recursive
11583 :help "Add `image-dired' tags to marked files, including those in marked subdirs"))
11584(define-key diredp-images-recursive-menu [diredp-image-dired-comment-files-recursive]
11585 '(menu-item "Add Image Comment..." diredp-image-dired-comment-files-recursive
11586 :help "Add image comment to marked files, including those in marked subdirs"))
11587(define-key diredp-images-recursive-menu [diredp-image-dired-display-thumbs-recursive]
11588 '(menu-item "Display Image Thumbnails" diredp-image-dired-display-thumbs-recursive
11589 :help "Show thumbnails for marked image files, including those in marked subdirs"))
11590
11591
11592;; `Multiple' > `Marked Here and Below' > `Encryption' menu.
11593;;
11594(when (fboundp 'epa-dired-do-encrypt) ; Emacs 23+
11595 (defvar diredp-menu-bar-encryption-recursive-menu (make-sparse-keymap "Encryption"))
11596 (define-key diredp-multiple-recursive-menu [encryption]
11597 (cons "Encryption" diredp-menu-bar-encryption-recursive-menu))
11598 (define-key diredp-menu-bar-encryption-recursive-menu [diredp-do-decrypt-recursive]
11599 '(menu-item "Decrypt..." diredp-do-decrypt-recursive
11600 :help "Decrypt marked files, including those in marked subdirs"))
11601 (define-key diredp-menu-bar-encryption-recursive-menu [diredp-do-verify-recursive]
11602 '(menu-item "Verify..." diredp-do-verify-recursive
11603 :help "Verify marked files, including those in marked subdirs"))
11604 (define-key diredp-menu-bar-encryption-recursive-menu [diredp-do-sign-recursive]
11605 '(menu-item "Sign..." diredp-do-sign-recursive
11606 :help "Sign marked files, including those in marked subdirs"))
11607 (define-key diredp-menu-bar-encryption-recursive-menu [diredp-do-encrypt-recursive]
11608 '(menu-item "Encrypt..." diredp-do-encrypt-recursive
11609 :help "Encrypt marked files, including those in marked subdirs")))
11610
11611
11612;; `Multiple' > `Marked Here and Below' > `Search' menu.
11613;;
11614(defvar diredp-menu-bar-search-recursive-menu (make-sparse-keymap "Search"))
11615(define-key diredp-multiple-recursive-menu [search]
11616 (cons "Search" diredp-menu-bar-search-recursive-menu))
11617(when (fboundp 'dired-do-isearch-regexp) ; Emacs 23+
11618 (define-key diredp-menu-bar-search-recursive-menu [diredp-do-isearch-regexp-recursive]
11619 '(menu-item "Isearch Regexp Files..." diredp-do-isearch-regexp-recursive
11620 :help "Incrementally regexp search marked files, including those in marked subdirs"))
11621 (define-key diredp-menu-bar-search-recursive-menu [diredp-do-isearch-recursive]
11622 '(menu-item "Isearch Files..." diredp-do-isearch-recursive
11623 :help "Incrementally search marked files, including those in marked subdirs")))
11624(define-key diredp-menu-bar-search-recursive-menu [diredp-do-query-replace-regexp-recursive]
11625 '(menu-item "Query Replace..." diredp-do-query-replace-regexp-recursive
11626 :help "Replace regexp in marked files, including those in marked subdirs"))
11627(define-key diredp-menu-bar-search-recursive-menu [diredp-do-search-recursive]
11628 '(menu-item "Search Files..." diredp-do-search-recursive
11629 :help "Regexp search marked files, including those in marked subdirs"))
11630(define-key diredp-menu-bar-search-recursive-menu [diredp-do-grep-recursive]
11631 '(menu-item "Grep..." diredp-do-grep-recursive
11632 :help "Run `grep' on the marked files, including those in marked subdirs"))
11633
11634
11635;; `Multiple' > `Marked Here and Below' > `Bookmark' menu.
11636;;
11637(defvar diredp-menu-bar-bookmarks-recursive-menu (make-sparse-keymap "Bookmark"))
11638(define-key diredp-multiple-recursive-menu [bookmarks]
11639 (cons "Bookmark" diredp-menu-bar-bookmarks-recursive-menu))
11640(define-key diredp-menu-bar-bookmarks-recursive-menu
11641 [diredp-do-bookmark-in-bookmark-file-recursive]
11642 '(menu-item "Bookmark in Bookmark File..." diredp-do-bookmark-in-bookmark-file-recursive
11643 :help "Bookmark marked files, including those in marked subdirs, in a bookmark file"))
11644(define-key diredp-menu-bar-bookmarks-recursive-menu
11645 [diredp-set-bookmark-file-bookmark-for-marked-recursive]
11646 '(menu-item "Create Bookmark-File Bookmark..."
11647 diredp-set-bookmark-file-bookmark-for-marked-recursive
11648 :help "Create a bookmark-file bookmark for marked files, including in marked subdirs"))
11649(define-key diredp-menu-bar-bookmarks-recursive-menu [diredp-do-bookmark-dirs-recursive]
11650 '(menu-item "Bookmark Dirs..." diredp-do-bookmark-dirs-recursive
11651 :help "Bookmark this Dired buffer and marked subdirectory Dired buffers, recursively."))
11652(define-key diredp-menu-bar-bookmarks-recursive-menu [diredp-do-bookmark-recursive]
11653 '(menu-item "Bookmark..." diredp-do-bookmark-recursive
11654 :help "Bookmark the marked files, including those in marked subdirs"))
11655
11656
11657
11658;; `Regexp' menu.
11659;;
11660;; REPLACE ORIGINAL `Regexp' menu in `dired.el'.
11661;;
11662(defvar diredp-menu-bar-regexp-menu (make-sparse-keymap "Regexp"))
11663(define-key dired-mode-map [menu-bar regexp] (cons "Regexp" diredp-menu-bar-regexp-menu))
11664
11665(define-key diredp-menu-bar-regexp-menu [hardlink]
11666 '(menu-item "Hardlink to..." dired-do-hardlink-regexp
11667 :help "Make hard links for files matching regexp"))
11668(if (not (fboundp 'dired-do-relsymlink-regexp))
11669 (define-key diredp-menu-bar-regexp-menu [symlink]
11670 '(menu-item "Symlink to..." dired-do-symlink-regexp
11671 :visible (fboundp 'make-symbolic-link)
11672 :help "Make symbolic links for files matching regexp"))
11673 (define-key diredp-menu-bar-regexp-menu [symlink]
11674 '(menu-item "Symlink to (Absolute)..." dired-do-symlink-regexp
11675 :visible (fboundp 'make-symbolic-link)
11676 :help "Make absolute symbolic links for files matching regexp"))
11677 (define-key diredp-menu-bar-regexp-menu [relsymlink] ; In `dired-x.el'.
11678 '(menu-item "Symlink to (Relative)..." dired-do-relsymlink-regexp
11679 :visible (fboundp 'make-symbolic-link)
11680 :help "Make relative symbolic links for files matching regexp")))
11681(define-key diredp-menu-bar-regexp-menu [copy]
11682 '(menu-item "Copy to..." dired-do-copy-regexp :help "Copy marked files matching regexp"))
11683(define-key diredp-menu-bar-regexp-menu [rename]
11684 '(menu-item "Move to..." dired-do-rename-regexp :help "Move marked files matching regexp"))
11685(define-key diredp-menu-bar-regexp-menu [flag]
11686 '(menu-item "Flag..." dired-flag-files-regexp :help "Flag files matching regexp for deletion"))
11687(define-key diredp-menu-bar-regexp-menu [image-dired-mark-tagged-files]
11688 '(menu-item "Mark Image Files Tagged..." image-dired-mark-tagged-files
11689 :enable (fboundp 'image-dired-mark-tagged-files)
11690 :help "Mark image files whose image tags match regexp"))
11691(define-key diredp-menu-bar-regexp-menu [mark-cont]
11692 '(menu-item "Mark Containing..." dired-mark-files-containing-regexp
11693 :help "Mark files whose contents matches regexp"))
11694(define-key diredp-menu-bar-regexp-menu [mark]
11695 '(menu-item "Mark..." dired-mark-files-regexp
11696 :help "Mark files matching regexp"))
11697
11698
11699;; `Regexp' > `Here and Below' menu.
11700;;
11701(defvar diredp-regexp-recursive-menu (make-sparse-keymap "Here and Below"))
11702(define-key diredp-menu-bar-regexp-menu [mark-recursive]
11703 (cons "Here and Below" diredp-regexp-recursive-menu))
11704(define-key diredp-regexp-recursive-menu [diredp-mark-files-regexp-recursive]
11705 '(menu-item "Mark..." diredp-mark-files-regexp-recursive
11706 :help "Mark all files matching a regexp, including those in marked subdirs"))
11707
11708;; We don't use `define-obsolete-variable-alias' so that byte-compilation in older Emacs
11709;; works for newer Emacs too.
11710(when (fboundp 'defvaralias) ; Emacs 22+
11711 (defvaralias 'diredp-menu-bar-regexp-recursive-menu 'diredp-regexp-recursive-menu))
11712(make-obsolete-variable 'diredp-menu-bar-regexp-recursive-menu 'diredp-regexp-recursive-menu) ; 2017-04-09
11713
11714(when (boundp 'diredp-menu-bar-regexp-recursive-menu)
11715 (defalias 'diredp-menu-bar-regexp-recursive-menu diredp-menu-bar-regexp-recursive-menu))
11716(make-obsolete 'diredp-menu-bar-regexp-recursive-menu 'diredp-regexp-recursive-menu) ; 2017-04-09
11717
11718
11719;; "Marks" menu.
11720;;
11721;; REPLACE ORIGINAL `Marks' menu in `dired.el'.
11722;;
11723(defvar diredp-menu-bar-marks-menu (make-sparse-keymap "Marks"))
11724(define-key dired-mode-map [menu-bar mark] (cons "Marks" diredp-menu-bar-marks-menu))
11725
11726;; We don't use `define-obsolete-variable-alias' so that byte-compilation in older Emacs
11727;; works for newer Emacs too.
11728(when (fboundp 'defvaralias) ; Emacs 22+
11729 (defvaralias 'diredp-menu-bar-mark-menu 'diredp-menu-bar-marks-menu))
11730(make-obsolete-variable 'diredp-menu-bar-mark-menu 'diredp-menu-bar-marks-menu) ; 2017-04-09
11731
11732(define-key diredp-menu-bar-marks-menu [prev]
11733 '(menu-item "Previous Marked" dired-prev-marked-file :help "Move to previous marked file"))
11734(define-key diredp-menu-bar-marks-menu [next]
11735 '(menu-item "Next Marked" dired-next-marked-file :help "Move to next marked file"))
11736(define-key diredp-menu-bar-marks-menu [marks]
11737 '(menu-item "Change Mark..." dired-change-marks
11738 :help "Replace a given mark character with another"))
11739(define-key diredp-menu-bar-marks-menu [toggle-marks]
11740 (if (> emacs-major-version 21)
11741 '(menu-item "Toggle Marked/Unmarked" dired-toggle-marks
11742 :help "Mark unmarked files, unmark marked ones")
11743 '(menu-item "Toggle Marked/Unmarked" dired-toggle-marks
11744 :help "Mark unmarked files, unmark marked ones")))
11745
11746
11747;; `Marks' > `Tagged' menu.
11748;;
11749(when (require 'bookmark+ nil t)
11750 (defvar diredp-marks-tags-menu (make-sparse-keymap "Tagged (Autofiles)")
11751 "`Tags' submenu for Dired menu-bar `Marks' menu.")
11752 (define-key diredp-menu-bar-marks-menu [mark-tags] (cons "Tagged" diredp-marks-tags-menu))
11753
11754 (define-key diredp-marks-tags-menu [diredp-unmark-files-tagged-none]
11755 '(menu-item "Unmark Not Tagged with Any..." diredp-unmark-files-tagged-none
11756 :help "Unmark files that are not tagged with *any* of the tags you enter"))
11757 (define-key diredp-marks-tags-menu [diredp-unmark-files-tagged-not-all]
11758 '(menu-item "Unmark Not Tagged with All..." diredp-unmark-files-tagged-not-all
11759 :help "Unmark files that are not tagged with *all* tags"))
11760 (define-key diredp-marks-tags-menu [diredp-unmark-files-tagged-some]
11761 '(menu-item "Unmark Tagged with Some..." diredp-unmark-files-tagged-some
11762 :help "Unmark files that are tagged with at least one of the tags you enter"))
11763 (define-key diredp-marks-tags-menu [diredp-unmark-files-tagged-all]
11764 '(menu-item "Unmark Tagged with All..." diredp-unmark-files-tagged-all
11765 :help "Unmark files that are tagged with *each* tag you enter"))
11766 (define-key diredp-marks-tags-menu [diredp-unmark-files-tagged-regexp]
11767 '(menu-item "Unmark Tagged Matching Regexp..." diredp-unmark-files-tagged-regexp
11768 :help "Unmark files that have at least one tag that matches a regexp"))
11769 (define-key diredp-marks-tags-menu [separator-marks-tags] '("--")) ; -------------------------
11770
11771 (define-key diredp-marks-tags-menu [diredp-mark-files-tagged-none]
11772 '(menu-item "Mark Not Tagged with Any..." diredp-mark-files-tagged-none
11773 :help "Mark files that are not tagged with *any* of the tags you enter"))
11774 (define-key diredp-marks-tags-menu [diredp-mark-files-tagged-not-all]
11775 '(menu-item "Mark Not Tagged with All..." diredp-mark-files-tagged-not-all
11776 :help "Mark files that are not tagged with *all* tags"))
11777 (define-key diredp-marks-tags-menu [diredp-mark-files-tagged-some]
11778 '(menu-item "Mark Tagged with Some..." diredp-mark-files-tagged-some
11779 :help "Mark files that are tagged with at least one of the tags you enter"))
11780 (define-key diredp-marks-tags-menu [diredp-mark-files-tagged-all]
11781 '(menu-item "Mark Tagged with All..." diredp-mark-files-tagged-all
11782 :help "Mark files that are tagged with *each* tag you enter"))
11783 (define-key diredp-marks-tags-menu [diredp-mark-files-tagged-regexp]
11784 '(menu-item "Mark Tagged Matching Regexp..." diredp-mark-files-tagged-regexp
11785 :help "Mark files that have at least one tag that matches a regexp")))
11786
11787
11788;; `Marks' > `Omit' menu.
11789;;
11790(defvar diredp-marks-omit-menu (make-sparse-keymap "Omit")
11791 "`Omit' submenu for Dired menu-bar `Marks' menu.")
11792(define-key diredp-menu-bar-marks-menu [marks-omit] (cons "Omit" diredp-marks-omit-menu))
11793
11794(define-key diredp-marks-omit-menu [marks-omit-unmarked]
11795 '(menu-item "Omit Unmarked" diredp-omit-unmarked :help "Hide lines of unmarked files"))
11796(define-key diredp-marks-omit-menu [marks-omit-marked]
11797 '(menu-item "Omit Marked" diredp-omit-marked :help "Hide lines of marked files"))
11798
11799
11800;; `Marks' > `Flag' menu.
11801;;
11802(defvar diredp-marks-flag-menu (make-sparse-keymap "Flag")
11803 "`Flag' submenu for Dired menu-bar `Marks' menu.")
11804(define-key diredp-menu-bar-marks-menu [mark-flag] (cons "Flag" diredp-marks-flag-menu))
11805
11806(when (fboundp 'dired-flag-extension)
11807 (define-key diredp-marks-flag-menu [marks-flag-extension] ; In `dired-x.el'
11808 '(menu-item "Flag Extension..." dired-flag-extension
11809 :help "Flag all files that have a certain extension, for deletion")))
11810(define-key diredp-marks-flag-menu [marks-flag-garbage-files]
11811 '(menu-item "Flag Garbage Files" dired-flag-garbage-files
11812 :help "Flag unneeded files for deletion"))
11813(define-key diredp-marks-flag-menu [marks-flag-backup-files]
11814 '(menu-item "Flag Backup Files" dired-flag-backup-files
11815 :help "Flag all backup files for deletion"))
11816(define-key diredp-marks-flag-menu [marks-flag-auto-save-files]
11817 '(menu-item "Flag Auto-save Files" dired-flag-auto-save-files
11818 :help "Flag auto-save files for deletion"))
11819(define-key diredp-marks-flag-menu [marks-flag-region]
11820 '(menu-item "Flag Region" diredp-flag-region-files-for-deletion
11821 :visible (diredp-nonempty-region-p)
11822 :help "Flag all files in the region (selection) for deletion"))
11823(when (< emacs-major-version 21)
11824 (put 'diredp-flag-region-files-for-deletion 'menu-enable '(diredp-nonempty-region-p)))
11825(define-key diredp-marks-flag-menu [marks-flag-deletion]
11826 '(menu-item "Flag This" dired-flag-file-deletion
11827 :visible (not (diredp-nonempty-region-p))
11828 :help "Flag current line's file for deletion"))
11829
11830
11831;; `Marks' > `Unmark' menu.
11832;;
11833(defvar diredp-marks-unmark-menu (make-sparse-keymap "Unmark")
11834 "`Unmark' submenu for Dired menu-bar `Marks' menu.")
11835(define-key diredp-menu-bar-marks-menu [mark-mark] (cons "Unmark" diredp-marks-unmark-menu))
11836
11837(define-key diredp-marks-unmark-menu [unmark-autofiles]
11838 '(menu-item "Unmark Autofiles" diredp-unmark-autofiles
11839 :help "Unmark all autofiles (bookmarks with same name as file)"
11840 :enable (featurep 'bookmark+)))
11841(define-key diredp-marks-unmark-menu [unmark-all]
11842 '(menu-item "Unmark All" dired-unmark-all-marks :help "Remove all marks from all files"))
11843(define-key diredp-marks-unmark-menu [unmark-with]
11844 '(menu-item "Unmark Marked-With..." dired-unmark-all-files
11845 :help "Remove a specific mark (or all marks) from every file"))
11846(define-key diredp-marks-unmark-menu [unmark-region]
11847 '(menu-item "Unmark Region" diredp-unmark-region-files
11848 :visible (diredp-nonempty-region-p)
11849 :help "Unmark all files in the region (selection)"))
11850(when (< emacs-major-version 21)
11851 (put 'diredp-unmark-region-files 'menu-enable '(diredp-nonempty-region-p)))
11852(define-key diredp-marks-unmark-menu [unmark-this]
11853 '(menu-item "Unmark This" dired-unmark
11854 :visible (not (diredp-nonempty-region-p))
11855 :help "Unmark or unflag current line's file"))
11856
11857
11858;; `Marks' > `Mark' menu.
11859;;
11860(defvar diredp-marks-mark-menu (make-sparse-keymap "Mark")
11861 "`Mark' submenu for Dired menu-bar `Marks' menu.")
11862(define-key diredp-menu-bar-marks-menu [marks-mark] (cons "Mark" diredp-marks-mark-menu))
11863
11864(when (fboundp 'dired-mark-sexp)
11865 (define-key diredp-marks-mark-menu [marks-mark-sexp] ; In `dired-x.el'.
11866 '(menu-item "Mark If..." dired-mark-sexp
11867 :help "Mark files for which specified condition is true")))
11868(define-key diredp-marks-mark-menu [marks-image-dired-mark-tagged-files]
11869 '(menu-item "Mark Image Files Tagged..." image-dired-mark-tagged-files
11870 :enable (fboundp 'image-dired-mark-tagged-files)
11871 :help "Mark image files whose image tags match regexp"))
11872(define-key diredp-marks-mark-menu [marks-mark-cont]
11873 '(menu-item "Mark Content Matching Regexp..." dired-mark-files-containing-regexp
11874 :help "Mark files whose contents matches regexp"))
11875(define-key diredp-marks-mark-menu [marks-mark...]
11876 '(menu-item "Mark Name Matching Regexp..." dired-mark-files-regexp
11877 :help "Mark file names matching regexp"))
11878(when (fboundp 'dired-mark-omitted) ; In `dired-x.el'.
11879 (define-key diredp-marks-mark-menu [marks-mark-omitted]
11880 '(menu-item "Mark Omitted..." dired-mark-omitted
11881 :help "Mark all omitted files and subdirectories")))
11882(define-key diredp-marks-mark-menu [marks-mark-extension]
11883 '(menu-item "Mark Extension..." diredp-mark/unmark-extension
11884 :help "Mark all files with specified extension"))
11885(define-key diredp-marks-mark-menu [marks-mark-autofiles]
11886 '(menu-item "Mark Autofiles" diredp-mark-autofiles
11887 :help "Mark all autofiles (bookmarks with same name as file)"
11888 :enable (featurep 'bookmark+)))
11889(define-key diredp-marks-mark-menu [marks-mark-symlinks]
11890 '(menu-item "Mark Symlinks" dired-mark-symlinks
11891 :visible (fboundp 'make-symbolic-link) :help "Mark all symbolic links"))
11892(define-key diredp-marks-mark-menu [marks-mark-directories]
11893 '(menu-item "Mark Directories" dired-mark-directories
11894 :help "Mark all directories except `.' and `..'"))
11895(define-key diredp-marks-mark-menu [marks-mark-directory]
11896 '(menu-item "Mark Old Backups" dired-clean-directory
11897 :help "Flag old numbered backups for deletion"))
11898(define-key diredp-marks-mark-menu [marks-mark-executables]
11899 '(menu-item "Mark Executables" dired-mark-executables :help "Mark all executable files"))
11900(define-key diredp-marks-mark-menu [marks-mark-region]
11901 '(menu-item "Mark Region" diredp-mark-region-files
11902 :visible (diredp-nonempty-region-p)
11903 :help "Mark all of the files in the region (selection)"))
11904(when (< emacs-major-version 21)
11905 (put 'diredp-mark-region-files 'menu-enable '(diredp-nonempty-region-p)))
11906(define-key diredp-marks-mark-menu [marks-mark-this]
11907 '(menu-item "Mark This" dired-mark
11908 :visible (not (diredp-nonempty-region-p))
11909 :help "Mark current line's file for future operations"))
11910
11911
11912;; `Marks' > `Here and Below' menu.
11913;;
11914(defvar diredp-marks-recursive-menu (make-sparse-keymap "Here and Below"))
11915(define-key diredp-menu-bar-marks-menu [mark-recursive]
11916 (cons "Here and Below" diredp-marks-recursive-menu))
11917
11918(define-key diredp-marks-recursive-menu [diredp-flag-auto-save-files-recursive]
11919 '(menu-item "Flag Auto-Save Files..." diredp-flag-auto-save-files-recursive
11920 :help "Flag all auto-save files for deletion, including those in marked subdirs"))
11921(when (fboundp 'diredp-unmark-all-marks-recursive) ; Emacs 22+
11922 (define-key diredp-marks-recursive-menu [diredp-change-marks-recursive]
11923 '(menu-item "Change Mark..." diredp-change-marks-recursive
11924 :help "Change all OLD marks to NEW marks, including those in marked subdirs"))
11925 (define-key diredp-marks-recursive-menu [diredp-unmark-all-files-recursive]
11926 '(menu-item "Unmark Marked-With..." diredp-unmark-all-files-recursive
11927 :help "Remove a given mark everywhere, including in marked subdirs"))
11928 (define-key diredp-marks-recursive-menu [diredp-unmark-all-marks-recursive]
11929 '(menu-item "Unmark All..." diredp-unmark-all-marks-recursive
11930 :help "Remove ALL marks everywhere, including in marked subdirs"))
11931 (define-key diredp-marks-recursive-menu [separator-1] '("--"))) ; ------------
11932(define-key diredp-marks-recursive-menu [diredp-mark-files-regexp-recursive]
11933 '(menu-item "Regexp..." diredp-mark-files-regexp-recursive
11934 :help "Mark all files matching a regexp, including those in marked subdirs"))
11935(define-key diredp-marks-recursive-menu [diredp-mark-extension-recursive]
11936 '(menu-item "Extension..." diredp-mark-extension-recursive
11937 :help "Mark all files with a given extension, including those in marked subdirs"))
11938(define-key diredp-marks-recursive-menu [diredp-mark-autofiles-recursive]
11939 '(menu-item "Autofiles" diredp-mark-autofiles-recursive
11940 :help "Mark all files with a given extension, including those in marked subdirs"
11941 :enable (featurep 'bookmark+)))
11942(define-key diredp-marks-recursive-menu [diredp-mark-symlinks-recursive]
11943 '(menu-item "Symbolic Links" diredp-mark-symlinks-recursive
11944 :help "Mark all symbolic links, including those in marked subdirs"))
11945(define-key diredp-marks-recursive-menu [diredp-mark-directories-recursive]
11946 '(menu-item "Directories" diredp-mark-directories-recursive
11947 :help "Mark all directories, including those in marked subdirs"))
11948(define-key diredp-marks-recursive-menu [diredp-mark-executables-recursive]
11949 '(menu-item "Executables" diredp-mark-executables-recursive
11950 :help "Mark all executable files, including those in marked subdirs"))
11951
11952
11953;; "Dir" menu.
11954;;
11955;; REPLACE ORIGINAL `Subdir' menu in `dired.el'.
11956;;
11957(defvar diredp-menu-bar-dir-menu (make-sparse-keymap "Dir"))
11958(define-key dired-mode-map [menu-bar subdir] (cons "Dir" diredp-menu-bar-dir-menu))
11959
11960;; We don't use `define-obsolete-variable-alias' so that byte-compilation in older Emacs
11961;; works for newer Emacs too.
11962(when (fboundp 'defvaralias) ; Emacs 22+
11963 (defvaralias 'diredp-menu-bar-subdir-menu 'diredp-dir-menu))
11964(make-obsolete-variable 'diredp-menu-bar-subdir-menu 'diredp-dir-menu) ; 2017-04-09
11965
11966(when (boundp 'diredp-menu-bar-subdir-menu)
11967 (defalias 'diredp-menu-bar-subdir-menu diredp-menu-bar-subdir-menu))
11968(make-obsolete 'diredp-menu-bar-subdir-menu 'diredp-dir-menu) ; 2017-04-09
11969
11970
11971;; `Dir' > `Hide/Show' menu.
11972;;
11973(defvar diredp-hide/show-menu (make-sparse-keymap "Hide/Show")
11974 "`Hide/Show' submenu for Dired menu-bar `Dir' menu.")
11975(define-key diredp-menu-bar-dir-menu [hide-show] (cons "Hide/Show" diredp-hide/show-menu))
11976
11977(when (fboundp 'dired-omit-mode)
11978 (define-key diredp-hide/show-menu [dired-omit-mode]
11979 '(menu-item "Hide/Show Uninteresting (Omit Mode)" dired-omit-mode
11980 :help "Toggle omission of uninteresting files (Omit mode)")))
11981(when (fboundp 'dired-hide-details-mode) ; Emacs 24.4+
11982 (define-key diredp-hide/show-menu [hide-details]
11983 '(menu-item "Hide/Show Details" dired-hide-details-mode
11984 :help "Hide or show less important fields of directory listing")))
11985(define-key diredp-hide/show-menu [hide-all]
11986 '(menu-item "Hide/Show All Subdirs" dired-hide-all
11987 :help "Hide all subdirectories, leave only header lines"))
11988(define-key diredp-hide/show-menu [hide-subdir]
11989 '(menu-item "Hide/Show Subdir" diredp-hide-subdir-nomove
11990 :help "Hide or unhide current directory listing"))
11991
11992
11993;; `Dir' > `Bookmark' menu.
11994;;
11995(defvar diredp-bookmark-menu (make-sparse-keymap "Bookmark")
11996 "`Bookmark' submenu for Dired menu-bar `Dir' menu.")
11997(define-key diredp-menu-bar-dir-menu [bookmark] (cons "Bookmark" diredp-bookmark-menu))
11998
11999(define-key diredp-bookmark-menu [diredp-highlight-autofiles-mode]
12000 '(menu-item "Toggle Autofile Highlighting" diredp-highlight-autofiles-mode
12001 :help "Toggle whether to highlight autofile bookmarks"
12002 :visible (and (featurep 'bookmark+) (featurep 'highlight))))
12003(define-key diredp-bookmark-menu [diredp-do-bookmark-dirs-recursive]
12004 '(menu-item "Bookmark Dirs Here and Below..." diredp-do-bookmark-dirs-recursive
12005 :help "Bookmark this Dired buffer and marked subdirectory Dired buffers, recursively."))
12006(define-key diredp-bookmark-menu [bookmark-dired]
12007 '(menu-item "Bookmark Dired Buffer..." bookmark-set :help "Bookmark this Dired buffer"))
12008
12009
12010;; `Dir' > `Navigate' menu.
12011;;
12012(defvar diredp-navigate-menu (make-sparse-keymap "Navigate")
12013 "`Navigate' submenu for Dired menu-bar `Dir' menu.")
12014(define-key diredp-menu-bar-dir-menu [navigate] (cons "Navigate" diredp-navigate-menu))
12015
12016(define-key diredp-navigate-menu [insert]
12017 '(menu-item "Move To This Subdir" dired-maybe-insert-subdir
12018 :help "Move to subdirectory line or listing"))
12019(define-key diredp-navigate-menu [tree-down]
12020 '(menu-item "Tree Down" dired-tree-down :help "Go to first subdirectory header down the tree"))
12021(define-key diredp-navigate-menu [tree-up]
12022 '(menu-item "Tree Up" dired-tree-up :help "Go to first subdirectory header up the tree"))
12023(define-key diredp-navigate-menu [up]
12024 '(menu-item "Up Directory" diredp-up-directory :help "Dired the parent directory"))
12025(define-key diredp-navigate-menu [prev-subdir]
12026 '(menu-item "Prev Subdir" diredp-prev-subdir :help "Go to previous subdirectory header line"))
12027(define-key diredp-navigate-menu [next-subdir]
12028 '(menu-item "Next Subdir" diredp-next-subdir :help "Go to next subdirectory header line"))
12029(define-key diredp-navigate-menu [prev-dirline]
12030 '(menu-item "Prev Dirline" diredp-prev-dirline :help "Move to previous directory-file line"))
12031(define-key diredp-navigate-menu [next-dirline]
12032 '(menu-item "Next Dirline" diredp-next-dirline :help "Move to next directory-file line"))
12033
12034(define-key diredp-menu-bar-dir-menu [separator-subdir] '("--")) ; --------------------------
12035
12036(define-key diredp-menu-bar-dir-menu [image-dired-dired-toggle-marked-thumbs]
12037 '(menu-item "Toggle Image Thumbnails" image-dired-dired-toggle-marked-thumbs
12038 :enable (fboundp 'image-dired-dired-toggle-marked-thumbs)
12039 :help "Add or remove image thumbnails in front of marked file names"))
12040(when (fboundp 'dired-isearch-filenames) ; Emacs 23+
12041 (define-key diredp-menu-bar-dir-menu [isearch-filenames-regexp]
12042 '(menu-item "Isearch Regexp in File Names..." dired-isearch-filenames-regexp
12043 :help "Incrementally search for regexp in file names only"))
12044 (define-key diredp-menu-bar-dir-menu [isearch-filenames]
12045 '(menu-item "Isearch in File Names..." dired-isearch-filenames
12046 :help "Incrementally search for literal text in file names only.")))
12047(when (or (> emacs-major-version 21) (fboundp 'wdired-change-to-wdired-mode))
12048 (define-key diredp-menu-bar-dir-menu [wdired-mode]
12049 '(menu-item "Edit File Names (WDired)" wdired-change-to-wdired-mode
12050 :help "Put a Dired buffer in a mode in which filenames are editable"
12051 :keys "C-x C-q" :filter (lambda (x) (and (derived-mode-p 'dired-mode) x)))))
12052(define-key diredp-menu-bar-dir-menu [diredp-yank-files]
12053 '(menu-item "Paste Files from Copied Absolute Names" diredp-yank-files
12054 :help "Paste files here whose absolute names you copied"
12055 :enable (catch 'dir-menu--yank-files
12056 (let ((files (car kill-ring-yank-pointer)))
12057 (and (stringp files)
12058 (dolist (file (split-string files))
12059 (unless (file-name-absolute-p file) (throw 'dir-menu--yank-files nil)))))
12060 t)))
12061(when (fboundp 'dired-compare-directories) ; Emacs 22+
12062 (define-key diredp-menu-bar-dir-menu [compare-directories]
12063 '(menu-item "Compare Directories..." dired-compare-directories
12064 :help "Mark files with different attributes in two Dired buffers")))
12065
12066(define-key diredp-menu-bar-dir-menu [separator-dired-on-set] '("--")) ; --------------------
12067
12068(define-key diredp-menu-bar-dir-menu [diredp-dired-recent-dirs]
12069 '(menu-item "Dired Recent Directories..." diredp-dired-recent-dirs
12070 :visible (boundp 'recentf-list) :enable (and (boundp 'recentf-list) (consp recentf-list))
12071 :help "Open a Dired buffer for recently used directories"))
12072(define-key diredp-menu-bar-dir-menu [diredp-dired-inserted-subdirs]
12073 '(menu-item "Dired Each Inserted Subdir..." diredp-dired-inserted-subdirs
12074 :enable (cdr dired-subdir-alist) ; First elt is current dir. Must have at least one more.
12075 :help "Open Dired separately for each of the inserted subdirectories"))
12076(define-key diredp-menu-bar-dir-menu [diredp-add-to-this-dired-buffer]
12077 '(menu-item "Add Entries Here..." diredp-add-to-this-dired-buffer
12078 :help "Add individual file and directory names to the listing"
12079 :keys "C-x E"))
12080(define-key diredp-menu-bar-dir-menu [diredp-dired-union]
12081 '(menu-item "Dired Union..." diredp-dired-union
12082 :help "Open Dired for the union of some existing Dired buffers"))
12083(define-key diredp-menu-bar-dir-menu [diredp-fileset-other-window]
12084 '(menu-item "Dired Fileset..." diredp-fileset-other-window
12085 :enable (> emacs-major-version 21) :help "Open Dired on an Emacs fileset"))
12086(define-key diredp-menu-bar-dir-menu [diredp-dired-for-files]
12087 '(menu-item "Dired Files Located Anywhere" diredp-dired-for-files
12088 :help "Open Dired on specific files whose names you provide"))
12089(define-key diredp-menu-bar-dir-menu [diredp-marked-other-window]
12090 '(menu-item "Dired Marked Files in Other Window" diredp-marked-other-window
12091 :enable (save-excursion (goto-char (point-min))
12092 (and (re-search-forward (dired-marker-regexp) nil t)
12093 (re-search-forward (dired-marker-regexp) nil t)))
12094 :help "Open Dired on marked files only, in other window"))
12095(define-key diredp-menu-bar-dir-menu [diredp-marked]
12096 '(menu-item "Dired Marked Files" diredp-marked
12097 :enable (save-excursion (goto-char (point-min))
12098 (and (re-search-forward (dired-marker-regexp) nil t)
12099 (re-search-forward (dired-marker-regexp) nil t)))
12100 :help "Open Dired on marked files only"))
12101(define-key diredp-menu-bar-dir-menu [dired]
12102 '(menu-item "Dired (Filter via Wildcards)..." dired
12103 :help "Explore a directory (you can provide wildcards)"))
12104
12105(define-key diredp-menu-bar-dir-menu [separator-dired] '("--")) ; ---------------------
12106
12107(define-key diredp-menu-bar-dir-menu [insert]
12108 '(menu-item "Insert/Move-To This Subdir" dired-maybe-insert-subdir
12109 :help "Move to subdirectory line or listing"))
12110(define-key diredp-menu-bar-dir-menu [revert]
12111 '(menu-item "Refresh (Sync \& Show All)" revert-buffer :help "Update directory contents"))
12112(define-key diredp-menu-bar-dir-menu [create-directory] ; Moved from "Immediate".
12113 '(menu-item "New Directory..." dired-create-directory :help "Create a directory"))
12114
12115
12116;;; Mouse-3 menu binding.
12117(define-key dired-mode-map [down-mouse-3] 'diredp-mouse-3-menu)
12118(define-key dired-mode-map [mouse-3] 'ignore)
12119
12120
12121;;; Non-menu Dired bindings.
12122
12123;; Move `dired-omit-mode' to `C-x M-o', so prefix key `M-o' is free for face/font-lock stuff.
12124(define-key dired-mode-map "\C-x\M-o" (if (fboundp 'dired-omit-mode) 'dired-omit-mode 'dired-omit-toggle))
12125(when (memq (lookup-key dired-mode-map "\M-o") '(dired-omit-mode dired-omit-toggle))
12126 (define-key dired-mode-map "\M-o" nil))
12127
12128;; These are global, not just Dired mode. They are on prefix key `C-x D'.
12129(unless (lookup-key ctl-x-map "D")
12130 (define-key ctl-x-map "D" nil) ; For Emacs 20
12131 (define-key ctl-x-map "DA" 'diredp-add-to-dired-buffer) ; `C-x D A'
12132 (define-key ctl-x-map "DF" 'diredp-dired-for-files) ; `C-x D F'
12133 (define-key ctl-x-map "DR" 'diredp-dired-recent-dirs) ; `C-x D R'
12134 (define-key ctl-x-map "DS" 'diredp-fileset) ; `C-x D S'
12135 (define-key ctl-x-map "DU" 'diredp-dired-union)) ; `C-x D U'
12136
12137(unless (lookup-key ctl-x-4-map "D")
12138 (define-key ctl-x-4-map "D" nil) ; For Emacs 20
12139 (define-key ctl-x-4-map "DA" 'diredp-add-to-dired-buffer-other-window) ; `C-x 4 D A'
12140 (define-key ctl-x-4-map "DF" 'diredp-dired-for-files-other-window) ; `C-x 4 D F'
12141 (define-key ctl-x-4-map "DR" 'diredp-dired-recent-dirs-other-window) ; `C-x 4 D R'
12142 (define-key ctl-x-4-map "DS" 'diredp-fileset-other-window) ; `C-x 4 D S'
12143 (define-key ctl-x-4-map "DU" 'diredp-dired-union-other-window)) ; `C-x 4 D U'
12144
12145;; Navigation
12146(substitute-key-definition 'dired-up-directory 'diredp-up-directory dired-mode-map)
12147(substitute-key-definition 'dired-next-line 'diredp-next-line dired-mode-map)
12148(substitute-key-definition 'dired-previous-line 'diredp-previous-line dired-mode-map)
12149(substitute-key-definition 'dired-next-dirline 'diredp-next-dirline dired-mode-map)
12150(substitute-key-definition 'dired-prev-dirline 'diredp-prev-dirline dired-mode-map)
12151(substitute-key-definition 'dired-next-subdir 'diredp-next-subdir dired-mode-map)
12152(substitute-key-definition 'dired-prev-subdir 'diredp-prev-subdir dired-mode-map)
12153
12154
12155(define-key dired-mode-map [S-down-mouse-1] 'ignore) ; (normally `mouse-set-font')
12156;; `diredp-mouse-mark-region-files' provides Windows-Explorer behavior
12157;; for selecting (marking) files.
12158(define-key dired-mode-map [S-mouse-1] 'diredp-mouse-mark-region-files) ; `S-mouse-1'
12159(define-key dired-mode-map [mouse-2] 'dired-mouse-find-file-other-window) ; `mouse-2'
12160;; But be aware that `dired-sort-menu.el' binds `S-mouse-2' to `dired-sort-menu-popup'.
12161(define-key dired-mode-map [S-down-mouse-2] 'dired-mouse-find-file) ; `S-mouse-2'
12162(define-key dired-mode-map [S-mouse-2] 'ignore)
12163(define-key dired-mode-map [M-mouse-2] 'diredp-mouse-find-file-other-frame) ; `M-mouse-2'
12164
12165;; On Windows, bind more.
12166(eval-after-load "w32-browser"
12167 '(progn
12168 (define-key dired-mode-map [(control return)] 'dired-w32explore) ; `C-RET'
12169 (define-key dired-mode-map [(meta return)] 'dired-w32-browser) ; `M-RET'
12170 (define-key dired-mode-map [mouse-2] 'dired-mouse-w32-browser) ; `mouse-2'
12171 (define-key dired-mode-map (kbd "<C-M-return>") 'dired-multiple-w32-browser))) ; `C-M-RET'
12172
12173(when (fboundp 'diredp-w32-drives)
12174 (when (< emacs-major-version 21) (define-key dired-mode-map ":" nil)) ; For Emacs 20
12175 (define-key dired-mode-map ":/" 'diredp-w32-drives)) ; `:/'
12176
12177;; Other keyboard keys
12178(define-key dired-mode-map "@" 'diredp-do-apply-function) ; `@'
12179(define-key dired-mode-map "\$" 'diredp-hide-subdir-nomove) ; `$'
12180(define-key dired-mode-map "\M-$" 'dired-hide-subdir) ; `M-$'
12181(define-key dired-mode-map "=" 'diredp-ediff) ; `='
12182;; This replaces the `dired-x.el' binding of `dired-mark-extension'.
12183(define-key dired-mode-map "*." 'diredp-mark/unmark-extension) ; `* .'
12184(define-key dired-mode-map "*B" 'diredp-mark-autofiles) ; `* B'
12185(define-key dired-mode-map [(control meta ?*)] 'diredp-marked-other-window) ; `C-M-*'
12186(define-key dired-mode-map "\M-a" 'dired-do-search) ; `M-a'
12187(define-key dired-mode-map "\M-b" 'diredp-do-bookmark) ; `M-b'
12188(define-key dired-mode-map "\C-\M-b" 'diredp-set-bookmark-file-bookmark-for-marked) ; `C-M-b'
12189(when diredp-bind-problematic-terminal-keys
12190 (define-key dired-mode-map [(control meta shift ?b)] ; `C-M-B' (aka `C-M-S-b')
12191 'diredp-do-bookmark-in-bookmark-file))
12192(define-key dired-mode-map "e" 'diredp-visit-this-file) ; `e' (was `dired-find-file')
12193(define-key dired-mode-map [C-down] 'diredp-visit-next-file) ; `C-down' (was `forward-paragraph')
12194(define-key dired-mode-map [C-up] 'diredp-visit-previous-file) ; `C-up' (was `backward-paragraph')
12195(define-key dired-mode-map "\C-\M-G" 'diredp-do-grep) ; `C-M-G'
12196(when (fboundp 'mkhtml-dired-files) ; In `mkhtml.el'.
12197 (define-key dired-mode-map "\M-h" 'mkhtml-dired-files)) ; `M-h'
12198(define-key dired-mode-map "\C-\M-i" 'diredp-dired-inserted-subdirs) ; `C-M-i'
12199(define-key dired-mode-map "\M-q" (if (< emacs-major-version 21)
12200 'dired-do-query-replace
12201 'dired-do-query-replace-regexp)) ; `M-q'
12202(when diredp-bind-problematic-terminal-keys
12203 (define-key dired-mode-map [(control meta shift ?r)] ; `C-M-R' (aka `C-M-S-r')
12204 'diredp-toggle-find-file-reuse-dir))
12205(define-key dired-mode-map "U" 'dired-unmark-all-marks) ; `U'
12206(substitute-key-definition 'describe-mode 'diredp-describe-mode ; `h', `C-h m'
12207 dired-mode-map (current-global-map))
12208
12209;; Tags - same keys as in `*Bookmark List*'.
12210;;
12211;; NOTE: If this changes then need to update `dired-sort-menu+.el' to reflect the changes.
12212;;
12213(define-key dired-mode-map "T" nil) ; For Emacs 20
12214(define-key dired-mode-map "T+" 'diredp-tag-this-file) ; `T +'
12215(define-key dired-mode-map "T-" 'diredp-untag-this-file) ; `T -'
12216(define-key dired-mode-map "T0" 'diredp-remove-all-tags-this-file) ; `T 0'
12217(define-key dired-mode-map "Tc" 'diredp-copy-tags-this-file) ; `T c'
12218(define-key dired-mode-map "Tp" 'diredp-paste-add-tags-this-file) ; `T p'
12219(define-key dired-mode-map "Tq" 'diredp-paste-replace-tags-this-file) ; `T q'
12220(define-key dired-mode-map "Tv" 'diredp-set-tag-value-this-file) ; `T v'
12221(define-key dired-mode-map "T\M-w" 'diredp-copy-tags-this-file) ; `T M-w'
12222(define-key dired-mode-map "T\C-y" 'diredp-paste-add-tags-this-file) ; `T C-y'
12223(define-key dired-mode-map "T>+" 'diredp-do-tag) ; `T > +'
12224(define-key dired-mode-map "T>-" 'diredp-do-untag) ; `T > -'
12225(define-key dired-mode-map "T>0" 'diredp-do-remove-all-tags) ; `T > 0'
12226(define-key dired-mode-map "T>p" 'diredp-do-paste-add-tags) ; `T > p'
12227(define-key dired-mode-map "T>q" 'diredp-do-paste-replace-tags) ; `T > q'
12228(define-key dired-mode-map "T>v" 'diredp-do-set-tag-value) ; `T > v'
12229(define-key dired-mode-map "T>\C-y" 'diredp-do-paste-add-tags) ; `T > C-y'
12230(define-key dired-mode-map "Tm%" 'diredp-mark-files-tagged-regexp) ; `T m %'
12231(define-key dired-mode-map "Tm*" 'diredp-mark-files-tagged-all) ; `T m *'
12232(define-key dired-mode-map "Tm+" 'diredp-mark-files-tagged-some) ; `T m +'
12233(define-key dired-mode-map "Tm~*" 'diredp-mark-files-tagged-not-all) ; `T m ~ *'
12234(define-key dired-mode-map "Tm~+" 'diredp-mark-files-tagged-none) ; `T m ~ +'
12235(define-key dired-mode-map "Tu%" 'diredp-unmark-files-tagged-regexp) ; `T u %'
12236(define-key dired-mode-map "Tu*" 'diredp-unmark-files-tagged-all) ; `T u *'
12237(define-key dired-mode-map "Tu+" 'diredp-unmark-files-tagged-some) ; `T u +'
12238(define-key dired-mode-map "Tu~*" 'diredp-unmark-files-tagged-not-all) ; `T u ~ *'
12239(define-key dired-mode-map "Tu~+" 'diredp-unmark-files-tagged-none) ; `T u ~ +'
12240;; $$$$$$ (define-key dired-mode-map [(control ?+)] 'diredp-do-tag)
12241;; $$$$$$ (define-key dired-mode-map [(control ?-)] 'diredp-do-untag)
12242
12243
12244;; Vanilla Emacs binds `c' to `dired-do-compress-to'. Use `M-z' instead'.
12245;; (`dired-sort-menu.el' binds `c' to `dired-sort-menu-toggle-ignore-case'.)
12246;;
12247(when (fboundp 'dired-do-compress-to) ; Emacs 25+
12248 (define-key dired-mode-map (kbd "M-z") 'dired-do-compress-to))
12249
12250
12251;; Commands for operating on the current line's file. When possible,
12252;; these are lower-case versions of the upper-case commands for operating on
12253;; the marked files. (Most of the other corresponding lower-case letters are already
12254;; defined and cannot be used here.)
12255
12256;; $$$$$$ (define-key dired-mode-map [(control meta ?+)] 'diredp-tag-this-file)
12257;; $$$$$$ (define-key dired-mode-map [(control meta ?-)] 'diredp-untag-this-file)
12258(define-key dired-mode-map "\r" 'dired-find-file) ; `RET'
12259(when (fboundp 'diredp-describe-file)
12260 (define-key dired-mode-map (kbd "C-h RET") 'diredp-describe-file) ; `C-h RET'
12261 (define-key dired-mode-map (kbd "C-h C-<return>") 'diredp-describe-file)) ; `C-h C-RET'
12262(define-key dired-mode-map "%c" 'diredp-capitalize) ; `% c'
12263(define-key dired-mode-map "b" 'diredp-byte-compile-this-file) ; `b'
12264(define-key dired-mode-map [(control shift ?b)] 'diredp-bookmark-this-file) ; `C-B'
12265(define-key dired-mode-map "\M-c" 'diredp-capitalize-this-file) ; `M-c'
12266(when (and (fboundp 'diredp-chgrp-this-file) diredp-bind-problematic-terminal-keys)
12267 (define-key dired-mode-map [(control meta shift ?g)] 'diredp-chgrp-this-file)) ; `C-M-G' (aka `C-M-S-g')
12268(define-key dired-mode-map "\M-i" 'diredp-insert-subdirs) ; `M-i'
12269(define-key dired-mode-map "\M-l" 'diredp-downcase-this-file) ; `M-l'
12270(define-key dired-mode-map "\C-\M-l" 'diredp-list-marked) ; `C-M-l'
12271(when diredp-bind-problematic-terminal-keys
12272 (define-key dired-mode-map [(meta shift ?m)] 'diredp-chmod-this-file)) ; `M-M' (aka `M-S-m')
12273(define-key dired-mode-map "\C-o" 'diredp-find-file-other-frame) ; `C-o'
12274(when (and (fboundp 'diredp-chown-this-file) diredp-bind-problematic-terminal-keys)
12275 (define-key dired-mode-map [(meta shift ?o)] 'diredp-chown-this-file)) ; `M-O' (aka `M-S-o')
12276(define-key dired-mode-map "\C-\M-o" 'dired-display-file) ; `C-M-o' (not `C-o')
12277(define-key dired-mode-map "\M-p" 'diredp-print-this-file) ; `M-p'
12278(define-key dired-mode-map "r" 'diredp-rename-this-file) ; `r'
12279(when (fboundp 'image-dired-dired-display-image)
12280 (define-key dired-mode-map "\C-tI" 'diredp-image-show-this-file)) ; `C-t I'
12281(when diredp-bind-problematic-terminal-keys
12282 (define-key dired-mode-map [(meta shift ?t)] 'diredp-touch-this-file) ; `M-T' (aka `M-S-t')
12283 (define-key dired-mode-map [(control meta shift ?t)] 'dired-do-touch)) ; `C-M-T' (aka `C-M-S-t')
12284(define-key dired-mode-map "\M-u" 'diredp-upcase-this-file) ; `M-u'
12285(define-key dired-mode-map "y" 'diredp-relsymlink-this-file) ; `y'
12286(define-key dired-mode-map "\C-y" 'diredp-yank-files) ; `C-y'
12287(define-key dired-mode-map "z" 'diredp-compress-this-file) ; `z'
12288(when (fboundp 'dired-show-file-type)
12289 (define-key dired-mode-map "_" 'dired-show-file-type)) ; `_' (underscore)
12290(substitute-key-definition 'kill-line 'diredp-delete-this-file ; `C-k', `delete', `deleteline'
12291 dired-mode-map (current-global-map))
12292
12293
12294;; Commands that handle marked below, recursively.
12295;; Use `M-+' as a prefix key for all such commands.
12296
12297(define-prefix-command 'diredp-recursive-map)
12298(define-key dired-mode-map "\M-+" diredp-recursive-map) ; `M-+'
12299
12300(when (fboundp 'char-displayable-p) ; Emacs 22+
12301 (define-key diredp-recursive-map "\M-\C-?" 'diredp-unmark-all-files-recursive)) ; `M-DEL'
12302(define-key diredp-recursive-map "@" 'diredp-do-apply-function-recursive) ; `@'
12303(define-key diredp-recursive-map "#" 'diredp-flag-auto-save-files-recursive) ; `#'
12304(define-key diredp-recursive-map "*@" 'diredp-mark-symlinks-recursive) ; `* @'
12305(define-key diredp-recursive-map "**" 'diredp-mark-executables-recursive) ; `* *'
12306(define-key diredp-recursive-map "*/" 'diredp-mark-directories-recursive) ; `* /'
12307(define-key diredp-recursive-map "*." 'diredp-mark-extension-recursive) ; `* .'
12308(define-key diredp-recursive-map "*B" 'diredp-mark-autofiles-recursive) ; `* B'
12309(when (fboundp 'char-displayable-p) ; Emacs 22+
12310 (define-key diredp-recursive-map "*c" 'diredp-change-marks-recursive)) ; `* c'
12311(define-key diredp-recursive-map "*%" 'diredp-mark-files-regexp-recursive) ; `* %'
12312(when (> emacs-major-version 22)
12313 (define-key diredp-recursive-map ":d" 'diredp-do-decrypt-recursive) ; `: d'
12314 (define-key diredp-recursive-map ":e" 'diredp-do-encrypt-recursive) ; `: e'
12315 (define-key diredp-recursive-map ":s" 'diredp-do-sign-recursive) ; `: s'
12316 (define-key diredp-recursive-map ":v" 'diredp-do-verify-recursive)) ; `: v'
12317(define-key diredp-recursive-map "%c" 'diredp-capitalize-recursive) ; `% c'
12318(define-key diredp-recursive-map "%l" 'diredp-downcase-recursive) ; `% l'
12319(define-key diredp-recursive-map "%m" 'diredp-mark-files-regexp-recursive) ; `% m'
12320(define-key diredp-recursive-map "%u" 'diredp-upcase-recursive) ; `% u'
12321(when (fboundp 'dired-do-async-shell-command) ; Emacs 23+
12322 (define-key diredp-recursive-map "&" 'diredp-do-async-shell-command-recursive)) ; `&'
12323(define-key diredp-recursive-map "!" 'diredp-do-shell-command-recursive) ; `!'
12324(define-key diredp-recursive-map (kbd "C-M-*") 'diredp-marked-recursive-other-window) ; `C-M-*'
12325(define-key diredp-recursive-map "A" 'diredp-do-search-recursive) ; `A'
12326(define-key diredp-recursive-map "\M-b" 'diredp-do-bookmark-recursive) ; `M-b'
12327(when diredp-bind-problematic-terminal-keys
12328 (define-key diredp-recursive-map [(meta shift ?b)] ; `M-B' (aka `M-S-b')
12329 'diredp-do-bookmark-dirs-recursive))
12330(define-key diredp-recursive-map (kbd "C-M-b") ; `C-M-b'
12331 'diredp-set-bookmark-file-bookmark-for-marked-recursive)
12332(when diredp-bind-problematic-terminal-keys
12333 (define-key diredp-recursive-map [(control meta shift ?b)] ; `C-M-B' (aka `C-M-S-b')
12334 'diredp-do-bookmark-in-bookmark-file-recursive))
12335(define-key diredp-recursive-map "C" 'diredp-do-copy-recursive) ; `C'
12336(define-key diredp-recursive-map "D" 'diredp-do-delete-recursive) ; `D'
12337(define-key diredp-recursive-map "F" 'diredp-do-find-marked-files-recursive) ; `F'
12338(when (fboundp 'diredp-do-chgrp-recursive)
12339 (define-key diredp-recursive-map "G" 'diredp-do-chgrp-recursive)) ; `G'
12340(define-key diredp-recursive-map "\C-\M-G" 'diredp-do-grep-recursive) ; `C-M-G'
12341(define-key diredp-recursive-map "H" 'diredp-do-hardlink-recursive) ; `H'
12342(define-key diredp-recursive-map "\M-i" 'diredp-insert-subdirs-recursive) ; `M-i'
12343(define-key diredp-recursive-map "\C-\M-l" 'diredp-list-marked-recursive) ; `C-M-l'
12344(define-key diredp-recursive-map "M" 'diredp-do-chmod-recursive) ; `M'
12345(when (fboundp 'diredp-do-chown-recursive)
12346 (define-key diredp-recursive-map "O" 'diredp-do-chown-recursive)) ; `O'
12347(define-key diredp-recursive-map "P" 'diredp-do-print-recursive) ; `P'
12348(define-key diredp-recursive-map "Q" 'diredp-do-query-replace-regexp-recursive) ; `Q'
12349(define-key diredp-recursive-map "R" 'diredp-do-move-recursive) ; `R'
12350(define-key diredp-recursive-map "S" 'diredp-do-symlink-recursive) ; `S'
12351(define-key diredp-recursive-map (kbd "M-s a C-s") ; `M-s a C-s'
12352 'diredp-do-isearch-recursive)
12353(define-key diredp-recursive-map (kbd "M-s a C-M-s") ; `M-s a C-M-s'
12354 'diredp-do-isearch-regexp-recursive)
12355(when diredp-bind-problematic-terminal-keys
12356 (define-key diredp-recursive-map [(control meta shift ?t)]
12357 'diredp-do-touch-recursive)) ; `C-M-T' (aka `C-M-S-t')
12358(define-key diredp-recursive-map "\C-tc" 'diredp-image-dired-comment-files-recursive) ; `C-t c'
12359(define-key diredp-recursive-map "\C-td" 'diredp-image-dired-display-thumbs-recursive) ; `C-t d'
12360(define-key diredp-recursive-map "\C-tr" 'diredp-image-dired-delete-tag-recursive) ; `C-t r'
12361(define-key diredp-recursive-map "\C-tt" 'diredp-image-dired-tag-files-recursive) ; `C-t t'
12362(when (fboundp 'char-displayable-p) ; Emacs 22+
12363 (define-key diredp-recursive-map "U" 'diredp-unmark-all-marks-recursive)) ; `U'
12364(define-key diredp-recursive-map "\M-w" 'diredp-copy-filename-as-kill-recursive) ; `M-w'
12365(define-key diredp-recursive-map "Y" 'diredp-do-relsymlink-recursive) ; `Y'
12366
12367(eval-after-load "w32-browser"
12368 '(define-key diredp-recursive-map (kbd "<C-M-return>") 'diredp-multiple-w32-browser-recursive)) ; `C-M-RET'
12369
12370;; Undefine some bindings that would try to modify a Dired buffer. Their key sequences will
12371;; then appear to the user as available for local (Dired) definition.
12372(when (fboundp 'undefine-killer-commands) (undefine-killer-commands dired-mode-map))
12373
12374;;;;;;;;;;;;
12375
12376(setq diredp-loaded-p t)
12377
12378;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12379;;; dired+.el ends here