X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/ab606888d5599f15d6a99b507d1d37e7b21bff79..937640a621a4ce2e5e56eaecca37a2a28a584318:/lisp/dired-x.el diff --git a/lisp/dired-x.el b/lisp/dired-x.el index a68772491b..6b44b73b17 100644 --- a/lisp/dired-x.el +++ b/lisp/dired-x.el @@ -1,13 +1,13 @@ -;;; dired-x.el --- Extra Dired functionality -*-byte-compile-dynamic: t;-*- +;;; dired-x.el --- extra Dired functionality -*-byte-compile-dynamic: t;-*- ;; Author: Sebastian Kremer ;; Lawrence R. Dodd -;; Maintainer: FSF (unless Dodd can be found) +;; Maintainer: nobody (want to volunteer?) ;; Version: 2.37+ ;; Date: 1994/08/18 19:27:42 ;; Keywords: dired extensions files -;; Copyright (C) 1993, 1994, 1997, 2001 Free Software Foundation, Inc. +;; Copyright (C) 1993, 1994, 1997, 2001, 2003, 2004 Free Software Foundation, Inc. ;; This file is part of GNU Emacs. @@ -33,9 +33,9 @@ ;; been removed or renamed in order to work properly with dired of GNU ;; Emacs. All suggestions or comments are most welcomed. -;; +;; ;; Please, PLEASE, *PLEASE* see the info pages. -;; +;; ;; BUGS: Type M-x dired-x-submit-report and a report will be generated. @@ -50,7 +50,7 @@ ;; (add-hook 'dired-mode-hook ;; (function (lambda () ;; ;; Set buffer-local variables here. For example: -;; ;; (setq dired-omit-files-p t) +;; ;; (dired-omit-mode 1) ;; ))) ;; ;; At load time dired-x.el will install itself, redefine some functions, and @@ -74,7 +74,7 @@ ;; dired-guess-shell-znew-switches ;; dired-guess-shell-alist-user ;; dired-clean-up-buffers-too -;; dired-omit-files-p +;; dired-omit-mode ;; dired-omit-files ;; dired-omit-extensions ;; dired-omit-size-limit @@ -154,19 +154,27 @@ Read-only folders only work in VM 5, not in VM 4." (other :tag "non-writable only" if-file-read-only)) :group 'dired-x) -(defcustom dired-omit-files-p nil - "*If non-nil, \"uninteresting\" files are not listed (buffer-local). -Use \\[dired-omit-toggle] to toggle its value. +(define-minor-mode dired-omit-mode + "Toggle Dired-Omit mode. +With numeric ARG, enable Dired-Omit mode if ARG is positive, disable +otherwise. Enabling and disabling is buffer-local. +If enabled, \"uninteresting\" files are not listed. Uninteresting files are those whose filenames match regexp `dired-omit-files', plus those ending with extensions in `dired-omit-extensions'." - :type 'boolean - :group 'dired-x) -(make-variable-buffer-local 'dired-omit-files-p) + :group 'dired-x + (if dired-omit-mode + ;; This will mention how many lines were omitted: + (let ((dired-omit-size-limit nil)) (dired-omit-expunge)) + (revert-buffer))) + +;; For backward compatibility +(defvaralias 'dired-omit-files-p 'dired-omit-mode) +(make-obsolete-variable 'dired-omit-files-p 'dired-omit-mode) (defcustom dired-omit-files "^\\.?#\\|^\\.$\\|^\\.\\.$" "*Filenames matching this regexp will not be displayed. -This only has effect when `dired-omit-files-p' is t. See interactive function -`dired-omit-toggle' \(\\[dired-omit-toggle]\) and variable +This only has effect when `dired-omit-mode' is t. See interactive function +`dired-omit-mode' \(\\[dired-omit-mode]\) and variable `dired-omit-extensions'. The default is to omit `.', `..', auto-save files and lock files." :type 'regexp @@ -230,7 +238,8 @@ to nil: a pipe using `zcat' or `gunzip -c' will be used." ;;; KEY BINDINGS. -(define-key dired-mode-map "\M-o" 'dired-omit-toggle) +(define-key dired-mode-map "\M-o" 'dired-omit-mode) +(define-key dired-mode-map "*O" 'dired-mark-omitted) (define-key dired-mode-map "\M-(" 'dired-mark-sexp) (define-key dired-mode-map "*(" 'dired-mark-sexp) (define-key dired-mode-map "*." 'dired-mark-extension) @@ -268,7 +277,7 @@ to nil: a pipe using `zcat' or `gunzip -c' will be used." \\[dired-info]\t-- run info on file \\[dired-man]\t-- run man on file \\[dired-do-find-marked-files]\t-- visit all marked files simultaneously - \\[dired-omit-toggle]\t-- toggle omitting of files + \\[dired-omit-mode]\t-- toggle omitting of files \\[dired-mark-sexp]\t-- mark by Lisp expression \\[dired-copy-filename-as-kill]\t-- copy the file or subdir names into the kill ring. \t You can feed it to other commands using \\[yank]. @@ -280,7 +289,7 @@ For more features, see variables `dired-bind-info' `dired-bind-man' `dired-vm-read-only-folders' - `dired-omit-files-p' + `dired-omit-mode' `dired-omit-files' `dired-omit-extensions' `dired-omit-size-limit' @@ -398,7 +407,7 @@ See variable `dired-patch-unclean-extensions'." (defun dired-clean-tex () "Flag dispensable files created by [La]TeX etc. for deletion. -See variables `dired-texinfo-unclean-extensions', +See variables `dired-tex-unclean-extensions', `dired-latex-unclean-extensions', `dired-bibtex-unclean-extensions' and `dired-texinfo-unclean-extensions'." (interactive) @@ -450,9 +459,9 @@ buffer and try again." (dired-insert-subdir (file-name-directory file)) (dired-goto-file file)) ;; Toggle omitting, if it is on, and try again. - (if dired-omit-files-p + (if dired-omit-mode (progn - (dired-omit-toggle) + (dired-omit-mode) (dired-goto-file file)))))))) (defun dired-jump-other-window () @@ -460,35 +469,6 @@ buffer and try again." (interactive) (dired-jump t)) -;;; COPY NAMES OF MARKED FILES INTO KILL-RING. - -(defun dired-copy-filename-as-kill (&optional arg) - "Copy names of marked (or next ARG) files into the kill ring. -The names are separated by a space. -With a zero prefix arg, use the complete pathname of each marked file. -With \\[universal-argument], use the relative pathname of each marked file. - -If on a subdir headerline, use subdirname instead; prefix arg is ignored -in this case. - -You can then feed the file name(s) to other commands with \\[yank]." - (interactive "P") - (let ((string - (or (dired-get-subdir) - (mapconcat (function identity) - (if arg - (cond ((zerop (prefix-numeric-value arg)) - (dired-get-marked-files)) - ((integerp arg) - (dired-get-marked-files 'no-dir arg)) - (t ; else a raw arg - (dired-get-marked-files t))) - (dired-get-marked-files 'no-dir)) - " ")))) - (kill-new string) - (message "%s" string))) - - ;;; OMITTING. ;;; Enhanced omitting of lines from directory listings. @@ -499,8 +479,8 @@ You can then feed the file name(s) to other commands with \\[yank]." (defvar dired-omit-localp 'no-dir "The LOCALP argument `dired-omit-expunge' passes to `dired-get-filename'. If it is 'no-dir, omitting is much faster, but you can only match -against the basename of the file. Set it to nil if you need to match the -whole pathname.") +against the non-directory part of the file name. Set it to nil if you +need to match the entire file name.") ;; \017=^O for Omit - other packages can chose other control characters. (defvar dired-omit-marker-char ?\017 @@ -508,31 +488,18 @@ whole pathname.") Should never be used as marker by the user or other packages.") (defun dired-omit-startup () - (or (assq 'dired-omit-files-p minor-mode-alist) + (or (assq 'dired-omit-mode minor-mode-alist) (setq minor-mode-alist - (append '((dired-omit-files-p + (append '((dired-omit-mode (:eval (if (eq major-mode 'dired-mode) " Omit" "")))) minor-mode-alist)))) -(defun dired-omit-toggle (&optional flag) - "Toggle omitting files matching `dired-omit-files' and `dired-omit-extensions'. -With an arg, and if omitting was off, don't toggle and just mark the - files but don't actually omit them. -With an arg, and if omitting was on, turn it off but don't refresh the buffer." - (interactive "P") - (if flag - (if dired-omit-files-p - (setq dired-omit-files-p (not dired-omit-files-p)) - (dired-mark-unmarked-files (dired-omit-regexp) nil nil - dired-omit-localp)) - ;; no FLAG - (setq dired-omit-files-p (not dired-omit-files-p)) - (if (not dired-omit-files-p) - (revert-buffer) - ;; this will mention how many were omitted: - (let ((dired-omit-size-limit nil)) - (dired-omit-expunge))))) +(defun dired-mark-omitted () + "Mark files matching `dired-omit-files' and `dired-omit-extensions'." + (interactive) + (let ((dired-omit-mode nil)) (revert-buffer)) ;; Show omitted files + (dired-mark-unmarked-files (dired-omit-regexp) nil nil dired-omit-localp)) (defvar dired-omit-extensions (append completion-ignored-extensions @@ -544,12 +511,12 @@ Defaults to elements of `completion-ignored-extensions', `dired-latex-unclean-extensions', `dired-bibtex-unclean-extensions', and `dired-texinfo-unclean-extensions'. -See interactive function `dired-omit-toggle' \(\\[dired-omit-toggle]\) and -variables `dired-omit-files-p' and `dired-omit-files'.") +See interactive function `dired-omit-mode' \(\\[dired-omit-mode]\) and +variables `dired-omit-mode' and `dired-omit-files'.") (defun dired-omit-expunge (&optional regexp) "Erases all unmarked files matching REGEXP. -Does nothing if global variable `dired-omit-files-p' is nil, or if called +Does nothing if global variable `dired-omit-mode' is nil, or if called non-interactively and buffer is bigger than `dired-omit-size-limit'. If REGEXP is nil or not specified, uses `dired-omit-files', and also omits filenames ending in `dired-omit-extensions'. @@ -558,14 +525,14 @@ If REGEXP is the empty string, this function is a no-op. This functions works by temporarily binding `dired-marker-char' to `dired-omit-marker-char' and calling `dired-do-kill-lines'." (interactive "sOmit files (regexp): ") - (if (and dired-omit-files-p + (if (and dired-omit-mode (or (interactive-p) (not dired-omit-size-limit) (< (buffer-size) dired-omit-size-limit) (progn (message "Not omitting: directory larger than %d characters." dired-omit-size-limit) - (setq dired-omit-files-p nil) + (setq dired-omit-mode nil) nil))) (let ((omit-re (or regexp (dired-omit-regexp))) (old-modified-p (buffer-modified-p)) @@ -599,7 +566,7 @@ This functions works by temporarily binding `dired-marker-char' to ;; Returns t if any work was done, nil otherwise. (defun dired-mark-unmarked-files (regexp msg &optional unflag-p localp) "Mark unmarked files matching REGEXP, displaying MSG. -REGEXP is matched against the complete pathname. +REGEXP is matched against the entire file name. Does not re-mark files which already have a mark. With prefix argument, unflag all those files. Second optional argument LOCALP is as in `dired-get-filename'." @@ -618,7 +585,7 @@ Second optional argument LOCALP is as in `dired-get-filename'." (defun dired-omit-new-add-entry (filename &optional marker-char relative) ;; This redefines dired-aux.el's dired-add-entry to avoid calling ls for ;; files that are going to be omitted anyway. - (if dired-omit-files-p + (if dired-omit-mode ;; perhaps return t without calling ls (let ((omit-re (dired-omit-regexp))) (if (or (string= omit-re "") @@ -871,7 +838,7 @@ dired." (save-excursion (set-buffer (get-buffer-create " *dot-dired*")) (erase-buffer) - (insert "Local Variables:\ndired-omit-files-p: t\nEnd:\n") + (insert "Local Variables:\ndired-omit-mode: t\nEnd:\n") (write-file dired-local-variables-file) (kill-buffer (current-buffer))) @@ -916,9 +883,17 @@ dired." (defvar dired-guess-shell-alist-default (list - (list "\\.tar$" '(if dired-guess-shell-gnutar - (concat dired-guess-shell-gnutar " xvf") - "tar xvf")) + (list "\\.tar$" + '(if dired-guess-shell-gnutar + (concat dired-guess-shell-gnutar " xvf") + "tar xvf") + ;; Extract files into a separate subdirectory + '(if dired-guess-shell-gnutar + (concat "mkdir " (file-name-sans-extension file) + "; " dired-guess-shell-gnutar " -C " + (file-name-sans-extension file) " -xvf") + (concat "mkdir " (file-name-sans-extension file) + "; tar -C " (file-name-sans-extension file) " -xvf"))) ;; REGEXPS for compressed archives must come before the .Z rule to ;; be recognized: @@ -936,31 +911,67 @@ dired." '(if dired-guess-shell-gnutar (concat dired-guess-shell-gnutar " zxvf") (concat "gunzip -qc * | tar xvf -")) + ;; Extract files into a separate subdirectory + '(if dired-guess-shell-gnutar + (concat "mkdir " (file-name-sans-extension file) + "; " dired-guess-shell-gnutar " -C " + (file-name-sans-extension file) " -zxvf") + (concat "mkdir " (file-name-sans-extension file) + "; gunzip -qc * | tar -C " + (file-name-sans-extension file) " -xvf -")) ;; Optional decompression. '(concat "gunzip" (if dired-guess-shell-gzip-quiet " -q" ""))) + ;; bzip2'ed archives - (list "\\.tar\\.bz2$" + (list "\\.t\\(ar\\.bz2\\|bz\\)$" "bunzip2 -c * | tar xvf -" + ;; Extract files into a separate subdirectory + '(concat "mkdir " (file-name-sans-extension file) + "; bunzip2 -c * | tar -C " + (file-name-sans-extension file) " -xvf -") ;; Optional decompression. "bunzip2") - '("\\.shar.Z$" "zcat * | unshar") - '("\\.shar.g?z$" "gunzip -qc * | unshar") + '("\\.shar\\.Z$" "zcat * | unshar") + '("\\.shar\\.g?z$" "gunzip -qc * | unshar") '("\\.e?ps$" "ghostview" "xloadimage" "lpr") - (list "\\.e?ps.g?z$" "gunzip -qc * | ghostview -" + (list "\\.e?ps\\.g?z$" "gunzip -qc * | ghostview -" ;; Optional decompression. '(concat "gunzip" (if dired-guess-shell-gzip-quiet " -q"))) - (list "\\.e?ps.Z$" "zcat * | ghostview -" + (list "\\.e?ps\\.Z$" "zcat * | ghostview -" ;; Optional conversion to gzip format. '(concat "znew" (if dired-guess-shell-gzip-quiet " -q") " " dired-guess-shell-znew-switches)) + '("\\.patch$" "cat * | patch") - '("\\.patch.g?z$" "gunzip -qc * | patch") - (list "\\.patch.Z$" "zcat * | patch" + (list "\\.patch\\.g?z$" "gunzip -qc * | patch" + ;; Optional decompression. + '(concat "gunzip" (if dired-guess-shell-gzip-quiet " -q"))) + (list "\\.patch\\.Z$" "zcat * | patch" + ;; Optional conversion to gzip format. + '(concat "znew" (if dired-guess-shell-gzip-quiet " -q") + " " dired-guess-shell-znew-switches)) + + ;; The following four extensions are useful with dired-man ("N" key) + (list "\\.[0-9]$" '(progn (require 'man) + (if (Man-support-local-filenames) + "man -l" + "cat * | tbl | nroff -man -h"))) + (list "\\.[0-9]\\.g?z$" '(progn (require 'man) + (if (Man-support-local-filenames) + "man -l" + "gunzip -qc * | tbl | nroff -man -h")) + ;; Optional decompression. + '(concat "gunzip" (if dired-guess-shell-gzip-quiet " -q"))) + (list "\\.[0-9]\\.Z$" '(progn (require 'man) + (if (Man-support-local-filenames) + "man -l" + "zcat * | tbl | nroff -man -h")) ;; Optional conversion to gzip format. '(concat "znew" (if dired-guess-shell-gzip-quiet " -q") " " dired-guess-shell-znew-switches)) + '("\\.pod$" "perldoc" "pod2man * | nroff -man") '("\\.dvi$" "xdvi" "dvips") ; preview and printing '("\\.au$" "play") ; play Sun audiofiles @@ -974,7 +985,7 @@ dired." '("\\.gif$" "xloadimage") ; view gif pictures '("\\.tif$" "xloadimage") '("\\.png$" "display") ; xloadimage 4.1 doesn't grok PNG - '("\\.jpg$" "xloadimage") + '("\\.jpe?g$" "xloadimage") '("\\.fig$" "xfig") ; edit fig pictures '("\\.out$" "xgraph") ; for plotting purposes. '("\\.tex$" "latex" "tex") @@ -982,14 +993,18 @@ dired." '("\\.pdf$" "xpdf") ; edit PDF files ;; Some other popular archivers. + (list "\\.zip$" "unzip" + ;; Extract files into a separate subdirectory + '(concat "unzip" (if dired-guess-shell-gzip-quiet " -q") + " -d " (file-name-sans-extension file))) '("\\.zoo$" "zoo x//") - '("\\.zip$" "unzip") '("\\.lzh$" "lharc x") '("\\.arc$" "arc x") '("\\.shar$" "unshar") ;; Compression. (list "\\.g?z$" '(concat "gunzip" (if dired-guess-shell-gzip-quiet " -q"))) + (list "\\.dz$" "dictunzip") (list "\\.bz2$" "bunzip2") (list "\\.Z$" "uncompress" ;; Optional conversion to gzip format. @@ -1027,11 +1042,17 @@ You can set this variable in your ~/.emacs. For example, to add rules for :group 'dired-x :type '(alist :key-type regexp :value-type (repeat sexp))) +(defcustom dired-guess-shell-case-fold-search t + "If non-nil, `dired-guess-shell-alist-default' and +`dired-guess-shell-alist-user' are matched case-insensitively." + :group 'dired-x + :type 'boolean) + (defun dired-guess-default (files) "Guess a shell commands for FILES. Return command or list of commands. See `dired-guess-shell-alist-user'." - (let* ((case-fold-search nil) ; case-sensitive matching + (let* ((case-fold-search dired-guess-shell-case-fold-search) ;; Prepend the user's alist to the default alist. (alist (append dired-guess-shell-alist-user dired-guess-shell-alist-default)) @@ -1151,7 +1172,7 @@ results in file2 (expand-file-name file2) len1 (length file1) len2 (length file2)) - ;; Find common initial pathname components: + ;; Find common initial file name components: (let (next) (while (and (setq next (string-match "/" file1 index)) (setq next (1+ next)) @@ -1169,7 +1190,7 @@ results in sub (substring file1 0 index) name1 (substring file1 index))) (if (string-equal sub "/") - ;; No common initial pathname found + ;; No common initial file name found (setq name1 file1) ;; Else they have a common parent directory (let ((tem (substring file2 index)) @@ -1197,19 +1218,19 @@ This creates relative symbolic links like not absolute ones like - foo -> /ugly/path/that/may/change/any/day/bar/foo" + foo -> /ugly/file/name/that/may/change/any/day/bar/foo" (interactive "P") (dired-do-create-files 'relsymlink (function dired-make-relative-symlink) "RelSymLink" arg dired-keep-marker-relsymlink)) -(defun dired-do-relsymlink-regexp (regexp newname &optional whole-path) +(defun dired-do-relsymlink-regexp (regexp newname &optional whole-name) "RelSymlink all marked files containing REGEXP to NEWNAME. See functions `dired-do-rename-regexp' and `dired-do-relsymlink' for more info." (interactive (dired-mark-read-regexp "RelSymLink")) (dired-do-create-files-regexp (function dired-make-relative-symlink) - "RelSymLink" nil regexp newname whole-path dired-keep-marker-relsymlink)) + "RelSymLink" nil regexp newname whole-name dired-keep-marker-relsymlink)) ;;; VISIT ALL MARKED FILES SIMULTANEOUSLY. @@ -1303,8 +1324,10 @@ NOSELECT the files are merely found but not selected." Uses ../lisp/man.el of \\[manual-entry] fame." (interactive) (require 'man) - (let ((file (dired-get-filename)) - (manual-program "nroff -man -h")) + (let* ((file (dired-get-filename)) + (manual-program (replace-regexp-in-string "\\*" "%s" + (dired-guess-shell-command + "Man command: " (list file))))) (Man-getpage-in-background file))) ;;; Run Info on files. @@ -1490,8 +1513,7 @@ to mark all zero length files." ;; Karsten Wenger fixed uid. (setq uid (buffer-substring (+ (point) 1) (progn (forward-word 1) (point)))) - (re-search-forward "\\(Jan\\|Feb\\|Mar\\|Apr\\|May\\|Jun\\|\ -Jul\\|Aug\\|Sep\\|Oct\\|Nov\\|Dec\\)") + (re-search-forward dired-move-to-filename-regexp) (goto-char (match-beginning 1)) (forward-char -1) (setq size (string-to-int (buffer-substring (save-excursion @@ -1589,15 +1611,14 @@ to test if that file exists. Use minibuffer after snatching filename." (find-file-other-window (expand-file-name filename))) ;;; Internal functions. -(defun dired-filename-at-point () +;; Fixme: This should probably use `thing-at-point'. -- fx +(defun dired-filename-at-point () "Get the filename closest to point, but do not change position. Has a preference for looking backward when not directly on a symbol. Not perfect - point must be in middle of or end of filename." - (let ((filename-chars ".a-zA-Z0-9---_/:$+@") ; fixme: allow non-ASCII - (bol (save-excursion (beginning-of-line) (point))) - (eol (save-excursion (end-of-line) (point))) + (let ((filename-chars "-.[:alnum:]_/:$+@") start end filename prefix) (save-excursion @@ -1612,16 +1633,19 @@ perfect - point must be in middle of or end of filename." (if (string-match (concat "[" filename-chars "]") (char-to-string (following-char))) (progn - (skip-chars-backward filename-chars) + (if (re-search-backward (concat "[^" filename-chars "]") nil t) + (forward-char) + (goto-char (point-min))) (setq start (point)) (setq prefix - (and (string-match "^\\w+@" - (buffer-substring start eol)) + (and (string-match + "^\\w+@" + (buffer-substring start (line-beginning-position))) "/")) (goto-char start) (if (string-match "[/~]" (char-to-string (preceding-char))) (setq start (1- start))) - (skip-chars-forward filename-chars)) + (re-search-forward (concat "\\=[" filename-chars "]*") nil t)) (error "No file found around point!")) @@ -1664,7 +1688,7 @@ If `current-prefix-arg' is non-nil, uses name at point as guess." 'dired-guess-shell-znew-switches 'dired-guess-shell-alist-user 'dired-clean-up-buffers-too - 'dired-omit-files-p + 'dired-omit-mode 'dired-omit-files 'dired-omit-extensions ) @@ -1688,4 +1712,5 @@ variables `dired-x-variable-list' in the message." ;; As Barry Warsaw would say: "This might be useful..." (provide 'dired-x) +;;; arch-tag: 71a43ba2-7a00-4793-a028-0613dd7765ae ;;; dired-x.el ends here