X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/c0d7987107ab2fa9183aadf36d38e3be2542873a..3b42af63b15ff2fdc7242f450a327bfacb2cbdb1:/lisp/dired-x.el diff --git a/lisp/dired-x.el b/lisp/dired-x.el index 876b040f2c..e207c60502 100644 --- a/lisp/dired-x.el +++ b/lisp/dired-x.el @@ -1,13 +1,14 @@ -;;; dired-x.el --- Sebastian Kremer's Extra DIRED hacked up for GNU Emacs19 +;;; dired-x.el --- extra Dired functionality -*-byte-compile-dynamic: t;-*- ;; Author: Sebastian Kremer ;; Lawrence R. Dodd -;; Maintainer: Lawrence R. Dodd +;; Maintainer: Romain Francoise ;; Version: 2.37+ ;; Date: 1994/08/18 19:27:42 -;; Keywords: dired extensions +;; Keywords: dired extensions files -;; Copyright (C) 1993, 1994 Free Software Foundation +;; Copyright (C) 1993, 1994, 1997, 2001, 2002, 2003, 2004, +;; 2005, 2006 Free Software Foundation, Inc. ;; This file is part of GNU Emacs. @@ -22,188 +23,231 @@ ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to -;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. ;;; Commentary: -;;; This is Sebastian Kremer's excellent dired-x.el (Dired Extra), version -;;; 1.191, hacked up for GNU Emacs 19. Redundant or conflicting material -;;; has been removed or renamed in order to work properly with dired of -;;; GNU Emacs 19. 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. - -;;; INSTALLATION: In your ~/.emacs, -;;; -;;; (add-hook 'dired-load-hook -;;; (function (lambda () -;;; (load "dired-x") -;;; ;; Set variables here. For example: -;;; ;; (setq dired-guess-shell-gnutar "gtar") -;;; ;; (setq dired-omit-files-p t) -;;; ))) -;;; -;;; At load time dired-x.el will install itself, redefine some functions, and -;;; bind some dired keys. *Please* see the info pages for more details. - -;;; CAUTION: If you are using a version of GNU Emacs earlier than 19.20 than -;;; you may have to edit dired.el. The copy of dired.el in GNU Emacs versions -;;; earlier than 19.20 incorrectly had the call to run-hooks *before* the call -;;; to provide. In such a case, it is possible that byte-compiling and/or -;;; loading dired can cause an infinite loop. To prevent this, make sure the -;;; line of code -;;; -;;; (run-hooks 'dired-load-hook) -;;; -;;; is the *last* executable line in the file dired.el. That is, make sure it -;;; comes *after* the line -;;; -;;; (provide 'dired) -;;; -;;; *Please* see the info pages for more details. - -;;; User defined variables: -;;; -;;; dired-bind-vm -;;; dired-vm-read-only-folders -;;; dired-bind-jump -;;; dired-bind-info -;;; dired-bind-man -;;; dired-x-hands-off-my-keys -;;; dired-find-subdir -;;; dired-enable-local-variables -;;; dired-local-variables-file -;;; dired-guess-shell-gnutar -;;; dired-guess-shell-gzip-quiet -;;; dired-guess-shell-znew-switches -;;; dired-guess-shell-alist-user -;;; dired-clean-up-buffers-too -;;; dired-omit-files-p -;;; dired-omit-files -;;; dired-omit-extensions -;;; -;;; To find out more about these variables, load this file, put your cursor at -;;; the end of any of the variable names, and hit C-h v [RET]. *Please* see -;;; the info pages for more details. - -;;; When loaded this code redefines the following functions of GNU Emacs -;;; -;;; Function Found in this file of GNU Emacs -;;; -------- ------------------------------- -;;; dired-clean-up-after-deletion ../lisp/dired.el -;;; dired-find-buffer-nocreate ../lisp/dired.el -;;; dired-initial-position ../lisp/dired.el -;;; dired-up-directory ../lisp/dired.el -;;; -;;; dired-add-entry ../lisp/dired-aux.el -;;; dired-read-shell-command ../lisp/dired-aux.el -;;; -;;; One drawback is that dired-x.el will load dired-aux.el as soon as dired is -;;; loaded. Thus, the advantage of separating out non-essential dired stuff -;;; into dired-aux.el and only loading when necessary will be lost. Please -;;; note also that some of the comments in dired.el and dired-aux.el are -;;; Kremer's that referred to the old dired-x.el. This now should be referring -;;; to this program. (This is also a good reason to call this dired-x.el -;;; instead of dired-x19.el.) +;; This is Sebastian Kremer's excellent dired-x.el (Dired Extra), version +;; 1.191, hacked up for GNU Emacs. Redundant or conflicting material has +;; 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. + +;; INSTALLATION: In your ~/.emacs, +;; +;; (add-hook 'dired-load-hook +;; (function (lambda () +;; (load "dired-x") +;; ;; Set global variables here. For example: +;; ;; (setq dired-guess-shell-gnutar "gtar") +;; ))) +;; (add-hook 'dired-mode-hook +;; (function (lambda () +;; ;; Set buffer-local variables here. For example: +;; ;; (dired-omit-mode 1) +;; ))) +;; +;; At load time dired-x.el will install itself, redefine some functions, and +;; bind some dired keys. *Please* see the info pages for more details. + +;; *Please* see the info pages for more details. + +;; User defined variables: +;; +;; dired-bind-vm +;; dired-vm-read-only-folders +;; dired-bind-jump +;; dired-bind-info +;; dired-bind-man +;; dired-x-hands-off-my-keys +;; dired-find-subdir +;; dired-enable-local-variables +;; dired-local-variables-file +;; dired-guess-shell-gnutar +;; dired-guess-shell-gzip-quiet +;; dired-guess-shell-znew-switches +;; dired-guess-shell-alist-user +;; dired-clean-up-buffers-too +;; dired-omit-mode +;; dired-omit-files +;; dired-omit-extensions +;; dired-omit-size-limit +;; +;; To find out more about these variables, load this file, put your cursor at +;; the end of any of the variable names, and hit C-h v [RET]. *Please* see +;; the info pages for more details. + +;; When loaded this code redefines the following functions of GNU Emacs +;; +;; Function Found in this file of GNU Emacs +;; -------- ------------------------------- +;; dired-clean-up-after-deletion ../lisp/dired.el +;; dired-find-buffer-nocreate ../lisp/dired.el +;; dired-initial-position ../lisp/dired.el +;; +;; dired-add-entry ../lisp/dired-aux.el +;; dired-read-shell-command ../lisp/dired-aux.el -;;;; Code: +;;; Code: -;;; LOAD. +;; LOAD. -;;; This is a no-op if dired-x is being loaded via `dired-load-hook'. It is -;;; here in case the user has autoloaded dired-x via the dired-jump key binding -;;; (instead of autoloading to dired as is suggested in the info-pages). +;; This is a no-op if dired-x is being loaded via `dired-load-hook'. It is +;; here in case the user has autoloaded dired-x via the dired-jump key binding +;; (instead of autoloading to dired as is suggested in the info-pages). (require 'dired) -;;; We will redefine some functions and also need some macros so we need to -;;; load dired stuff of GNU Emacs. +;; We will redefine some functions and also need some macros so we need to +;; load dired stuff of GNU Emacs. (require 'dired-aux) -;;;; User-defined variables. +(defvar vm-folder-directory) +(eval-when-compile (require 'man)) -(defvar dired-bind-vm nil - "*t says \"V\" in dired-mode will `dired-vm', otherwise \"V\" is `dired-rmail'. -Also, RMAIL files contain -*- rmail -*- at the top so \"f\", -`dired-advertised-find-file', will run rmail.") - -(defvar dired-bind-jump t - "*t says bind `dired-jump' to C-x C-j, otherwise do not.") +;;; User-defined variables. -(defvar dired-bind-man t - "*t says bind `dired-man' to \"N\" in dired-mode, otherwise do not.") +(defgroup dired-x nil + "Extended directory editing (dired-x)." + :group 'dired) -(defvar dired-bind-info t - "*t says bind `dired-info' to \"I\" in dired-mode, otherwise do not.") +(defgroup dired-keys nil + "Dired keys customizations." + :prefix "dired-" + :group 'dired-x) -(defvar dired-vm-read-only-folders nil - "*If t, \\[dired-vm] will visit all folders read-only. +(defcustom dired-bind-vm nil + "*Non-nil means \"V\" runs `dired-vm', otherwise \"V\" runs `dired-rmail'. +Also, RMAIL files contain -*- rmail -*- at the top so \"f\", +`dired-advertised-find-file', will run rmail." + :type 'boolean + :group 'dired-keys) + +(defcustom dired-bind-jump t + "*Non-nil means bind `dired-jump' to C-x C-j, otherwise do not." + :type 'boolean + :group 'dired-keys) + +(defcustom dired-bind-man t + "*Non-nil means bind `dired-man' to \"N\" in dired-mode, otherwise do not." + :type 'boolean + :group 'dired-keys) + +(defcustom dired-bind-info t + "*Non-nil means bind `dired-info' to \"I\" in dired-mode, otherwise do not." + :type 'boolean + :group 'dired-keys) + +(defcustom dired-vm-read-only-folders nil + "*If non-nil, \\[dired-vm] will visit all folders read-only. If neither nil nor t, e.g. the symbol `if-file-read-only', only files not writable by you are visited read-only. -Read-only folders only work in VM 5, not in VM 4.") - -(defvar dired-omit-files-p nil - "*If non-nil, \"uninteresting\" files are not listed (buffer-local). -Use \\[dired-omit-toggle] to toggle its value. +Read-only folders only work in VM 5, not in VM 4." + :type '(choice (const :tag "off" nil) + (const :tag "on" t) + (other :tag "non-writable only" if-file-read-only)) + :group 'dired-x) + +(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'.") +plus those ending with extensions in `dired-omit-extensions'." + :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))) -(defvar dired-omit-files "^#\\|^\\.$\\|^\\.\\.$" - "*Filenames matching this regexp will not be displayed \(buffer-local\). -This only has effect when `dired-omit-files-p' is t. See interactive function -`dired-omit-toggle' \(\\[dired-omit-toggle]\) and variable -`dired-omit-extensions'. The default is to omit `.', `..', and auto-save -files.") +;; For backward compatibility +(defvaralias 'dired-omit-files-p 'dired-omit-mode) +(make-obsolete-variable 'dired-omit-files-p 'dired-omit-mode) -(defvar dired-find-subdir nil ; t is pretty near to DWIM... +(defcustom dired-omit-files "^\\.?#\\|^\\.$\\|^\\.\\.$" + "*Filenames matching this regexp will not be displayed. +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 + :group 'dired-x) + +(defcustom dired-find-subdir nil ; t is pretty near to DWIM... "*If non-nil, Dired always finds a directory in a buffer of its own. If nil, Dired finds the directory as a subdirectory in some other buffer if it is present as one. -If there are several Dired buffers for a directory, the most recently +If there are several dired buffers for a directory, the most recently used is chosen. Dired avoids switching to the current buffer, so that if you have -a normal and a wildcard buffer for the same directory, C-x d RET will -toggle between those two.") - -(defvar dired-enable-local-variables t - "*Control use of local-variables lists in dired. +a normal and a wildcard buffer for the same directory, \\[dired] will +toggle between those two." + :type 'boolean + :group 'dired-x) + +(defcustom dired-omit-size-limit 30000 + "*Maximum size for the \"omitting\" feature. +If nil, there is no maximum size." + :type '(choice (const :tag "no maximum" nil) integer) + :group 'dired-x) + +(defcustom dired-enable-local-variables t + "*Control use of local-variables lists in Dired. The value can be t, nil or something else. A value of t means local-variables lists are obeyed; nil means they are ignored; anything else means query. This temporarily overrides the value of `enable-local-variables' when listing -a directory. See also `dired-local-variables-file'.") - -(defvar dired-guess-shell-gnutar nil - "*If non-nil, name of GNU tar executable (e.g., \"tar\" or \"gtar\") and `z' -switch will be used for compressed or gzip'ed tar files. If no GNU tar, set -to nil: a pipe using `zcat' or `gunzip -c' will be used.") - -(defvar dired-guess-shell-gzip-quiet t - "*non-nil says pass -q to gzip overriding verbose GZIP environment.") - -(defvar dired-guess-shell-znew-switches nil - "*If non-nil, then string of switches passed to `znew', example: \"-K\"") - -(defvar dired-clean-up-buffers-too t - "*t says offer to kill buffers visiting files and dirs deleted in dired.") - -;;;; KEY BINDINGS. - -(define-key dired-mode-map "\M-o" 'dired-omit-toggle) +a directory. See also `dired-local-variables-file'." + :type 'boolean + :group 'dired-x) + +(defcustom dired-guess-shell-gnutar nil + "*If non-nil, name of GNU tar executable. +\(E.g., \"tar\" or \"gtar\"). The `z' switch will be used with it for +compressed or gzip'ed tar files. If you don't have GNU tar, set this +to nil: a pipe using `zcat' or `gunzip -c' will be used." + :type '(choice (const :tag "Not GNU tar" nil) + (string :tag "Command name")) + :group 'dired-x) + +(defcustom dired-guess-shell-gzip-quiet t + "*Non-nil says pass -q to gzip overriding verbose GZIP environment." + :type 'boolean + :group 'dired-x) + +(defcustom dired-guess-shell-znew-switches nil + "*If non-nil, then string of switches passed to `znew', example: \"-K\"." + :type '(choice (const :tag "None" nil) + (string :tag "Switches")) + :group 'dired-x) + +(defcustom dired-clean-up-buffers-too t + "*Non-nil means offer to kill buffers visiting files and dirs deleted in Dired." + :type 'boolean + :group 'dired-x) + +;;; KEY BINDINGS. + +(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) (define-key dired-mode-map "\M-!" 'dired-smart-shell-command) -(define-key dired-mode-map "T" 'dired-do-toggle) (define-key dired-mode-map "w" 'dired-copy-filename-as-kill) (define-key dired-mode-map "\M-g" 'dired-goto-file) (define-key dired-mode-map "\M-G" 'dired-goto-subdir) @@ -218,6 +262,72 @@ to nil: a pipe using `zcat' or `gunzip -c' will be used.") (if dired-bind-info (define-key dired-mode-map "I" 'dired-info)) +;;; MENU BINDINGS + +(let ((menu-bar (lookup-key dired-mode-map [menu-bar]))) + (let ((menu (lookup-key menu-bar [operate]))) + (define-key-after + menu + [find-files] + '(menu-item + "Find files" + dired-do-find-marked-files + :help "Find current or marked files") + 'delete) + (define-key-after + menu + [relsymlink] + '(menu-item + "Relative symlink to..." + dired-do-relsymlink + :visible (fboundp 'make-symbolic-link) + :help "Make relative symbolic links for current or marked files") + 'symlink)) + (let ((menu (lookup-key menu-bar [mark]))) + (define-key-after + menu + [flag-extension] + '(menu-item + "Flag extension..." + dired-flag-extension + :help "Flag files with a certain extension for deletion") + 'garbage-files) + (define-key-after + menu + [mark-extension] + '(menu-item + "Mark extension..." + dired-mark-extension + :help "Mark files with a certain extension") + 'symlinks) + (define-key-after + menu + [mark-omitted] + '(menu-item + "Mark omitted" + dired-mark-omitted + :help "Mark files matching `dired-omit-files' and `dired-omit-extensions'") + 'mark-extension)) + (let ((menu (lookup-key menu-bar [regexp]))) + (define-key-after + menu + [relsymlink-regexp] + '(menu-item + "Relative symlink..." + dired-do-relsymlink-regexp + :visible (fboundp 'make-symbolic-link) + :help "Make relative symbolic links for files matching regexp") + 'symlink)) + (let ((menu (lookup-key menu-bar [immediate]))) + (define-key-after + menu + [omit-mode] + '(menu-item + "Omit mode" dired-omit-mode + :button (:toggle . dired-omit-mode) + :help "Enable or disable omitting \"uninteresting\" files") + 'dashes))) + ;;; GLOBAL BINDING. (if dired-bind-jump (progn @@ -225,55 +335,53 @@ to nil: a pipe using `zcat' or `gunzip -c' will be used.") (define-key global-map "\C-x4\C-j" 'dired-jump-other-window))) -;;;; Install into appropriate hooks. +;;; Install into appropriate hooks. (add-hook 'dired-mode-hook 'dired-extra-startup) (add-hook 'dired-after-readin-hook 'dired-omit-expunge) (defun dired-extra-startup () - "Automatically put on dired-mode-hook to get extra dired features: + "Automatically put on `dired-mode-hook' to get extra Dired features: \\ - \\[dired-do-run-mail]\t-- run mail on folder (see `dired-bind-vm') \\[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-do-toggle]\t-- toggle marks - \\[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]. + \\[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] For more features, see variables - dired-bind-vm - dired-bind-jump - dired-bind-info - dired-bind-man - dired-vm-read-only-folders - dired-omit-files-p - dired-omit-files - dired-omit-extensions - dired-find-subdir - dired-enable-local-variables - dired-local-variables-file - dired-guess-shell-gnutar - dired-guess-shell-gzip-quiet - dired-guess-shell-znew-switches - dired-guess-shell-alist-user - dired-clean-up-buffers-too + `dired-bind-vm' + `dired-bind-jump' + `dired-bind-info' + `dired-bind-man' + `dired-vm-read-only-folders' + `dired-omit-mode' + `dired-omit-files' + `dired-omit-extensions' + `dired-omit-size-limit' + `dired-find-subdir' + `dired-enable-local-variables' + `dired-local-variables-file' + `dired-guess-shell-gnutar' + `dired-guess-shell-gzip-quiet' + `dired-guess-shell-znew-switches' + `dired-guess-shell-alist-user' + `dired-clean-up-buffers-too' See also functions - dired-flag-extension - dired-virtual - dired-jump - dired-man - dired-vm - dired-rmail - dired-info - dired-do-find-marked-files -" + `dired-flag-extension' + `dired-virtual' + `dired-jump' + `dired-man' + `dired-vm' + `dired-rmail' + `dired-info' + `dired-do-find-marked-files'" (interactive) ;; These must be done in each new dired buffer. @@ -281,13 +389,12 @@ See also functions (dired-omit-startup)) -;;;; BUFFER CLEANING. +;;; BUFFER CLEANING. -;;; REDEFINE. +;; REDEFINE. (defun dired-clean-up-after-deletion (fn) - - ;; Clean up after a deleted file or directory FN. - ;; Remove expanded subdir of deleted dir, if any. + "Clean up after a deleted file or directory FN. +Remove expanded subdir of deleted dir, if any." (save-excursion (and (cdr dired-subdir-alist) (dired-goto-subdir fn) (dired-kill-subdir))) @@ -315,12 +422,12 @@ See also functions ) -;;;; EXTENSION MARKING FUNCTIONS. +;;; EXTENSION MARKING FUNCTIONS. ;;; Mark files with some extension. (defun dired-mark-extension (extension &optional marker-char) - "Mark all files with a certain extension for use in later commands. -A `.' is not automatically prepended to the string entered." + "Mark all files with a certain EXTENSION for use in later commands. +A `.' is *not* automatically prepended to the string entered." ;; EXTENSION may also be a list of extensions instead of a single one. ;; Optional MARKER-CHAR is marker to use. (interactive "sMarking extension: \nP") @@ -334,7 +441,7 @@ A `.' is not automatically prepended to the string entered." marker-char)) (defun dired-flag-extension (extension) - "In dired, flag all files with a certain extension for deletion. + "In dired, flag all files with a certain EXTENSION for deletion. A `.' is *not* automatically prepended to the string entered." (interactive "sFlagging extension: ") (dired-mark-extension extension dired-del-marker)) @@ -370,7 +477,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) @@ -391,13 +498,13 @@ See variables `dired-texinfo-unclean-extensions', dired-tex-unclean-extensions (list ".dvi")))) -;;;; JUMP. +;;; JUMP. ;;;###autoload (defun dired-jump (&optional other-window) "Jump to dired buffer corresponding to current buffer. If in a file, dired the current directory and move to file's line. -If in dired already, pop up a level and goto old directory's line. +If in Dired already, pop up a level and goto old directory's line. In case the proper dired file line cannot be found, refresh the dired buffer and try again." (interactive "P") @@ -417,99 +524,22 @@ buffer and try again." (dired dir)) (if file (or (dired-goto-file file) - ;; Toggle omitting, if necessary, and try again. - (progn - (dired-omit-toggle t) - (dired-goto-file file)) ;; refresh and try again (progn (dired-insert-subdir (file-name-directory file)) - (dired-goto-file file))))))) + (dired-goto-file file)) + ;; Toggle omitting, if it is on, and try again. + (if dired-omit-mode + (progn + (dired-omit-mode) + (dired-goto-file file)))))))) (defun dired-jump-other-window () - "Like \\[dired-jump] (dired-jump) but in other window." + "Like \\[dired-jump] (`dired-jump') but in other window." (interactive) (dired-jump t)) - -;;; REDEFINE. -;;; This replaces the version in dired.el -;;; It simply adds the OTHER-WINDOW option to the one in dired.el. -(defun dired-up-directory (&optional other-window) - "Run dired on parent directory of current directory. -Find the parent directory either in this buffer or another buffer. -Finds in current window or in other window with optional OTHER-WINDOW. -Creates a buffer if necessary." - (interactive "P") - (let* ((dir (dired-current-directory)) - (up (file-name-directory (directory-file-name dir)))) - (or (dired-goto-file (directory-file-name dir)) - ;; Only try dired-goto-subdir if buffer has more than one dir. - (and (cdr dired-subdir-alist) - (dired-goto-subdir up)) - (progn - (if other-window - (dired-other-window up) - (dired up)) - (dired-goto-file dir))))) - -;;;; TOGGLE. -;;; Toggle marked files with unmarked files. - -(defun dired-do-toggle () - "Toggle marks. -That is, currently marked files become unmarked and vice versa. -Files marked with other flags (such as `D') are not affected. -`.' and `..' are never toggled. -As always, hidden subdirs are not affected." - (interactive) - (save-excursion - (goto-char (point-min)) - (let (buffer-read-only) - (while (not (eobp)) - (or (dired-between-files) - (looking-at dired-re-dot) - ;; use subst instead of insdel because it does not move - ;; the gap and thus should be faster and because - ;; other characters are left alone automatically - (apply 'subst-char-in-region - (point) (1+ (point)) - (if (eq ?\040 (following-char)) ; SPC - (list ?\040 dired-marker-char) - (list dired-marker-char ?\040)))) - (forward-line 1))))) - - -;;;; 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. +;;; OMITTING. ;;; Enhanced omitting of lines from directory listings. ;;; Marked files are never omitted. @@ -517,56 +547,47 @@ You can then feed the file name(s) to other commands with \\[yank]." ;; should probably get rid of this and always use 'no-dir. ;; sk 28-Aug-1991 09:37 (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.") + "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 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 - "Temporary marker used by by dired-omit. + "Temporary marker used by dired-omit. Should never be used as marker by the user or other packages.") (defun dired-omit-startup () - (make-local-variable 'dired-omit-files-p) - (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 " Omit")) minor-mode-alist)))) + (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: - (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 dired-latex-unclean-extensions dired-bibtex-unclean-extensions dired-texinfo-unclean-extensions) - "If non-nil, a list of extensions \(strings\) to omit from Dired listings. + "If non-nil, a list of extensions \(strings\) to omit from Dired listings. Defaults to elements of `completion-ignored-extensions', `dired-latex-unclean-extensions', `dired-bibtex-unclean-extensions', and -`dired-texinfo-unclean-extensions'. +`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. +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'. If REGEXP is the empty string, this function is a no-op. @@ -574,7 +595,15 @@ 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 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-mode nil) + nil))) (let ((omit-re (or regexp (dired-omit-regexp))) (old-modified-p (buffer-modified-p)) count) @@ -584,12 +613,11 @@ This functions works by temporarily binding `dired-marker-char' to (if (dired-mark-unmarked-files omit-re nil nil dired-omit-localp) (progn (setq count (dired-do-kill-lines nil "Omitted %d line%s.")) - ;; Force an update of modeline. - (set-buffer-modified-p (buffer-modified-p))) + (force-mode-line-update)) (message "(Nothing to omit)")))) ;; Try to preserve modified state of buffer. So `%*' doesn't appear ;; in mode-line of omitted buffers. - (set-buffer-modified-p (and old-modified-p + (set-buffer-modified-p (and old-modified-p (save-excursion (goto-char (point-min)) (re-search-forward dired-re-mark nil t)))) @@ -607,13 +635,13 @@ 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) - "Marks unmarked files matching REGEXP, displaying MSG. -REGEXP is matched against the complete pathname. + "Mark unmarked files matching REGEXP, displaying MSG. +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'." +Optional fourth argument LOCALP is as in `dired-get-filename'." (interactive "P") - (let ((dired-marker-char (if unflag-p ?\ dired-marker-char))) + (let ((dired-marker-char (if unflag-p ?\s dired-marker-char))) (dired-mark-if (and ;; not already marked @@ -624,10 +652,10 @@ Second optional argument LOCALP is as in `dired-get-filename'." msg))) ;;; REDEFINE. -(defun dired-omit-new-add-entry (filename &optional marker-char) +(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 "") @@ -643,12 +671,12 @@ Second optional argument LOCALP is as in `dired-get-filename'." filename (file-name-directory filename))))))) ;; if it didn't match, go ahead and add the entry - (dired-omit-old-add-entry filename marker-char) + (dired-omit-old-add-entry filename marker-char relative) ;; dired-add-entry returns t for success, perhaps we should ;; return file-exists-p t)) ;; omitting is not turned on at all - (dired-omit-old-add-entry filename marker-char))) + (dired-omit-old-add-entry filename marker-char relative))) ;;; REDEFINE. ;;; Redefine dired-aux.el's version of `dired-add-entry' @@ -659,11 +687,11 @@ Second optional argument LOCALP is as in `dired-get-filename'." (fset 'dired-add-entry 'dired-omit-new-add-entry) -;;;; VIRTUAL DIRED MODE. +;;; VIRTUAL DIRED MODE. ;;; For browsing `ls -lR' listings in a dired-like fashion. -(fset 'virtual-dired 'dired-virtual) +(defalias 'virtual-dired 'dired-virtual) (defun dired-virtual (dirname &optional switches) "Put this buffer into Virtual Dired mode. @@ -680,11 +708,10 @@ buffer. If you have save a Dired buffer in a file you can use \\[dired-virtual] to resume it in a later session. -Type \\\\[revert-buffer] in the -Virtual Dired buffer and answer `y' to convert the virtual to a real -dired buffer again. You don't have to do this, though: you can relist -single subdirs using \\[dired-do-redisplay]. -" +Type \\\\[revert-buffer] \ +in the Virtual Dired buffer and answer `y' to convert +the virtual to a real dired buffer again. You don't have to do this, though: +you can relist single subdirs using \\[dired-do-redisplay]." ;; DIRNAME is the top level directory of the buffer. It will become ;; its `default-directory'. If nil, the old value of @@ -718,7 +745,9 @@ single subdirs using \\[dired-do-redisplay]. ;; decent subdir headerline: (goto-char (point-min)) (or (looking-at dired-subdir-regexp) - (dired-insert-headerline default-directory)) + (insert " " + (directory-file-name (file-name-directory default-directory)) + ":\n")) (dired-mode dirname (or switches dired-listing-switches)) (setq mode-name "Virtual Dired" revert-buffer-function 'dired-virtual-revert) @@ -728,11 +757,10 @@ single subdirs using \\[dired-do-redisplay]. (dired-initial-position dirname)) (defun dired-virtual-guess-dir () - - ;; Guess and return appropriate working directory of this buffer, - ;; assumed to be in Dired or ls -lR format. - ;; The guess is based upon buffer contents. - ;; If nothing could be guessed, returns nil. + "Guess and return appropriate working directory of this buffer. +The buffer is assumed to be in Dired or ls -lR format. The guess is +based upon buffer contents. If nothing could be guessed, returns +nil." (let ((regexp "^\\( \\)?\\([^ \n\r]*\\)\\(:\\)[\n\r]") (subexpr 2)) @@ -759,7 +787,7 @@ single subdirs using \\[dired-do-redisplay]. (defun dired-virtual-revert (&optional arg noconfirm) (if (not (y-or-n-p "Cannot revert a Virtual Dired buffer - switch to Real Dired mode? ")) - (error "Cannot revert a Virtual Dired buffer.") + (error "Cannot revert a Virtual Dired buffer") (setq mode-name "Dired" revert-buffer-function 'dired-revert) (revert-buffer))) @@ -769,12 +797,12 @@ single subdirs using \\[dired-do-redisplay]. ;; `buffer-contents-mode-alist'. ;; Or you use infer-mode.el and infer-mode-alist, same syntax. (defun dired-virtual-mode () - "Put current buffer into virtual dired mode (see `dired-virtual'). + "Put current buffer into Virtual Dired mode (see `dired-virtual'). Useful on `buffer-contents-mode-alist' (which see) with the regexp \"^ \\(/[^ /]+\\)/?+:$\" -to put saved dired buffers automatically into virtual dired mode. +to put saved dired buffers automatically into Virtual Dired mode. Also useful for `auto-mode-alist' (which see) like this: @@ -784,7 +812,7 @@ Also useful for `auto-mode-alist' (which see) like this: (dired-virtual (dired-virtual-guess-dir))) -;;;; SMART SHELL. +;;; SMART SHELL. ;;; An Emacs buffer can have but one working directory, stored in the ;;; buffer-local variable `default-directory'. A Dired buffer may have @@ -801,24 +829,26 @@ Also useful for `auto-mode-alist' (which see) like this: '((dired-mode . (if (fboundp 'dired-current-directory) (dired-current-directory) default-directory))) - "Alist of major modes and their opinion on default-directory, as a -lisp expression to evaluate. A resulting value of nil is ignored in -favor of default-directory.") + "Alist of major modes and their opinion on `default-directory'. +This is given as a Lisp expression to evaluate. A resulting value of +nil is ignored in favor of `default-directory'.") -(defun default-directory () - "Usage like variable `default-directory', but knows about the special -cases in variable `default-directory-alist' (which see)." +(defun dired-default-directory () + "Usage like variable `default-directory'. +Knows about the special cases in variable `default-directory-alist'." (or (eval (cdr (assq major-mode default-directory-alist))) default-directory)) (defun dired-smart-shell-command (cmd &optional insert) - "Like function `shell-command', but in the current Tree Dired directory." - (interactive "sShell command: \nP") - (let ((default-directory (default-directory))) + "Like function `shell-command', but in the current Virtual Dired directory." + (interactive (list (read-from-minibuffer "Shell command: " + nil nil nil 'shell-command-history) + current-prefix-arg)) + (let ((default-directory (dired-default-directory))) (shell-command cmd insert))) -;;;; LOCAL VARIABLES FOR DIRED BUFFERS. +;;; LOCAL VARIABLES FOR DIRED BUFFERS. ;;; Brief Description: ;;; @@ -839,11 +869,12 @@ cases in variable `default-directory-alist' (which see)." ;;; `dired-enable-local-variables' and run `hack-local-variables' on the ;;; Dired Buffer. -(defvar dired-local-variables-file ".dired" +(defvar dired-local-variables-file (convert-standard-filename ".dired") "Filename, as string, containing local dired buffer variables to be hacked. If this file found in current directory, then it will be inserted into dired -buffer and `hack-local-variables' will be run. See Emacs Info pages for more -information on local variables. See also `dired-enable-local-variables'.") +buffer and `hack-local-variables' will be run. See Info node +`(emacs)File Variables' for more information on local variables. +See also `dired-enable-local-variables'.") (defun dired-hack-local-variables () "Evaluate local variables in `dired-local-variables-file' for dired buffer." @@ -869,8 +900,8 @@ information on local variables. See also `dired-enable-local-variables'.") (delete-region opoint (point-max))))) (defun dired-omit-here-always () - "Creates `dired-local-variables-file' for omitting and reverts directory. -Sets dired-omit-file-p to t in a local variables file that is readable by + "Create `dired-local-variables-file' for omitting and reverts directory. +Sets `dired-omit-mode' to t in a local variables file that is readable by dired." (interactive) (if (file-exists-p dired-local-variables-file) @@ -880,7 +911,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))) @@ -889,7 +920,7 @@ dired." (dired-revert))) -;;;; GUESS SHELL COMMAND. +;;; GUESS SHELL COMMAND. ;;; Brief Description: ;;; @@ -910,7 +941,7 @@ dired." ;;; string. COMMAND may be a list of commands. ;;; ;;; * Return this command to `dired-guess-shell-command' which prompts user -;;; with it. The list of commands are temporaily put into the history list. +;;; with it. The list of commands is temporarily put into the history list. ;;; If a command is used successfully then it is stored permanently in ;;; `dired-shell-command-history'. @@ -925,9 +956,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: @@ -941,30 +980,71 @@ dired." " " dired-guess-shell-znew-switches)) ;; gzip'ed archives - (list "\\.tar\\.g?z$" + (list "\\.t\\(ar\\.\\)?gz$" '(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" ""))) - '("\\.shar.Z$" "zcat * | unshar") - '("\\.shar.g?z$" "gunzip -qc * | unshar") - - '("\\.ps$" "ghostview" "xv" "lpr") - (list "\\.ps.g?z$" "gunzip -qc * | ghostview -" + ;; bzip2'ed archives + (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") + + '("\\.e?ps$" "ghostview" "xloadimage" "lpr") + (list "\\.e?ps\\.g?z$" "gunzip -qc * | ghostview -" ;; Optional decompression. '(concat "gunzip" (if dired-guess-shell-gzip-quiet " -q"))) - (list "\\.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]\\|man\\)$" '(progn (require 'man) + (if (Man-support-local-filenames) + "man -l" + "cat * | tbl | nroff -man -h"))) + (list "\\.\\(?:[0-9]\\|man\\)\\.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,24 +1054,31 @@ dired." '("\\.sh$" "sh") ; execute shell scripts '("\\.xbm$" "bitmap") ; view X11 bitmaps '("\\.gp$" "gnuplot") - '("\\.p[bgpn]m$" "xv") - '("\\.gif$" "xv") ; view gif pictures - '("\\.tif$" "xv") - '("\\.jpg$" "xv") + '("\\.p[bgpn]m$" "xloadimage") + '("\\.gif$" "xloadimage") ; view gif pictures + '("\\.tif$" "xloadimage") + '("\\.png$" "display") ; xloadimage 4.1 doesn't grok PNG + '("\\.jpe?g$" "xloadimage") '("\\.fig$" "xfig") ; edit fig pictures '("\\.out$" "xgraph") ; for plotting purposes. '("\\.tex$" "latex" "tex") '("\\.texi\\(nfo\\)?$" "makeinfo" "texi2dvi") + '("\\.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. '(concat "znew" (if dired-guess-shell-gzip-quiet " -q") @@ -999,18 +1086,18 @@ dired." ) "Default alist used for shell command guessing. -See `dired-guess-shell-alist-user'") +See `dired-guess-shell-alist-user'.") -(defvar dired-guess-shell-alist-user nil - "User-defined alist of rules for suggested commands. These rules take -precedence over the predefined rules in the variable +(defcustom dired-guess-shell-alist-user nil + "User-defined alist of rules for suggested commands. +These rules take precedence over the predefined rules in the variable `dired-guess-shell-alist-default' (to which they are prepended). Each element of this list looks like \(REGEXP COMMAND...\) -where each COMMAND can either be a string or a lisp expression that evaluates +where each COMMAND can either be a string or a Lisp expression that evaluates to a string. If several COMMANDs are given, the first one will be the default and the rest will be added temporarily to the history and can be retrieved with \\[previous-history-element] (M-p) . @@ -1019,20 +1106,26 @@ You can set this variable in your ~/.emacs. For example, to add rules for `.foo' and `.bar' files, write \(setq dired-guess-shell-alist-user - (list (list \"\\\\.foo$\" \"FOO-COMMAND\");; fixed rule + (list (list \"\\\\.foo\\\\'\" \"FOO-COMMAND\");; fixed rule ;; possibly more rules ... - (list \"\\\\.bar$\";; rule with condition test + (list \"\\\\.bar\\\'\";; rule with condition test '(if condition \"BAR-COMMAND-1\" - \"BAR-COMMAND-2\")))\) -") + \"BAR-COMMAND-2\")))\)" + :group 'dired-x + :type '(alist :key-type regexp :value-type (repeat sexp))) -(defun dired-guess-default (files) +(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) - ;; Guess a shell commands for FILES. Return command or list of commands. - ;; See `dired-guess-shell-alist-user'. +(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)) @@ -1066,8 +1159,7 @@ You can set this variable in your ~/.emacs. For example, to add rules for (mapcar (function eval) cmds))))) (defun dired-guess-shell-command (prompt files) - - ;; Ask user with PROMPT for a shell command, guessing a default from FILES. + "Ask user with PROMPT for a shell command, guessing a default from FILES." (let ((default (dired-guess-default files)) default-list old-history val (failed t)) @@ -1122,10 +1214,10 @@ You can set this variable in your ~/.emacs. For example, to add rules for ;;; REDEFINE. ;;; Redefine dired-aux.el's version: (defun dired-read-shell-command (prompt arg files) -;; "Read a dired shell command prompting with PROMPT (using read-string). -;;ARG is the prefix arg and may be used to indicate in the prompt which -;; files are affected. -;;This is an extra function so that you can redefine it, e.g., to use gmhist." + "Read a dired shell command prompting with PROMPT (using read-string). +ARG is the prefix arg and may be used to indicate in the prompt which + files are affected. +This is an extra function so that you can redefine it." (dired-mark-pop-up nil 'shell files 'dired-guess-shell-command @@ -1133,29 +1225,27 @@ You can set this variable in your ~/.emacs. For example, to add rules for files)) ; FILES -;;;; RELATIVE SYMBOLIC LINKS. +;;; RELATIVE SYMBOLIC LINKS. (defvar dired-keep-marker-relsymlink ?S "See variable `dired-keep-marker-move'.") (defun dired-make-relative-symlink (file1 file2 &optional ok-if-already-exists) - "Three arguments: FILE1 FILE2 &optional OK-IF-ALREADY-EXISTS -Make a symbolic link (pointing to FILE1) in FILE2. + "Make a symbolic link (pointing to FILE1) in FILE2. The link is relative (if possible), for example \"/vol/tex/bin/foo\" \"/vol/local/bin/foo\" results in - \"../../tex/bin/foo\" \"/vol/local/bin/foo\" -" + \"../../tex/bin/foo\" \"/vol/local/bin/foo\"" (interactive "FRelSymLink: \nFRelSymLink %s: \np") (let (name1 name2 len1 len2 (index 0) sub) (setq file1 (expand-file-name file1) 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)) @@ -1164,7 +1254,7 @@ results in ;; `/', so NEXT is *one plus* the result of the ;; string-match. ;; E.g., consider the case of linking "/tmp/a/abc" - ;; to "/tmp/abc" erronously giving "/tmp/a" instead + ;; to "/tmp/abc" erroneously giving "/tmp/a" instead ;; of "/tmp/" as common initial component (string-equal (substring file1 0 next) (substring file2 0 next))) @@ -1173,7 +1263,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)) @@ -1193,30 +1283,30 @@ results in name2 ok-if-already-exists))) (defun dired-do-relsymlink (&optional arg) - "Relative symlink all marked (or next ARG) files into a directory, -or make a relative symbolic link to the current file. + "Relative symlink all marked (or next ARG) files into a directory. +Otherwise make a relative symbolic link to the current file. This creates relative symbolic links like foo -> ../bar/foo 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 arg 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" arg regexp newname whole-name dired-keep-marker-relsymlink)) -;;;; VISIT ALL MARKED FILES SIMULTANEOUSLY. +;;; VISIT ALL MARKED FILES SIMULTANEOUSLY. ;;; Brief Description: ;;; @@ -1258,12 +1348,12 @@ To display just marked files, type \\[delete-other-windows] first." (defun dired-simultaneous-find-file (file-list noselect) - ;; Visit all files in FILE-LIST and display them simultaneously. The - ;; current window is split across all files in FILE-LIST, as evenly as - ;; possible. Remaining lines go to the bottom-most window. The number of - ;; files that can be displayed this way is restricted by the height of the - ;; current window and the variable `window-min-height'. With non-nil - ;; NOSELECT the files are merely found but not selected. + "Visit all files in FILE-LIST and display them simultaneously. +The current window is split across all files in FILE-LIST, as evenly as +possible. Remaining lines go to the bottom-most window. The number of +files that can be displayed this way is restricted by the height of the +current window and the variable `window-min-height'. With non-nil +NOSELECT the files are merely found but not selected." ;; We don't make this function interactive because it is usually too clumsy ;; to specify FILE-LIST interactively unless via dired. @@ -1277,7 +1367,7 @@ To display just marked files, type \\[delete-other-windows] first." ;; We will have to select the buffer. Calculate and check window size. (setq size (/ (window-height) (length file-list))) (or (<= window-min-height size) - (error "Too many files to visit simultaneously. Try C-u prefix.")) + (error "Too many files to visit simultaneously. Try C-u prefix")) (find-file (car file-list))) ;; Decrement. @@ -1298,17 +1388,19 @@ To display just marked files, type \\[delete-other-windows] first." (setq file-list (cdr file-list))))) -;;;; MISCELLANEOUS COMMANDS. +;;; MISCELLANEOUS COMMANDS. ;;; Run man on files. (defun dired-man () "Run man on this file. Display old buffer if buffer name matches filename. -Uses ../lisp/man.el of \\[manual-entry] fame." +Uses `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. @@ -1320,9 +1412,11 @@ Uses ../lisp/man.el of \\[manual-entry] fame." ;;; Run mail on mail folders. -;;; (and (not (fboundp 'vm-visit-folder)) -;;; (defun vm-visit-folder (file &optional arg) -;;; nil)) +;; Avoid compiler warning. +(eval-when-compile + (when (not (fboundp 'vm-visit-folder)) + (defun vm-visit-folder (file &optional arg) + nil))) (defun dired-vm (&optional read-only) "Run VM on this file. @@ -1354,7 +1448,7 @@ See also variable `dired-vm-read-only-folders'." (dired-rmail))) -;;;; MISCELLANEOUS INTERNAL FUNCTIONS. +;;; MISCELLANEOUS INTERNAL FUNCTIONS. (or (fboundp 'dired-old-find-buffer-nocreate) (fset 'dired-old-find-buffer-nocreate @@ -1362,20 +1456,22 @@ See also variable `dired-vm-read-only-folders'." ;;; REDEFINE. ;;; Redefines dired.el's version of `dired-find-buffer-nocreate' -(defun dired-find-buffer-nocreate (dirname) - (if dired-find-subdir +(defun dired-find-buffer-nocreate (dirname &optional mode) + (if (and dired-find-subdir + ;; don't try to find a wildcard as a subdirectory + (string-equal dirname (file-name-directory dirname))) (let* ((cur-buf (current-buffer)) - (buffers (nreverse + (buffers (nreverse (dired-buffers-for-dir (expand-file-name dirname)))) - (cur-buf-matches (and (memq cur-buf buffers) - ;; wildcards must match, too: - (equal dired-directory dirname)))) - ;; We don't want to switch to the same buffer--- - (setq buffers (delq cur-buf buffers));;need setq with delq - (or (car (sort buffers (function dired-buffer-more-recently-used-p))) - ;; ---unless it's the only possibility: - (and cur-buf-matches cur-buf))) - (dired-old-find-buffer-nocreate dirname))) + (cur-buf-matches (and (memq cur-buf buffers) + ;; wildcards must match, too: + (equal dired-directory dirname)))) + ;; We don't want to switch to the same buffer--- + (setq buffers (delq cur-buf buffers));;need setq with delq + (or (car (sort buffers (function dired-buffer-more-recently-used-p))) + ;; ---unless it's the only possibility: + (and cur-buf-matches cur-buf))) + (dired-old-find-buffer-nocreate dirname mode))) ;; This should be a builtin (defun dired-buffer-more-recently-used-p (buffer1 buffer2) @@ -1418,12 +1514,16 @@ See also variable `dired-vm-read-only-folders'." ;;; REDEFINE. ;;; Redefines dired.el's version of `dired-initial-position' (defun dired-initial-position (dirname) + "Where point should go in a new listing of DIRNAME. +Point assumed at beginning of new subdir line. +You may redefine this function as you wish, e.g. like in `dired-x.el'." (end-of-line) (if dired-find-subdir (dired-goto-subdir dirname)) ; new (if dired-trivial-filenames (dired-goto-next-nontrivial-file))) ;; Does anyone use this? - lrd 6/29/93. +;; Apparently people do use it. - lrd 12/22/97. (defun dired-mark-sexp (predicate &optional unflag-p) "Mark files for which PREDICATE returns non-nil. With a prefix arg, unflag those files instead. @@ -1432,7 +1532,7 @@ PREDICATE is a lisp expression that can refer to the following symbols: inode [integer] the inode of the file (only for ls -i output) s [integer] the size of the file for ls -s output - (ususally in blocks or, with -k, in KByte) + (usually in blocks or, with -k, in KByte) mode [string] file permission bits, e.g. \"-rw-r--r--\" nlink [integer] number of links to file uid [string] owner @@ -1476,38 +1576,43 @@ to mark all zero length files." (if (looking-at dired-re-inode-size) (progn (goto-char (match-end 0)) - (setq inode (string-to-int (buffer-substring (match-beginning 1) - (match-end 1))) - s (string-to-int (buffer-substring (match-beginning 2) - (match-end 2))))) + (setq inode (string-to-number (buffer-substring (match-beginning 1) + (match-end 1))) + s (string-to-number (buffer-substring (match-beginning 2) + (match-end 2))))) (setq inode nil s nil)) (setq mode (buffer-substring (point) (+ mode-len (point)))) (forward-char mode-len) (setq nlink (read (current-buffer))) - (setq uid (buffer-substring (point) (progn (forward-word 1) (point)))) - (re-search-forward "\\(Jan\\|Feb\\|Mar\\|Apr\\|May\\|Jun\\|Jul\\|Aug\\|Sep\\|Oct\\|Nov\\|Dec\\)") + ;; Karsten Wenger fixed uid. + (setq uid (buffer-substring (+ (point) 1) + (progn (forward-word 1) (point)))) + (re-search-forward directory-listing-before-filename-regexp) (goto-char (match-beginning 1)) (forward-char -1) - (setq size (string-to-int (buffer-substring (save-excursion - (backward-word 1) - (setq pos (point))) - (point)))) + (setq size (string-to-number (buffer-substring (save-excursion + (backward-word 1) + (setq pos (point))) + (point)))) (goto-char pos) (backward-word 1) ;; if no gid is displayed, gid will be set to uid ;; but user will then not reference it anyway in PREDICATE. - (setq gid (buffer-substring (save-excursion (forward-word 1) (point)) + (setq gid (buffer-substring (save-excursion + (forward-word 1) (point)) (point)) time (buffer-substring (match-beginning 1) (1- (dired-move-to-filename))) name (buffer-substring (point) - (or (dired-move-to-end-of-filename t) - (point))) + (or + (dired-move-to-end-of-filename t) + (point))) sym (progn (if (looking-at " -> ") - (buffer-substring (progn (forward-char 4) (point)) - (progn (end-of-line) (point))) + (buffer-substring + (progn (forward-char 4) (point)) + (progn (end-of-line) (point))) ""))) t) nil) @@ -1515,12 +1620,12 @@ to mark all zero length files." (format "'%s file" predicate)))) -;;;; FIND FILE AT POINT. +;;; FIND FILE AT POINT. (defvar dired-x-hands-off-my-keys t - "*t means don't bind `dired-x-find-file' over `find-file' on keyboard. + "*Non-nil means don't bind `dired-x-find-file' over `find-file' on keyboard. Similarly for `dired-x-find-file-other-window' over `find-file-other-window'. -If you change this variable after dired-x.el is loaded then do +If you change this variable after `dired-x.el' is loaded then do \\[dired-x-bind-find-file].") ;;; Bind `dired-x-find-file{-other-window}' over wherever @@ -1529,7 +1634,7 @@ If you change this variable after dired-x.el is loaded then do "Bind `dired-x-find-file' in place of `find-file' \(or reverse\). Similarly for `dired-x-find-file-other-window' and `find-file-other-window'. Binding direction based on `dired-x-hands-off-my-keys'. -This function part of `after-init-hook'." +This function is part of `after-init-hook'." (interactive) (if (interactive-p) (setq dired-x-hands-off-my-keys @@ -1562,9 +1667,9 @@ May create a new window, or reuse an existing one. See the function `display-buffer'. Identical to `find-file' except when called interactively, with a prefix arg -\(e.g., \\[universal-argument]\), in which case it guesses filename near -point. Useful for editing file mentioned in buffer you are viewing, or to -test if that file exists. Use minibuffer after snatching filename." +\(e.g., \\[universal-argument]\), in which case it guesses filename near point. +Useful for editing file mentioned in buffer you are viewing, +or to test if that file exists. Use minibuffer after snatching filename." (interactive (list (read-filename-at-point "Find file: "))) (find-file (expand-file-name filename))) @@ -1574,23 +1679,22 @@ May create a new window, or reuse an existing one. See the function `display-buffer'. Identical to `find-file-other-window' except when called interactively, with a -prefix arg \(e.g., \\[universal-argument]\), in which case it guesses filename -near point. Useful for editing file mentioned in buffer you are viewing, or -to test if that file exists. Use minibuffer after snatching filename." +prefix arg \(e.g., \\[universal-argument]\), in which case it guesses filename near point. +Useful for editing file mentioned in buffer you are viewing, +or to test if that file exists. Use minibuffer after snatching filename." (interactive (list (read-filename-at-point "Find file: "))) (find-file-other-window (expand-file-name filename))) ;;; Internal functions. -(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. +;; 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---_/:$+") - (bol (save-excursion (beginning-of-line) (point))) - (eol (save-excursion (end-of-line) (point))) - start end filename) + (let ((filename-chars "-.[:alnum:]_/:$+@") + start end filename prefix) (save-excursion ;; First see if just past a filename. @@ -1604,20 +1708,28 @@ to test if that file exists. Use minibuffer after snatching 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 (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!")) ;; Return string. - (expand-file-name (buffer-substring start (point)))))) + (expand-file-name (concat prefix (buffer-substring start (point))))))) (defun read-filename-at-point (prompt) - ;;; Returns filename prompting with PROMPT with completion. If - ;;; `current-prefix-arg' is non-nil, uses name at point as guess. + "Return filename prompting with PROMPT with completion. +If `current-prefix-arg' is non-nil, uses name at point as guess." (if current-prefix-arg (let ((guess (dired-filename-at-point))) (read-file-name prompt @@ -1625,29 +1737,17 @@ to test if that file exists. Use minibuffer after snatching filename." guess nil (file-name-nondirectory guess))) (read-file-name prompt default-directory))) - -;;;; BUG REPORTS +;;; BUG REPORTS + +;; Fixme: get rid of this later. ;;; This section is provided for reports. It uses Barry A. Warsaw's ;;; reporter.el which is bundled with GNU Emacs v19. -(defconst dired-x-version "2.37" - "Revision number of dired-x.el -- dired extra for GNU Emacs v19. -Type \\[dired-x-submit-report] to send a bug report. Available via anonymous -ftp in - - /roebling.poly.edu:/pub/packages/dired-x.tar.gz") - -(defconst dired-x-help-address "dodd@roebling.poly.edu" +(defconst dired-x-help-address "bug-gnu-emacs@gnu.org" "Address(es) accepting submission of reports on dired-x.el.") -(defconst dired-x-maintainer "Larry" - "First name(s) of people accepting submission of reports on dired-x.el.") - -(defconst dired-x-file "dired-x.el" - "Name of file containing emacs lisp code.") - (defconst dired-x-variable-list (list 'dired-bind-vm @@ -1663,38 +1763,29 @@ ftp in '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 ) - "List of variables to be appended to reports sent by `dired-x-submit-report.'") + "List of variables to be appended to reports sent by `dired-x-submit-report'.") (defun dired-x-submit-report () - "Submit via reporter.el a bug report on program. Send report on `dired-x-file' -version `dired-x-version,' to `dired-x-maintainer' at address `dired-x-help-address' -listing variables `dired-x-variable-list' in the message." + "Submit via `reporter.el' a bug report on program. +Send report on `dired-x-file' version `dired-x-version,' to +`dired-x-maintainer' at address `dired-x-help-address' listing +variables `dired-x-variable-list' in the message." (interactive) - ;; In case we can't find reporter... - (condition-case err - (progn - ;; Get it if we can. - (require 'reporter) - - (reporter-submit-bug-report - dired-x-help-address ; address - (concat dired-x-file " (" dired-x-version ")") ; pkgname - dired-x-variable-list ; varlist - nil nil ; pre-/post-hooks - (concat dired-x-maintainer ","))) ; salutation - - ;; ...fail gracefully. - (error - (beep) - (message "Sorry, reporter.el not found.")))) + (reporter-submit-bug-report + dired-x-help-address ; address + "dired-x" ; pkgname + dired-x-variable-list ; varlist + nil nil ; pre-/post-hooks + "")) ;; As Barry Warsaw would say: "This might be useful..." (provide 'dired-x) +;; arch-tag: 71a43ba2-7a00-4793-a028-0613dd7765ae ;;; dired-x.el ends here