diff options
| author | Stefan Kangas | 2022-08-16 17:14:33 +0200 |
|---|---|---|
| committer | Stefan Kangas | 2022-08-17 16:21:09 +0200 |
| commit | a6412b96e72c32ee981f469a564c8d2155d575aa (patch) | |
| tree | a2342cddcb5a3a9e1849363f3f03c78e900a7a29 | |
| parent | d214dd67cd5910c4c9ecefdf879886c4d01b0c27 (diff) | |
| download | emacs-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.texi | 104 | ||||
| -rw-r--r-- | doc/misc/dired-x.texi | 112 | ||||
| -rw-r--r-- | etc/NEWS | 6 | ||||
| -rw-r--r-- | lisp/dired-aux.el | 259 | ||||
| -rw-r--r-- | lisp/dired-x.el | 325 | ||||
| -rw-r--r-- | lisp/dired.el | 71 | ||||
| -rw-r--r-- | test/lisp/dired-aux-tests.el | 13 | ||||
| -rw-r--r-- | test/lisp/dired-x-tests.el | 13 |
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 |
| 1122 | outside Dired. | 1123 | outside Dired. |
| 1123 | 1124 | ||
| 1125 | @node Shell Command Guessing | ||
| 1126 | @section Shell Command Guessing | ||
| 1127 | @cindex guessing shell commands for files (in Dired) | ||
| 1128 | |||
| 1129 | Based upon the name of a file, Dired tries to guess what shell command | ||
| 1130 | you might want to apply to it. For example, if you have point on a | ||
| 1131 | file named @file{foo.tar} and you press @kbd{!}, Dired will guess that | ||
| 1132 | you want to run @samp{tar xvf}, and suggest that as the default shell | ||
| 1133 | command. | ||
| 1134 | |||
| 1135 | The default is mentioned in brackets and you can type @kbd{M-n} to get | ||
| 1136 | the default into the minibuffer for editing. If there are several | ||
| 1137 | commands 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 | ||
| 1139 | the matching commands. | ||
| 1140 | |||
| 1141 | Dired only tries to guess a command for a single file, never for a | ||
| 1142 | list of marked files. | ||
| 1143 | |||
| 1144 | The following variables control guessing of shell commands: | ||
| 1145 | |||
| 1146 | @defvar dired-guess-shell-alist-default | ||
| 1147 | This variable specifies the predefined rules for guessing shell | ||
| 1148 | commands suitable for certain files. Set this to @code{nil} to turn | ||
| 1149 | guessing 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 | ||
| 1154 | If non-@code{nil}, this variables specifies the user-defined alist of | ||
| 1155 | file regexps and their suggested commands. These rules take | ||
| 1156 | precedence over the predefined rules in the variable | ||
| 1157 | @code{dired-guess-shell-alist-default} (to which they are prepended) | ||
| 1158 | when @code{dired-do-shell-command} is run). The default is | ||
| 1159 | @code{nil}. | ||
| 1160 | |||
| 1161 | Each element of the alist looks like | ||
| 1162 | |||
| 1163 | @example | ||
| 1164 | (@var{regexp} @var{command}@dots{}) | ||
| 1165 | @end example | ||
| 1166 | |||
| 1167 | @noindent | ||
| 1168 | where each @var{command} can either be a string or a Lisp expression | ||
| 1169 | that evaluates to a string. If several commands are given, all of | ||
| 1170 | them will temporarily be pushed onto the history. | ||
| 1171 | |||
| 1172 | A @samp{*} in the shell command stands for the file name that matched | ||
| 1173 | @var{regexp}. When Emacs invokes the @var{command}, it replaces each | ||
| 1174 | instance of @samp{*} with the matched file name. | ||
| 1175 | |||
| 1176 | You can set this variable in your Init file. For example, to add | ||
| 1177 | rules 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 | ||
| 1191 | This will override any predefined rules for the same extensions. | ||
| 1192 | @end defvar | ||
| 1193 | |||
| 1194 | @defvar dired-guess-shell-case-fold-search | ||
| 1195 | If 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. | ||
| 1198 | The default is @code{t}. | ||
| 1199 | @end defvar | ||
| 1200 | |||
| 1201 | @defvar dired-guess-shell-gnutar | ||
| 1202 | If this variable is non-@code{nil}, it specifies the name of the GNU | ||
| 1203 | Tar executable (e.g., @file{tar} or @file{gtar}). GNU Tar's @samp{z} | ||
| 1204 | switch is used for compressed archives. If you don't have GNU Tar, | ||
| 1205 | set this to @code{nil}: a pipe using @command{zcat} is then used | ||
| 1206 | instead. | ||
| 1207 | @end defvar | ||
| 1208 | |||
| 1209 | @defvar dired-guess-shell-gzip-quiet | ||
| 1210 | A non-@code{nil} value of this variable means that @samp{-q} is passed | ||
| 1211 | to @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 | ||
| 1216 | This variable specifies a string of switches passed to @command{znew}. | ||
| 1217 | An 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 | ||
| 1219 | default is @code{nil}: no additional switches are passed to | ||
| 1220 | @command{znew}. | ||
| 1221 | @end defvar | ||
| 1222 | |||
| 1223 | @defvar dired-shell-command-history nil | ||
| 1224 | This variable holds the history list for commands that read | ||
| 1225 | dired-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: | |||
| 135 | Omitting uninteresting files from Dired listing | 134 | Omitting uninteresting files from Dired listing |
| 136 | (@pxref{Omitting Files in Dired}). | 135 | (@pxref{Omitting Files in Dired}). |
| 137 | @item | 136 | @item |
| 138 | Guessing shell commands in Dired buffers | ||
| 139 | (@pxref{Shell Command Guessing}). | ||
| 140 | @item | ||
| 141 | Running Dired command in non-Dired buffers | 137 | Running 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 | |||
| 165 | Dired}), if it is active. @code{dired-find-buffer-nocreate} and | 161 | Dired}), 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 | |||
| 436 | call @code{dired-extra-startup}, which in turn calls @code{dired-omit-startup} | 429 | call @code{dired-extra-startup}, which in turn calls @code{dired-omit-startup} |
| 437 | in your @code{dired-mode-hook}. | 430 | in 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 | |||
| 443 | Based upon the name of a file, Dired tries to guess what shell | ||
| 444 | command you might want to apply to it. For example, if you have point | ||
| 445 | on a file named @file{foo.tar} and you press @kbd{!}, Dired will guess | ||
| 446 | you want to @samp{tar xvf} it and suggest that as the default shell | ||
| 447 | command. | ||
| 448 | |||
| 449 | The default is mentioned in brackets and you can type @kbd{M-n} to get | ||
| 450 | the 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 | ||
| 452 | file, 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 | |||
| 455 | Dired only tries to guess a command for a single file, never for a list | ||
| 456 | of marked files. | ||
| 457 | |||
| 458 | The following variables control guessing of shell commands: | ||
| 459 | |||
| 460 | @defvar dired-guess-shell-alist-default | ||
| 461 | This variable specifies the predefined rules for guessing shell | ||
| 462 | commands suitable for certain files. Set this to @code{nil} to turn | ||
| 463 | guessing 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 | ||
| 468 | If non-@code{nil}, this variables specifies the user-defined alist of | ||
| 469 | file regexps and their suggested commands. These rules take | ||
| 470 | precedence over the predefined rules in the variable | ||
| 471 | @code{dired-guess-shell-alist-default} (to which they are prepended) | ||
| 472 | when @code{dired-do-shell-command} is run). The default is | ||
| 473 | @code{nil}. | ||
| 474 | |||
| 475 | Each element of the alist looks like | ||
| 476 | |||
| 477 | @example | ||
| 478 | (@var{regexp} @var{command}@dots{}) | ||
| 479 | @end example | ||
| 480 | |||
| 481 | @noindent | ||
| 482 | where each @var{command} can either be a string or a Lisp expression | ||
| 483 | that evaluates to a string. If several commands are given, all of | ||
| 484 | them will temporarily be pushed onto the history. | ||
| 485 | |||
| 486 | A @samp{*} in the shell command stands for the file name that matched | ||
| 487 | @var{regexp}. When Emacs invokes the @var{command}, it replaces each | ||
| 488 | instance of @samp{*} with the matched file name. | ||
| 489 | |||
| 490 | You can set this variable in your @file{~/.emacs}. For example, | ||
| 491 | to 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 | ||
| 505 | This will override any predefined rules for the same extensions. | ||
| 506 | @end defvar | ||
| 507 | |||
| 508 | @defvar dired-guess-shell-case-fold-search | ||
| 509 | If 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. | ||
| 512 | The default is @code{t}. | ||
| 513 | @end defvar | ||
| 514 | |||
| 515 | @cindex passing GNU Tar its @samp{z} switch. | ||
| 516 | @defvar dired-guess-shell-gnutar | ||
| 517 | If this variable is non-@code{nil}, it specifies the name of the GNU | ||
| 518 | Tar 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 | ||
| 520 | GNU Tar, set this to @code{nil}: a pipe using @command{zcat} is then | ||
| 521 | used instead. The default is @code{nil}. | ||
| 522 | @end defvar | ||
| 523 | |||
| 524 | @cindex @code{gzip} | ||
| 525 | @defvar dired-guess-shell-gzip-quiet | ||
| 526 | A non-@code{nil} value of this variable means that @samp{-q} is passed | ||
| 527 | to @command{gzip}, possibly overriding a verbose option in the @env{GZIP} | ||
| 528 | environment variable. The default is @code{t}. | ||
| 529 | @end defvar | ||
| 530 | |||
| 531 | @cindex @code{znew} | ||
| 532 | @defvar dired-guess-shell-znew-switches nil | ||
| 533 | This variable specifies a string of switches passed to @command{znew}. | ||
| 534 | An example is @samp{-K} which will make @command{znew} keep a @file{.Z} | ||
| 535 | file 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 | ||
| 540 | This variable holds the history list for commands that read | ||
| 541 | dired-shell commands. | ||
| 542 | @end defvar | ||
| 543 | |||
| 544 | @node Virtual Dired | 432 | @node Virtual Dired |
| 545 | @chapter Virtual Dired | 433 | @chapter Virtual Dired |
| 546 | 434 | ||
| @@ -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. | ||
| 1164 | This means that 'dired-do-shell-command' will now provide smarter | ||
| 1165 | defaults 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. |
| 1164 | This means that Dired now offers to kill buffers visiting files and | 1170 | This 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. | ||
| 1279 | See `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. | ||
| 1283 | See `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 | ||
| 208 | compressed or gzip'ed tar files. If you don't have GNU tar, set this | ||
| 209 | to 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. | ||
| 940 | See `dired-guess-shell-alist-user'.") | ||
| 941 | |||
| 942 | (defcustom dired-guess-shell-alist-user nil | ||
| 943 | "User-defined alist of rules for suggested commands. | ||
| 944 | These rules take precedence over the predefined rules in the variable | ||
| 945 | `dired-guess-shell-alist-default' (to which they are prepended). | ||
| 946 | |||
| 947 | Each element of this list looks like | ||
| 948 | |||
| 949 | (REGEXP COMMAND...) | ||
| 950 | |||
| 951 | COMMAND will be used if REGEXP matches the file to be processed. | ||
| 952 | If several files are to be processed, REGEXP has to match all the | ||
| 953 | files. | ||
| 954 | |||
| 955 | Each COMMAND can either be a string or a Lisp expression that evaluates | ||
| 956 | to a string. If this expression needs to consult the name of the file for | ||
| 957 | which the shell commands are being requested, it can access that file name | ||
| 958 | as the variable `file'. | ||
| 959 | |||
| 960 | If several COMMANDs are given, the first one will be the default | ||
| 961 | and the rest will be added temporarily to the history and can be retrieved | ||
| 962 | with `previous-history-element' (\\<minibuffer-mode-map>\\[previous-history-element]). | ||
| 963 | |||
| 964 | The variable `dired-guess-shell-case-fold-search' controls whether | ||
| 965 | REGEXP 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. | ||
| 977 | See `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. | ||
| 436 | These rules take precedence over the predefined rules in the variable | ||
| 437 | `dired-guess-shell-alist-default' (to which they are prepended). | ||
| 438 | |||
| 439 | Each element of this list looks like | ||
| 440 | |||
| 441 | (REGEXP COMMAND...) | ||
| 442 | |||
| 443 | COMMAND will be used if REGEXP matches the file to be processed. | ||
| 444 | If several files are to be processed, REGEXP has to match all the | ||
| 445 | files. | ||
| 446 | |||
| 447 | Each COMMAND can either be a string or a Lisp expression that evaluates | ||
| 448 | to a string. If this expression needs to consult the name of the file for | ||
| 449 | which the shell commands are being requested, it can access that file name | ||
| 450 | as the variable `file'. | ||
| 451 | |||
| 452 | If several COMMANDs are given, the first one will be the default | ||
| 453 | and the rest will be added temporarily to the history and can be retrieved | ||
| 454 | with `previous-history-element' (\\<minibuffer-mode-map>\\[previous-history-element]). | ||
| 455 | |||
| 456 | The variable `dired-guess-shell-case-fold-search' controls whether | ||
| 457 | REGEXP 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 | ||
| 471 | compressed or gzip'ed tar files. If you don't have GNU tar, set this | ||
| 472 | to 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)) |