aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Kangas2022-08-16 17:14:33 +0200
committerStefan Kangas2022-08-17 16:21:09 +0200
commita6412b96e72c32ee981f469a564c8d2155d575aa (patch)
treea2342cddcb5a3a9e1849363f3f03c78e900a7a29
parentd214dd67cd5910c4c9ecefdf879886c4d01b0c27 (diff)
downloademacs-a6412b96e72c32ee981f469a564c8d2155d575aa.tar.gz
emacs-a6412b96e72c32ee981f469a564c8d2155d575aa.zip
Move dired-guess commands from dired-x to dired
* lisp/dired-x.el (dired-shell-command-history) (dired-guess-shell-alist-default, dired-guess-default) (dired-guess-shell-command): Move from here... * lisp/dired-aux.el (dired-shell-command-history) (dired-guess-shell-alist-default, dired-guess-default) (dired-guess-shell-command): ...to here. (Bug#21981) * lisp/dired-x.el (dired-guess-shell-gnutar) (dired-guess-shell-gzip-quiet, dired-guess-shell-znew-switches) (dired-guess-shell-case-fold-search, dired-guess-shell-alist-user): Move from here... * lisp/dired.el (dired-guess-shell-gnutar) (dired-guess-shell-gzip-quiet, dired-guess-shell-znew-switches) (dired-guess-shell-case-fold-search, dired-guess-shell-alist-user): ...to here. Change :group to dired-guess. (dired-guess): New defgroup. * test/lisp/dired-x-tests.el (dired-guess-default): Move from here... * test/lisp/dired-aux-tests.el (dired-guess-default): ...to here. * doc/misc/dired-x.texi (Features, Technical Details, Installation): Delete any mention of shell command guessing. (Shell Command Guessing): Move from here... * doc/emacs/dired.texi (Shell Command Guessing): ...to here. Adapt to better fit the Emacs Manual conventions. * lisp/dired-aux.el (dired-do-shell-command): Doc fix to adjust for above changes. * etc/NEWS: Announce the above change.
-rw-r--r--doc/emacs/dired.texi104
-rw-r--r--doc/misc/dired-x.texi112
-rw-r--r--etc/NEWS6
-rw-r--r--lisp/dired-aux.el259
-rw-r--r--lisp/dired-x.el325
-rw-r--r--lisp/dired.el71
-rw-r--r--test/lisp/dired-aux-tests.el13
-rw-r--r--test/lisp/dired-x-tests.el13
8 files changed, 453 insertions, 450 deletions
diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi
index 292c986c1c6..00028cac0fa 100644
--- a/doc/emacs/dired.texi
+++ b/doc/emacs/dired.texi
@@ -41,6 +41,7 @@ you to operate on the listed files. @xref{Directories}.
41* Operating on Files:: How to copy, rename, print, compress, etc. 41* Operating on Files:: How to copy, rename, print, compress, etc.
42 either one file or several files. 42 either one file or several files.
43* Shell Commands in Dired:: Running a shell command on the marked files. 43* Shell Commands in Dired:: Running a shell command on the marked files.
44* Shell Command Guessing:: Guessing shell commands for files.
44* Transforming File Names:: Using patterns to rename multiple files. 45* Transforming File Names:: Using patterns to rename multiple files.
45* Comparison in Dired:: Running @code{diff} by way of Dired. 46* Comparison in Dired:: Running @code{diff} by way of Dired.
46* Subdirectories in Dired:: Adding subdirectories to the Dired buffer. 47* Subdirectories in Dired:: Adding subdirectories to the Dired buffer.
@@ -1121,6 +1122,109 @@ buffer (@pxref{Dired Updating}).
1121 @xref{Single Shell}, for information about running shell commands 1122 @xref{Single Shell}, for information about running shell commands
1122outside Dired. 1123outside Dired.
1123 1124
1125@node Shell Command Guessing
1126@section Shell Command Guessing
1127@cindex guessing shell commands for files (in Dired)
1128
1129Based upon the name of a file, Dired tries to guess what shell command
1130you might want to apply to it. For example, if you have point on a
1131file named @file{foo.tar} and you press @kbd{!}, Dired will guess that
1132you want to run @samp{tar xvf}, and suggest that as the default shell
1133command.
1134
1135The default is mentioned in brackets and you can type @kbd{M-n} to get
1136the default into the minibuffer for editing. If there are several
1137commands for a given file, e.g., @samp{xtex} and @samp{dvips} for a
1138@file{.dvi} file, you can type @kbd{M-n} several times to see each of
1139the matching commands.
1140
1141Dired only tries to guess a command for a single file, never for a
1142list of marked files.
1143
1144The following variables control guessing of shell commands:
1145
1146@defvar dired-guess-shell-alist-default
1147This variable specifies the predefined rules for guessing shell
1148commands suitable for certain files. Set this to @code{nil} to turn
1149guessing off. The elements of @code{dired-guess-shell-alist-user}
1150(defined by the user) will override these rules.
1151@end defvar
1152
1153@defvar dired-guess-shell-alist-user
1154If non-@code{nil}, this variables specifies the user-defined alist of
1155file regexps and their suggested commands. These rules take
1156precedence over the predefined rules in the variable
1157@code{dired-guess-shell-alist-default} (to which they are prepended)
1158when @code{dired-do-shell-command} is run). The default is
1159@code{nil}.
1160
1161Each element of the alist looks like
1162
1163@example
1164(@var{regexp} @var{command}@dots{})
1165@end example
1166
1167@noindent
1168where each @var{command} can either be a string or a Lisp expression
1169that evaluates to a string. If several commands are given, all of
1170them will temporarily be pushed onto the history.
1171
1172A @samp{*} in the shell command stands for the file name that matched
1173@var{regexp}. When Emacs invokes the @var{command}, it replaces each
1174instance of @samp{*} with the matched file name.
1175
1176You can set this variable in your Init file. For example, to add
1177rules for @samp{.foo} and @samp{.bar} file extensions:
1178
1179@example
1180(setq dired-guess-shell-alist-user
1181 (list
1182 (list "\\.foo$" "@var{foo-command}") ; fixed rule
1183 ;; possibly more rules...
1184 (list "\\.bar$" ; rule with condition test
1185 '(if @var{condition}
1186 "@var{bar-command-1}"
1187 "@var{bar-command-2}"))))
1188@end example
1189
1190@noindent
1191This will override any predefined rules for the same extensions.
1192@end defvar
1193
1194@defvar dired-guess-shell-case-fold-search
1195If this variable is non-@code{nil},
1196@code{dired-guess-shell-alist-default} and
1197@code{dired-guess-shell-alist-user} are matched case-insensitively.
1198The default is @code{t}.
1199@end defvar
1200
1201@defvar dired-guess-shell-gnutar
1202If this variable is non-@code{nil}, it specifies the name of the GNU
1203Tar executable (e.g., @file{tar} or @file{gtar}). GNU Tar's @samp{z}
1204switch is used for compressed archives. If you don't have GNU Tar,
1205set this to @code{nil}: a pipe using @command{zcat} is then used
1206instead.
1207@end defvar
1208
1209@defvar dired-guess-shell-gzip-quiet
1210A non-@code{nil} value of this variable means that @samp{-q} is passed
1211to @command{gzip}, possibly overriding a verbose option in the
1212@env{GZIP} environment variable. The default is @code{t}.
1213@end defvar
1214
1215@defvar dired-guess-shell-znew-switches nil
1216This variable specifies a string of switches passed to @command{znew}.
1217An example is @samp{-K} which will make @command{znew} keep a
1218@file{.Z} file when it is smaller than the @file{.gz} file. The
1219default is @code{nil}: no additional switches are passed to
1220@command{znew}.
1221@end defvar
1222
1223@defvar dired-shell-command-history nil
1224This variable holds the history list for commands that read
1225dired-shell commands.
1226@end defvar
1227
1124@node Transforming File Names 1228@node Transforming File Names
1125@section Transforming File Names in Dired 1229@section Transforming File Names in Dired
1126 1230
diff --git a/doc/misc/dired-x.texi b/doc/misc/dired-x.texi
index 50d9914081c..002164ed91f 100644
--- a/doc/misc/dired-x.texi
+++ b/doc/misc/dired-x.texi
@@ -92,7 +92,6 @@ For @file{dired-x.el} as distributed with GNU Emacs @value{EMACSVER}.
92* Introduction:: 92* Introduction::
93* Installation:: 93* Installation::
94* Omitting Files in Dired:: 94* Omitting Files in Dired::
95* Shell Command Guessing::
96* Virtual Dired:: 95* Virtual Dired::
97* Advanced Mark Commands:: 96* Advanced Mark Commands::
98* Multiple Dired Directories:: 97* Multiple Dired Directories::
@@ -135,9 +134,6 @@ Some features provided by Dired Extra:
135Omitting uninteresting files from Dired listing 134Omitting uninteresting files from Dired listing
136(@pxref{Omitting Files in Dired}). 135(@pxref{Omitting Files in Dired}).
137@item 136@item
138Guessing shell commands in Dired buffers
139(@pxref{Shell Command Guessing}).
140@item
141Running Dired command in non-Dired buffers 137Running Dired command in non-Dired buffers
142(@pxref{Virtual Dired}). 138(@pxref{Virtual Dired}).
143@item 139@item
@@ -165,8 +161,6 @@ When @file{dired-x.el} is loaded, some standard Dired functions from
165Dired}), if it is active. @code{dired-find-buffer-nocreate} and 161Dired}), if it is active. @code{dired-find-buffer-nocreate} and
166@code{dired-initial-position} respect the value of 162@code{dired-initial-position} respect the value of
167@code{dired-find-subdir} (@pxref{Miscellaneous Commands}). 163@code{dired-find-subdir} (@pxref{Miscellaneous Commands}).
168@code{dired-read-shell-command} uses @code{dired-guess-shell-command}
169(@pxref{Shell Command Guessing}) to offer a smarter default command.
170 164
171@node Installation 165@node Installation
172@chapter Installation 166@chapter Installation
@@ -184,7 +178,6 @@ In your @file{~/.emacs} file, or in the system-wide initialization file
184(with-eval-after-load 'dired 178(with-eval-after-load 'dired
185 (require 'dired-x) 179 (require 'dired-x)
186 ;; Set dired-x global variables here. For example: 180 ;; Set dired-x global variables here. For example:
187 ;; (setq dired-guess-shell-gnutar "gtar")
188 ;; (setq dired-x-hands-off-my-keys nil) 181 ;; (setq dired-x-hands-off-my-keys nil)
189 )) 182 ))
190(add-hook 'dired-mode-hook 183(add-hook 'dired-mode-hook
@@ -436,111 +429,6 @@ Loading @file{dired-x.el} will install Dired Omit by putting
436call @code{dired-extra-startup}, which in turn calls @code{dired-omit-startup} 429call @code{dired-extra-startup}, which in turn calls @code{dired-omit-startup}
437in your @code{dired-mode-hook}. 430in your @code{dired-mode-hook}.
438 431
439@node Shell Command Guessing
440@chapter Shell Command Guessing
441@cindex guessing shell commands for files.
442
443Based upon the name of a file, Dired tries to guess what shell
444command you might want to apply to it. For example, if you have point
445on a file named @file{foo.tar} and you press @kbd{!}, Dired will guess
446you want to @samp{tar xvf} it and suggest that as the default shell
447command.
448
449The default is mentioned in brackets and you can type @kbd{M-n} to get
450the default into the minibuffer and then edit it, e.g., to change
451@samp{tar xvf} to @samp{tar tvf}. If there are several commands for a given
452file, e.g., @samp{xtex} and @samp{dvips} for a @file{.dvi} file, you can type
453@kbd{M-n} several times to see each of the matching commands.
454
455Dired only tries to guess a command for a single file, never for a list
456of marked files.
457
458The following variables control guessing of shell commands:
459
460@defvar dired-guess-shell-alist-default
461This variable specifies the predefined rules for guessing shell
462commands suitable for certain files. Set this to @code{nil} to turn
463guessing off. The elements of @code{dired-guess-shell-alist-user}
464(defined by the user) will override these rules.
465@end defvar
466
467@defvar dired-guess-shell-alist-user
468If non-@code{nil}, this variables specifies the user-defined alist of
469file regexps and their suggested commands. These rules take
470precedence over the predefined rules in the variable
471@code{dired-guess-shell-alist-default} (to which they are prepended)
472when @code{dired-do-shell-command} is run). The default is
473@code{nil}.
474
475Each element of the alist looks like
476
477@example
478(@var{regexp} @var{command}@dots{})
479@end example
480
481@noindent
482where each @var{command} can either be a string or a Lisp expression
483that evaluates to a string. If several commands are given, all of
484them will temporarily be pushed onto the history.
485
486A @samp{*} in the shell command stands for the file name that matched
487@var{regexp}. When Emacs invokes the @var{command}, it replaces each
488instance of @samp{*} with the matched file name.
489
490You can set this variable in your @file{~/.emacs}. For example,
491to add rules for @samp{.foo} and @samp{.bar} file extensions, write
492
493@example
494(setq dired-guess-shell-alist-user
495 (list
496 (list "\\.foo$" "@var{foo-command}");; fixed rule
497 ;; possibly more rules...
498 (list "\\.bar$";; rule with condition test
499 '(if @var{condition}
500 "@var{bar-command-1}"
501 "@var{bar-command-2}"))))
502@end example
503
504@noindent
505This will override any predefined rules for the same extensions.
506@end defvar
507
508@defvar dired-guess-shell-case-fold-search
509If this variable is non-@code{nil},
510@code{dired-guess-shell-alist-default} and
511@code{dired-guess-shell-alist-user} are matched case-insensitively.
512The default is @code{t}.
513@end defvar
514
515@cindex passing GNU Tar its @samp{z} switch.
516@defvar dired-guess-shell-gnutar
517If this variable is non-@code{nil}, it specifies the name of the GNU
518Tar executable (e.g., @file{tar} or @file{gnutar}). GNU Tar's
519@samp{z} switch is used for compressed archives. If you don't have
520GNU Tar, set this to @code{nil}: a pipe using @command{zcat} is then
521used instead. The default is @code{nil}.
522@end defvar
523
524@cindex @code{gzip}
525@defvar dired-guess-shell-gzip-quiet
526A non-@code{nil} value of this variable means that @samp{-q} is passed
527to @command{gzip}, possibly overriding a verbose option in the @env{GZIP}
528environment variable. The default is @code{t}.
529@end defvar
530
531@cindex @code{znew}
532@defvar dired-guess-shell-znew-switches nil
533This variable specifies a string of switches passed to @command{znew}.
534An example is @samp{-K} which will make @command{znew} keep a @file{.Z}
535file when it is smaller than the @file{.gz} file. The default is
536@code{nil}: no additional switches are passed to @command{znew}.
537@end defvar
538
539@defvar dired-shell-command-history nil
540This variable holds the history list for commands that read
541dired-shell commands.
542@end defvar
543
544@node Virtual Dired 432@node Virtual Dired
545@chapter Virtual Dired 433@chapter Virtual Dired
546 434
diff --git a/etc/NEWS b/etc/NEWS
index 5d87bc9e2eb..4b3a48a8206 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1159,6 +1159,12 @@ change the input method's translation rules, customize the user option
1159 1159
1160** Dired 1160** Dired
1161 1161
1162+++
1163*** 'dired-guess-shell-command' moved from dired-x to dired.
1164This means that 'dired-do-shell-command' will now provide smarter
1165defaults without first having to require 'dired-x'. See the node
1166"(emacs) Shell Command Guessing" in the Emacs manual for more details.
1167
1162--- 1168---
1163*** 'dired-clean-up-buffers-too' moved from dired-x to dired. 1169*** 'dired-clean-up-buffers-too' moved from dired-x to dired.
1164This means that Dired now offers to kill buffers visiting files and 1170This means that Dired now offers to kill buffers visiting files and
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 7ff3e333515..426273f65e8 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -1071,6 +1071,265 @@ Return the result of `process-file' - zero for success."
1071 res))))) 1071 res)))))
1072 1072
1073 1073
1074;;; Guess shell command
1075
1076;; * `dired-guess-shell-command' provides smarter defaults for
1077;; `dired-read-shell-command'.
1078;;
1079;; * `dired-guess-shell-command' calls `dired-guess-default' with list of
1080;; marked files.
1081;;
1082;; * Parse `dired-guess-shell-alist-user' and
1083;; `dired-guess-shell-alist-default' (in that order) for the first REGEXP
1084;; that matches the first file in the file list.
1085;;
1086;; * If the REGEXP matches all the entries of the file list then evaluate
1087;; COMMAND, which is either a string or a Lisp expression returning a
1088;; string. COMMAND may be a list of commands.
1089;;
1090;; * Return this command to `dired-guess-shell-command' which prompts user
1091;; with it. The list of commands is put into the list of default values.
1092;; If a command is used successfully then it is stored permanently in
1093;; `dired-shell-command-history'.
1094
1095;; Guess what shell command to apply to a file.
1096(defvar dired-shell-command-history nil
1097 "History list for commands that read dired-shell commands.")
1098
1099;; Default list of shell commands.
1100
1101;; NOTE: Use `gunzip -c' instead of `zcat' on `.gz' files. Some do not
1102;; install GNU zip's version of zcat.
1103
1104(autoload 'Man-support-local-filenames "man")
1105(autoload 'vc-responsible-backend "vc")
1106
1107(defvar dired-guess-shell-alist-default
1108 (list
1109 (list "\\.tar\\'"
1110 '(if dired-guess-shell-gnutar
1111 (concat dired-guess-shell-gnutar " xvf")
1112 "tar xvf")
1113 ;; Extract files into a separate subdirectory
1114 '(if dired-guess-shell-gnutar
1115 (concat "mkdir " (file-name-sans-extension file)
1116 "; " dired-guess-shell-gnutar " -C "
1117 (file-name-sans-extension file) " -xvf")
1118 (concat "mkdir " (file-name-sans-extension file)
1119 "; tar -C " (file-name-sans-extension file) " -xvf"))
1120 ;; List archive contents.
1121 '(if dired-guess-shell-gnutar
1122 (concat dired-guess-shell-gnutar " tvf")
1123 "tar tvf"))
1124
1125 ;; REGEXPS for compressed archives must come before the .Z rule to
1126 ;; be recognized:
1127 (list "\\.tar\\.Z\\'"
1128 ;; Untar it.
1129 '(if dired-guess-shell-gnutar
1130 (concat dired-guess-shell-gnutar " zxvf")
1131 (concat "zcat * | tar xvf -"))
1132 ;; Optional conversion to gzip format.
1133 '(concat "znew" (if dired-guess-shell-gzip-quiet " -q")
1134 " " dired-guess-shell-znew-switches))
1135
1136 ;; gzip'ed archives
1137 (list "\\.t\\(ar\\.\\)?gz\\'"
1138 '(if dired-guess-shell-gnutar
1139 (concat dired-guess-shell-gnutar " zxvf")
1140 (concat "gunzip -qc * | tar xvf -"))
1141 ;; Extract files into a separate subdirectory
1142 '(if dired-guess-shell-gnutar
1143 (concat "mkdir " (file-name-sans-extension file)
1144 "; " dired-guess-shell-gnutar " -C "
1145 (file-name-sans-extension file) " -zxvf")
1146 (concat "mkdir " (file-name-sans-extension file)
1147 "; gunzip -qc * | tar -C "
1148 (file-name-sans-extension file) " -xvf -"))
1149 ;; Optional decompression.
1150 '(concat "gunzip" (if dired-guess-shell-gzip-quiet " -q" ""))
1151 ;; List archive contents.
1152 '(if dired-guess-shell-gnutar
1153 (concat dired-guess-shell-gnutar " ztvf")
1154 (concat "gunzip -qc * | tar tvf -")))
1155
1156 ;; bzip2'ed archives
1157 (list "\\.t\\(ar\\.bz2\\|bz\\)\\'"
1158 "bunzip2 -c * | tar xvf -"
1159 ;; Extract files into a separate subdirectory
1160 '(concat "mkdir " (file-name-sans-extension file)
1161 "; bunzip2 -c * | tar -C "
1162 (file-name-sans-extension file) " -xvf -")
1163 ;; Optional decompression.
1164 "bunzip2")
1165
1166 ;; xz'ed archives
1167 (list "\\.t\\(ar\\.\\)?xz\\'"
1168 "unxz -c * | tar xvf -"
1169 ;; Extract files into a separate subdirectory
1170 '(concat "mkdir " (file-name-sans-extension file)
1171 "; unxz -c * | tar -C "
1172 (file-name-sans-extension file) " -xvf -")
1173 ;; Optional decompression.
1174 "unxz")
1175
1176 '("\\.shar\\.Z\\'" "zcat * | unshar")
1177 '("\\.shar\\.g?z\\'" "gunzip -qc * | unshar")
1178
1179 '("\\.e?ps\\'" "ghostview" "xloadimage" "lpr")
1180 (list "\\.e?ps\\.g?z\\'" "gunzip -qc * | ghostview -"
1181 ;; Optional decompression.
1182 '(concat "gunzip" (if dired-guess-shell-gzip-quiet " -q")))
1183 (list "\\.e?ps\\.Z\\'" "zcat * | ghostview -"
1184 ;; Optional conversion to gzip format.
1185 '(concat "znew" (if dired-guess-shell-gzip-quiet " -q")
1186 " " dired-guess-shell-znew-switches))
1187
1188 (list "\\.patch\\'"
1189 '(if (eq (ignore-errors (vc-responsible-backend default-directory)) 'Git)
1190 "cat * | git apply"
1191 "cat * | patch"))
1192 (list "\\.patch\\.g?z\\'" "gunzip -qc * | patch"
1193 ;; Optional decompression.
1194 '(concat "gunzip" (if dired-guess-shell-gzip-quiet " -q")))
1195 (list "\\.patch\\.Z\\'" "zcat * | patch"
1196 ;; Optional conversion to gzip format.
1197 '(concat "znew" (if dired-guess-shell-gzip-quiet " -q")
1198 " " dired-guess-shell-znew-switches))
1199
1200 ;; The following four extensions are useful with dired-man ("N" key)
1201 ;; FIXME "man ./" does not work with dired-do-shell-command,
1202 ;; because there seems to be no way for us to modify the filename,
1203 ;; only the command. Hmph. `dired-man' works though.
1204 (list "\\.\\(?:[0-9]\\|man\\)\\'"
1205 '(let ((loc (Man-support-local-filenames)))
1206 (cond ((eq loc 'man-db) "man -l")
1207 ((eq loc 'man) "man ./")
1208 (t
1209 "cat * | tbl | nroff -man -h | col -b"))))
1210 (list "\\.\\(?:[0-9]\\|man\\)\\.g?z\\'"
1211 '(let ((loc (Man-support-local-filenames)))
1212 (cond ((eq loc 'man-db)
1213 "man -l")
1214 ((eq loc 'man)
1215 "man ./")
1216 (t "gunzip -qc * | tbl | nroff -man -h | col -b")))
1217 ;; Optional decompression.
1218 '(concat "gunzip" (if dired-guess-shell-gzip-quiet " -q")))
1219 (list "\\.[0-9]\\.Z\\'"
1220 '(let ((loc (Man-support-local-filenames)))
1221 (cond ((eq loc 'man-db) "man -l")
1222 ((eq loc 'man) "man ./")
1223 (t "zcat * | tbl | nroff -man -h | col -b")))
1224 ;; Optional conversion to gzip format.
1225 '(concat "znew" (if dired-guess-shell-gzip-quiet " -q")
1226 " " dired-guess-shell-znew-switches))
1227 '("\\.pod\\'" "perldoc" "pod2man * | nroff -man")
1228
1229 '("\\.dvi\\'" "xdvi" "dvips") ; preview and printing
1230 '("\\.au\\'" "play") ; play Sun audiofiles
1231 '("\\.mpe?g\\'\\|\\.avi\\'" "xine -p")
1232 '("\\.ogg\\'" "ogg123")
1233 '("\\.mp3\\'" "mpg123")
1234 '("\\.wav\\'" "play")
1235 '("\\.uu\\'" "uudecode") ; for uudecoded files
1236 '("\\.hqx\\'" "mcvert")
1237 '("\\.sh\\'" "sh") ; execute shell scripts
1238 '("\\.xbm\\'" "bitmap") ; view X11 bitmaps
1239 '("\\.gp\\'" "gnuplot")
1240 '("\\.p[bgpn]m\\'" "xloadimage")
1241 '("\\.gif\\'" "xloadimage") ; view gif pictures
1242 '("\\.tif\\'" "xloadimage")
1243 '("\\.png\\'" "display") ; xloadimage 4.1 doesn't grok PNG
1244 '("\\.jpe?g\\'" "xloadimage")
1245 '("\\.fig\\'" "xfig") ; edit fig pictures
1246 '("\\.out\\'" "xgraph") ; for plotting purposes.
1247 '("\\.tex\\'" "latex" "tex")
1248 '("\\.texi\\(nfo\\)?\\'" "makeinfo" "texi2dvi")
1249 '("\\.pdf\\'" "xpdf")
1250 '("\\.doc\\'" "antiword" "strings")
1251 '("\\.rpm\\'" "rpm -qilp" "rpm -ivh")
1252 '("\\.dia\\'" "dia")
1253 '("\\.mgp\\'" "mgp")
1254
1255 ;; Some other popular archivers.
1256 (list "\\.zip\\'" "unzip" "unzip -l"
1257 ;; Extract files into a separate subdirectory
1258 '(concat "unzip" (if dired-guess-shell-gzip-quiet " -q")
1259 " -d " (file-name-sans-extension file)))
1260 '("\\.zoo\\'" "zoo x//")
1261 '("\\.lzh\\'" "lharc x")
1262 '("\\.arc\\'" "arc x")
1263 '("\\.shar\\'" "unshar")
1264 '("\\.rar\\'" "unrar x")
1265 '("\\.7z\\'" "7z x")
1266
1267 ;; Compression.
1268 (list "\\.g?z\\'" '(concat "gunzip" (if dired-guess-shell-gzip-quiet " -q")))
1269 (list "\\.dz\\'" "dictunzip")
1270 (list "\\.bz2\\'" "bunzip2")
1271 (list "\\.xz\\'" "unxz")
1272 (list "\\.Z\\'" "uncompress"
1273 ;; Optional conversion to gzip format.
1274 '(concat "znew" (if dired-guess-shell-gzip-quiet " -q")
1275 " " dired-guess-shell-znew-switches))
1276
1277 '("\\.sign?\\'" "gpg --verify"))
1278 "Default alist used for shell command guessing.
1279See `dired-guess-shell-alist-user'.")
1280
1281(defun dired-guess-default (files)
1282 "Return a shell command, or a list of commands, appropriate for FILES.
1283See `dired-guess-shell-alist-user'."
1284 (let* ((case-fold-search dired-guess-shell-case-fold-search)
1285 (programs
1286 (delete-dups
1287 (mapcar
1288 (lambda (command)
1289 (eval command `((file . ,(car files)))))
1290 (seq-reduce
1291 #'append
1292 (mapcar #'cdr
1293 (seq-filter (lambda (elem)
1294 (seq-every-p
1295 (lambda (file)
1296 (string-match-p (car elem) file))
1297 files))
1298 (append dired-guess-shell-alist-user
1299 dired-guess-shell-alist-default)))
1300 nil)))))
1301 (if (length= programs 1)
1302 (car programs)
1303 programs)))
1304
1305;;;###autoload
1306(defun dired-guess-shell-command (prompt files)
1307 "Ask user with PROMPT for a shell command, guessing a default from FILES."
1308 (let ((default (dired-guess-default files))
1309 default-list val)
1310 (if (null default)
1311 ;; Nothing to guess
1312 (read-shell-command prompt nil 'dired-shell-command-history)
1313 (setq prompt (replace-regexp-in-string ": $" " " prompt))
1314 (if (listp default)
1315 ;; More than one guess
1316 (setq default-list default
1317 default (car default)
1318 prompt (concat
1319 prompt
1320 (format "{%d guesses} " (length default-list))))
1321 ;; Just one guess
1322 (setq default-list (list default)))
1323 ;; Put the first guess in the prompt but not in the initial value.
1324 (setq prompt (concat prompt (format "[%s]: " default)))
1325 ;; All guesses can be retrieved with M-n
1326 (setq val (read-shell-command prompt nil
1327 'dired-shell-command-history
1328 default-list))
1329 ;; If we got a return, then return default.
1330 (if (equal val "") default val))))
1331
1332
1074;;; Commands that delete or redisplay part of the dired buffer 1333;;; Commands that delete or redisplay part of the dired buffer
1075 1334
1076(defun dired-kill-line (&optional arg) 1335(defun dired-kill-line (&optional arg)
diff --git a/lisp/dired-x.el b/lisp/dired-x.el
index 9edf8374815..cf1ef37694f 100644
--- a/lisp/dired-x.el
+++ b/lisp/dired-x.el
@@ -196,35 +196,6 @@ toggle between those two."
196 :type 'boolean 196 :type 'boolean
197 :group 'dired-x) 197 :group 'dired-x)
198 198
199(defcustom dired-guess-shell-gnutar
200 (catch 'found
201 (dolist (exe '("tar" "gtar"))
202 (if (with-temp-buffer
203 (ignore-errors (call-process exe nil t nil "--version"))
204 (and (re-search-backward "GNU tar" nil t) t))
205 (throw 'found exe))))
206 "If non-nil, name of GNU tar executable.
207\(E.g., \"tar\" or \"gtar\"). The `z' switch will be used with it for
208compressed or gzip'ed tar files. If you don't have GNU tar, set this
209to nil: a pipe using `zcat' or `gunzip -c' will be used."
210 ;; Changed from system-type test to testing --version output.
211 ;; Maybe test --help for -z instead?
212 :version "24.1"
213 :type '(choice (const :tag "Not GNU tar" nil)
214 (string :tag "Command name"))
215 :group 'dired-x)
216
217(defcustom dired-guess-shell-gzip-quiet t
218 "Non-nil says pass -q to gzip overriding verbose GZIP environment."
219 :type 'boolean
220 :group 'dired-x)
221
222(defcustom dired-guess-shell-znew-switches nil
223 "If non-nil, then string of switches passed to `znew', example: \"-K\"."
224 :type '(choice (const :tag "None" nil)
225 (string :tag "Switches"))
226 :group 'dired-x)
227
228 199
229;;; Key bindings 200;;; Key bindings
230 201
@@ -727,302 +698,6 @@ Also useful for `auto-mode-alist' like this:
727 (shell-command command output-buffer error-buffer))) 698 (shell-command command output-buffer error-buffer)))
728 699
729 700
730;;; Guess shell command
731
732;; Brief Description:
733;;
734;; * `dired-do-shell-command' is bound to `!' by dired.el.
735;;
736;; * `dired-guess-shell-command' provides smarter defaults for
737;; dired-aux.el's `dired-read-shell-command'.
738;;
739;; * `dired-guess-shell-command' calls `dired-guess-default' with list of
740;; marked files.
741;;
742;; * Parse `dired-guess-shell-alist-user' and
743;; `dired-guess-shell-alist-default' (in that order) for the first REGEXP
744;; that matches the first file in the file list.
745;;
746;; * If the REGEXP matches all the entries of the file list then evaluate
747;; COMMAND, which is either a string or a Lisp expression returning a
748;; string. COMMAND may be a list of commands.
749;;
750;; * Return this command to `dired-guess-shell-command' which prompts user
751;; with it. The list of commands is put into the list of default values.
752;; If a command is used successfully then it is stored permanently in
753;; `dired-shell-command-history'.
754
755;; Guess what shell command to apply to a file.
756(defvar dired-shell-command-history nil
757 "History list for commands that read dired-shell commands.")
758
759;; Default list of shell commands.
760
761;; NOTE: Use `gunzip -c' instead of `zcat' on `.gz' files. Some do not
762;; install GNU zip's version of zcat.
763
764(autoload 'Man-support-local-filenames "man")
765(autoload 'vc-responsible-backend "vc")
766
767(defvar dired-guess-shell-alist-default
768 (list
769 (list "\\.tar\\'"
770 '(if dired-guess-shell-gnutar
771 (concat dired-guess-shell-gnutar " xvf")
772 "tar xvf")
773 ;; Extract files into a separate subdirectory
774 '(if dired-guess-shell-gnutar
775 (concat "mkdir " (file-name-sans-extension file)
776 "; " dired-guess-shell-gnutar " -C "
777 (file-name-sans-extension file) " -xvf")
778 (concat "mkdir " (file-name-sans-extension file)
779 "; tar -C " (file-name-sans-extension file) " -xvf"))
780 ;; List archive contents.
781 '(if dired-guess-shell-gnutar
782 (concat dired-guess-shell-gnutar " tvf")
783 "tar tvf"))
784
785 ;; REGEXPS for compressed archives must come before the .Z rule to
786 ;; be recognized:
787 (list "\\.tar\\.Z\\'"
788 ;; Untar it.
789 '(if dired-guess-shell-gnutar
790 (concat dired-guess-shell-gnutar " zxvf")
791 (concat "zcat * | tar xvf -"))
792 ;; Optional conversion to gzip format.
793 '(concat "znew" (if dired-guess-shell-gzip-quiet " -q")
794 " " dired-guess-shell-znew-switches))
795
796 ;; gzip'ed archives
797 (list "\\.t\\(ar\\.\\)?gz\\'"
798 '(if dired-guess-shell-gnutar
799 (concat dired-guess-shell-gnutar " zxvf")
800 (concat "gunzip -qc * | tar xvf -"))
801 ;; Extract files into a separate subdirectory
802 '(if dired-guess-shell-gnutar
803 (concat "mkdir " (file-name-sans-extension file)
804 "; " dired-guess-shell-gnutar " -C "
805 (file-name-sans-extension file) " -zxvf")
806 (concat "mkdir " (file-name-sans-extension file)
807 "; gunzip -qc * | tar -C "
808 (file-name-sans-extension file) " -xvf -"))
809 ;; Optional decompression.
810 '(concat "gunzip" (if dired-guess-shell-gzip-quiet " -q" ""))
811 ;; List archive contents.
812 '(if dired-guess-shell-gnutar
813 (concat dired-guess-shell-gnutar " ztvf")
814 (concat "gunzip -qc * | tar tvf -")))
815
816 ;; bzip2'ed archives
817 (list "\\.t\\(ar\\.bz2\\|bz\\)\\'"
818 "bunzip2 -c * | tar xvf -"
819 ;; Extract files into a separate subdirectory
820 '(concat "mkdir " (file-name-sans-extension file)
821 "; bunzip2 -c * | tar -C "
822 (file-name-sans-extension file) " -xvf -")
823 ;; Optional decompression.
824 "bunzip2")
825
826 ;; xz'ed archives
827 (list "\\.t\\(ar\\.\\)?xz\\'"
828 "unxz -c * | tar xvf -"
829 ;; Extract files into a separate subdirectory
830 '(concat "mkdir " (file-name-sans-extension file)
831 "; unxz -c * | tar -C "
832 (file-name-sans-extension file) " -xvf -")
833 ;; Optional decompression.
834 "unxz")
835
836 '("\\.shar\\.Z\\'" "zcat * | unshar")
837 '("\\.shar\\.g?z\\'" "gunzip -qc * | unshar")
838
839 '("\\.e?ps\\'" "ghostview" "xloadimage" "lpr")
840 (list "\\.e?ps\\.g?z\\'" "gunzip -qc * | ghostview -"
841 ;; Optional decompression.
842 '(concat "gunzip" (if dired-guess-shell-gzip-quiet " -q")))
843 (list "\\.e?ps\\.Z\\'" "zcat * | ghostview -"
844 ;; Optional conversion to gzip format.
845 '(concat "znew" (if dired-guess-shell-gzip-quiet " -q")
846 " " dired-guess-shell-znew-switches))
847
848 (list "\\.patch\\'"
849 '(if (eq (ignore-errors (vc-responsible-backend default-directory)) 'Git)
850 "cat * | git apply"
851 "cat * | patch"))
852 (list "\\.patch\\.g?z\\'" "gunzip -qc * | patch"
853 ;; Optional decompression.
854 '(concat "gunzip" (if dired-guess-shell-gzip-quiet " -q")))
855 (list "\\.patch\\.Z\\'" "zcat * | patch"
856 ;; Optional conversion to gzip format.
857 '(concat "znew" (if dired-guess-shell-gzip-quiet " -q")
858 " " dired-guess-shell-znew-switches))
859
860 ;; The following four extensions are useful with dired-man ("N" key)
861 ;; FIXME "man ./" does not work with dired-do-shell-command,
862 ;; because there seems to be no way for us to modify the filename,
863 ;; only the command. Hmph. `dired-man' works though.
864 (list "\\.\\(?:[0-9]\\|man\\)\\'"
865 '(let ((loc (Man-support-local-filenames)))
866 (cond ((eq loc 'man-db) "man -l")
867 ((eq loc 'man) "man ./")
868 (t
869 "cat * | tbl | nroff -man -h | col -b"))))
870 (list "\\.\\(?:[0-9]\\|man\\)\\.g?z\\'"
871 '(let ((loc (Man-support-local-filenames)))
872 (cond ((eq loc 'man-db)
873 "man -l")
874 ((eq loc 'man)
875 "man ./")
876 (t "gunzip -qc * | tbl | nroff -man -h | col -b")))
877 ;; Optional decompression.
878 '(concat "gunzip" (if dired-guess-shell-gzip-quiet " -q")))
879 (list "\\.[0-9]\\.Z\\'"
880 '(let ((loc (Man-support-local-filenames)))
881 (cond ((eq loc 'man-db) "man -l")
882 ((eq loc 'man) "man ./")
883 (t "zcat * | tbl | nroff -man -h | col -b")))
884 ;; Optional conversion to gzip format.
885 '(concat "znew" (if dired-guess-shell-gzip-quiet " -q")
886 " " dired-guess-shell-znew-switches))
887 '("\\.pod\\'" "perldoc" "pod2man * | nroff -man")
888
889 '("\\.dvi\\'" "xdvi" "dvips") ; preview and printing
890 '("\\.au\\'" "play") ; play Sun audiofiles
891 '("\\.mpe?g\\'\\|\\.avi\\'" "xine -p")
892 '("\\.ogg\\'" "ogg123")
893 '("\\.mp3\\'" "mpg123")
894 '("\\.wav\\'" "play")
895 '("\\.uu\\'" "uudecode") ; for uudecoded files
896 '("\\.hqx\\'" "mcvert")
897 '("\\.sh\\'" "sh") ; execute shell scripts
898 '("\\.xbm\\'" "bitmap") ; view X11 bitmaps
899 '("\\.gp\\'" "gnuplot")
900 '("\\.p[bgpn]m\\'" "xloadimage")
901 '("\\.gif\\'" "xloadimage") ; view gif pictures
902 '("\\.tif\\'" "xloadimage")
903 '("\\.png\\'" "display") ; xloadimage 4.1 doesn't grok PNG
904 '("\\.jpe?g\\'" "xloadimage")
905 '("\\.fig\\'" "xfig") ; edit fig pictures
906 '("\\.out\\'" "xgraph") ; for plotting purposes.
907 '("\\.tex\\'" "latex" "tex")
908 '("\\.texi\\(nfo\\)?\\'" "makeinfo" "texi2dvi")
909 '("\\.pdf\\'" "xpdf")
910 '("\\.doc\\'" "antiword" "strings")
911 '("\\.rpm\\'" "rpm -qilp" "rpm -ivh")
912 '("\\.dia\\'" "dia")
913 '("\\.mgp\\'" "mgp")
914
915 ;; Some other popular archivers.
916 (list "\\.zip\\'" "unzip" "unzip -l"
917 ;; Extract files into a separate subdirectory
918 '(concat "unzip" (if dired-guess-shell-gzip-quiet " -q")
919 " -d " (file-name-sans-extension file)))
920 '("\\.zoo\\'" "zoo x//")
921 '("\\.lzh\\'" "lharc x")
922 '("\\.arc\\'" "arc x")
923 '("\\.shar\\'" "unshar")
924 '("\\.rar\\'" "unrar x")
925 '("\\.7z\\'" "7z x")
926
927 ;; Compression.
928 (list "\\.g?z\\'" '(concat "gunzip" (if dired-guess-shell-gzip-quiet " -q")))
929 (list "\\.dz\\'" "dictunzip")
930 (list "\\.bz2\\'" "bunzip2")
931 (list "\\.xz\\'" "unxz")
932 (list "\\.Z\\'" "uncompress"
933 ;; Optional conversion to gzip format.
934 '(concat "znew" (if dired-guess-shell-gzip-quiet " -q")
935 " " dired-guess-shell-znew-switches))
936
937 '("\\.sign?\\'" "gpg --verify"))
938
939 "Default alist used for shell command guessing.
940See `dired-guess-shell-alist-user'.")
941
942(defcustom dired-guess-shell-alist-user nil
943 "User-defined alist of rules for suggested commands.
944These rules take precedence over the predefined rules in the variable
945`dired-guess-shell-alist-default' (to which they are prepended).
946
947Each element of this list looks like
948
949 (REGEXP COMMAND...)
950
951COMMAND will be used if REGEXP matches the file to be processed.
952If several files are to be processed, REGEXP has to match all the
953files.
954
955Each COMMAND can either be a string or a Lisp expression that evaluates
956to a string. If this expression needs to consult the name of the file for
957which the shell commands are being requested, it can access that file name
958as the variable `file'.
959
960If several COMMANDs are given, the first one will be the default
961and the rest will be added temporarily to the history and can be retrieved
962with `previous-history-element' (\\<minibuffer-mode-map>\\[previous-history-element]).
963
964The variable `dired-guess-shell-case-fold-search' controls whether
965REGEXP is matched case-sensitively."
966 :group 'dired-x
967 :type '(alist :key-type regexp :value-type (repeat sexp)))
968
969(defcustom dired-guess-shell-case-fold-search t
970 "If non-nil, `dired-guess-shell-alist-default' and
971`dired-guess-shell-alist-user' are matched case-insensitively."
972 :group 'dired-x
973 :type 'boolean)
974
975(defun dired-guess-default (files)
976 "Return a shell command, or a list of commands, appropriate for FILES.
977See `dired-guess-shell-alist-user'."
978 (let* ((case-fold-search dired-guess-shell-case-fold-search)
979 (programs
980 (delete-dups
981 (mapcar
982 (lambda (command)
983 (eval command `((file . ,(car files)))))
984 (seq-reduce
985 #'append
986 (mapcar #'cdr
987 (seq-filter (lambda (elem)
988 (seq-every-p
989 (lambda (file)
990 (string-match-p (car elem) file))
991 files))
992 (append dired-guess-shell-alist-user
993 dired-guess-shell-alist-default)))
994 nil)))))
995 (if (length= programs 1)
996 (car programs)
997 programs)))
998
999(defun dired-guess-shell-command (prompt files)
1000 "Ask user with PROMPT for a shell command, guessing a default from FILES."
1001 (let ((default (dired-guess-default files))
1002 default-list val)
1003 (if (null default)
1004 ;; Nothing to guess
1005 (read-shell-command prompt nil 'dired-shell-command-history)
1006 (setq prompt (replace-regexp-in-string ": $" " " prompt))
1007 (if (listp default)
1008 ;; More than one guess
1009 (setq default-list default
1010 default (car default)
1011 prompt (concat
1012 prompt
1013 (format "{%d guesses} " (length default-list))))
1014 ;; Just one guess
1015 (setq default-list (list default)))
1016 ;; Put the first guess in the prompt but not in the initial value.
1017 (setq prompt (concat prompt (format "[%s]: " default)))
1018 ;; All guesses can be retrieved with M-n
1019 (setq val (read-shell-command prompt nil
1020 'dired-shell-command-history
1021 default-list))
1022 ;; If we got a return, then return default.
1023 (if (equal val "") default val))))
1024
1025
1026;;; Visit all marked files simultaneously 701;;; Visit all marked files simultaneously
1027 702
1028;; Brief Description: 703;; Brief Description:
diff --git a/lisp/dired.el b/lisp/dired.el
index 10813e56dff..799a9f4716b 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -53,6 +53,11 @@
53 :prefix "dired-" 53 :prefix "dired-"
54 :group 'dired) 54 :group 'dired)
55 55
56(defgroup dired-guess nil
57 "Guess shell command in Dired."
58 :prefix "dired-"
59 :group 'dired)
60
56;;;###autoload 61;;;###autoload
57(defcustom dired-listing-switches (purecopy "-al") 62(defcustom dired-listing-switches (purecopy "-al")
58 "Switches passed to `ls' for Dired. MUST contain the `l' option. 63 "Switches passed to `ls' for Dired. MUST contain the `l' option.
@@ -419,6 +424,72 @@ is anywhere on its Dired line, except the beginning of the line."
419 :type 'boolean 424 :type 'boolean
420 :version "28.1") 425 :version "28.1")
421 426
427(defcustom dired-guess-shell-case-fold-search t
428 "If non-nil, `dired-guess-shell-alist-default' and
429`dired-guess-shell-alist-user' are matched case-insensitively."
430 :group 'dired-guess
431 :type 'boolean
432 :version "29.1")
433
434(defcustom dired-guess-shell-alist-user nil
435 "User-defined alist of rules for suggested commands.
436These rules take precedence over the predefined rules in the variable
437`dired-guess-shell-alist-default' (to which they are prepended).
438
439Each element of this list looks like
440
441 (REGEXP COMMAND...)
442
443COMMAND will be used if REGEXP matches the file to be processed.
444If several files are to be processed, REGEXP has to match all the
445files.
446
447Each COMMAND can either be a string or a Lisp expression that evaluates
448to a string. If this expression needs to consult the name of the file for
449which the shell commands are being requested, it can access that file name
450as the variable `file'.
451
452If several COMMANDs are given, the first one will be the default
453and the rest will be added temporarily to the history and can be retrieved
454with `previous-history-element' (\\<minibuffer-mode-map>\\[previous-history-element]).
455
456The variable `dired-guess-shell-case-fold-search' controls whether
457REGEXP is matched case-sensitively."
458 :group 'dired-guess
459 :type '(alist :key-type regexp :value-type (repeat sexp))
460 :version "29.1")
461
462(defcustom dired-guess-shell-gnutar
463 (catch 'found
464 (dolist (exe '("tar" "gtar"))
465 (if (with-temp-buffer
466 (ignore-errors (call-process exe nil t nil "--version"))
467 (and (re-search-backward "GNU tar" nil t) t))
468 (throw 'found exe))))
469 "If non-nil, name of GNU tar executable.
470\(E.g., \"tar\" or \"gtar\"). The `z' switch will be used with it for
471compressed or gzip'ed tar files. If you don't have GNU tar, set this
472to nil: a pipe using `zcat' or `gunzip -c' will be used."
473 ;; Changed from system-type test to testing --version output.
474 ;; Maybe test --help for -z instead?
475 :group 'dired-guess
476 :type '(choice (const :tag "Not GNU tar" nil)
477 (string :tag "Command name"))
478 :version "29.1")
479
480(defcustom dired-guess-shell-gzip-quiet t
481 "Non-nil says pass -q to gzip overriding verbose GZIP environment."
482 :group 'dired-guess
483 :type 'boolean
484 :version "29.1")
485
486(defcustom dired-guess-shell-znew-switches nil
487 "If non-nil, then string of switches passed to `znew', example: \"-K\"."
488 :group 'dired-guess
489 :type '(choice (const :tag "None" nil)
490 (string :tag "Switches"))
491 :version "29.1")
492
422 493
423;;; Internal variables 494;;; Internal variables
424 495
diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el
index 694deaae4c2..e70898ab74e 100644
--- a/test/lisp/dired-aux-tests.el
+++ b/test/lisp/dired-aux-tests.el
@@ -154,5 +154,18 @@
154 (should (string-match (regexp-quote command) (nth 0 lines))) 154 (should (string-match (regexp-quote command) (nth 0 lines)))
155 (dired-test--check-highlighting (nth 0 lines) '(8)))) 155 (dired-test--check-highlighting (nth 0 lines) '(8))))
156 156
157(ert-deftest dired-guess-default ()
158 (let ((dired-guess-shell-alist-user nil)
159 (dired-guess-shell-alist-default
160 '(("\\.png\\'" "display")
161 ("\\.gif\\'" "display" "xloadimage")
162 ("\\.gif\\'" "feh")
163 ("\\.jpe?g\\'" "xloadimage"))))
164 (should (equal (dired-guess-default '("/tmp/foo.png")) "display"))
165 (should (equal (dired-guess-default '("/tmp/foo.gif"))
166 '("display" "xloadimage" "feh")))
167 (should (equal (dired-guess-default '("/tmp/foo.png" "/tmp/foo.txt"))
168 nil))))
169
157(provide 'dired-aux-tests) 170(provide 'dired-aux-tests)
158;;; dired-aux-tests.el ends here 171;;; dired-aux-tests.el ends here
diff --git a/test/lisp/dired-x-tests.el b/test/lisp/dired-x-tests.el
index cec266b0ef9..7acaa3c1319 100644
--- a/test/lisp/dired-x-tests.el
+++ b/test/lisp/dired-x-tests.el
@@ -47,19 +47,6 @@
47 (should (equal all-but-c 47 (should (equal all-but-c
48 (sort (dired-get-marked-files 'local) #'string<)))))) 48 (sort (dired-get-marked-files 'local) #'string<))))))
49 49
50(ert-deftest dired-guess-default ()
51 (let ((dired-guess-shell-alist-user nil)
52 (dired-guess-shell-alist-default
53 '(("\\.png\\'" "display")
54 ("\\.gif\\'" "display" "xloadimage")
55 ("\\.gif\\'" "feh")
56 ("\\.jpe?g\\'" "xloadimage"))))
57 (should (equal (dired-guess-default '("/tmp/foo.png")) "display"))
58 (should (equal (dired-guess-default '("/tmp/foo.gif"))
59 '("display" "xloadimage" "feh")))
60 (should (equal (dired-guess-default '("/tmp/foo.png" "/tmp/foo.txt"))
61 nil))))
62
63(ert-deftest dired-x--string-to-number () 50(ert-deftest dired-x--string-to-number ()
64 (should (= (dired-x--string-to-number "2.4K") 2457.6)) 51 (should (= (dired-x--string-to-number "2.4K") 2457.6))
65 (should (= (dired-x--string-to-number "2400") 2400)) 52 (should (= (dired-x--string-to-number "2400") 2400))