mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-12-27 10:54:40 +00:00
Added better remote directory support to Eshell, as well as a few bug
fixes. See the ChangeLog.
This commit is contained in:
parent
e2c06b17a9
commit
8c6b1d8311
@ -1,3 +1,82 @@
|
|||||||
|
2000-10-13 John Wiegley <johnw@gnu.org>
|
||||||
|
|
||||||
|
* eshell/esh-util.el: Added a global form which declares an
|
||||||
|
autoload for `parse-time-string', if that function is not already
|
||||||
|
defined, and if parse-time.el is available on the user's system.
|
||||||
|
|
||||||
|
* eshell/em-ls.el (eshell-ls-applicable): Extended this function
|
||||||
|
to be aware of ange-ftp user info.
|
||||||
|
(eshell-do-ls): Bind `ange-cache'. Also, use
|
||||||
|
`eshell-file-attributes'.
|
||||||
|
(eshell-ls-annotate): Use `eshell-file-attributes'.
|
||||||
|
(eshell-ls-file): Made the user-id printing code a bit smarter.
|
||||||
|
|
||||||
|
* eshell/esh-util.el (eshell-ange-ls-uids): Added variable, to
|
||||||
|
allow identification of alias user ids in remote directories.
|
||||||
|
It's manual, but there's no other way to know when the current
|
||||||
|
user on the local machine, is also the owning user on the remote
|
||||||
|
machine.
|
||||||
|
(fboundp): Bind `ange-cache'.
|
||||||
|
(eshell-directory-files-and-attributes): Re-organized the logic a
|
||||||
|
bit to use `eshell-file-attributes' instead of `file-attributes'.
|
||||||
|
The former is more sensitive to directories that are read via FTP,
|
||||||
|
and knows how to use ange-ftp to determine full attribute
|
||||||
|
information, instead of just the name and last modtime.
|
||||||
|
(eshell-current-ange-uids): Return the current user id when in a
|
||||||
|
remote directory.
|
||||||
|
(eshell-parse-ange-ls): Parse a full directory listing that has
|
||||||
|
been returned by ange-ftp.
|
||||||
|
(eshell-file-attributes): This beefed up version of
|
||||||
|
`file-attributes' is only special if the user is currently in a
|
||||||
|
remote directory, in which case it does a lot of work to find out
|
||||||
|
what the real attributes of a file are, as they appear on the
|
||||||
|
remote machine. This makes usage of remote directories (i.e.,
|
||||||
|
ange-ftp pathnames) much more useful. You can now use Eshell as a
|
||||||
|
full-fledged FTP client, with much more manipulation ability than
|
||||||
|
most other clients.
|
||||||
|
|
||||||
|
* eshell/em-unix.el (eshell-du-prefer-over-ange): Added a new
|
||||||
|
variable, which means that Eshell's du should always be preferred
|
||||||
|
in remote directories.
|
||||||
|
(eshell-shuffle-files): Use `eshell-file-attributes', rather than
|
||||||
|
just `file-attributes'.
|
||||||
|
(eshell-mvcp-template): Bind `ange-cache', to improve performance
|
||||||
|
when reading remote directories. This is an Eshell-specific
|
||||||
|
variable (not part of ange-ftp).
|
||||||
|
(eshell/ln): Bind `ange-cache'.
|
||||||
|
(eshell/du): Added some extra logic for determining when to use
|
||||||
|
Eshell's du (which is slow), and when to use the external version
|
||||||
|
(which may or may not exist).
|
||||||
|
|
||||||
|
* eshell/em-rebind.el (eshell-delchar-or-maybe-eof): Call
|
||||||
|
`eshell-interactive-process', rather than using
|
||||||
|
`get-buffer-process', since backgrounded processes don't count in
|
||||||
|
the context of this function's logic.
|
||||||
|
|
||||||
|
* eshell/esh-arg.el (eshell-parse-double-quote): Moved a call to
|
||||||
|
`forward-char', so that null strings are parsed correctly.
|
||||||
|
|
||||||
|
2000-09-10 John Wiegley <johnw@gnu.org>
|
||||||
|
|
||||||
|
* eshell/em-pred.el (eshell-pred-file-type,
|
||||||
|
eshell-pred-file-links, eshell-pred-file-size): Use
|
||||||
|
`eshell-file-attributes'. This is more correct over ange-ftp.
|
||||||
|
|
||||||
|
* eshell/em-glob.el (eshell-extended-glob): Bind `ange-cache', so
|
||||||
|
that remote file globbing is more efficient.
|
||||||
|
|
||||||
|
* eshell/em-ls.el (eshell-ls-dir): Use `expand-file-name' when
|
||||||
|
gathering the files and attributes within a directory.
|
||||||
|
|
||||||
|
* eshell/em-unix.el (eshell/cat): If any of the files passed on
|
||||||
|
the command line is a special file (not a regular file, directory
|
||||||
|
or symlink), always attempt to call the external version of cat.
|
||||||
|
|
||||||
|
2000-09-06 John Wiegley <johnw@gnu.org>
|
||||||
|
|
||||||
|
* eshell/esh-mode.el (eshell-find-tag): Corrections to the
|
||||||
|
Eshell-friendly version of find-tag.
|
||||||
|
|
||||||
2000-10-13 Miles Bader <miles@lsi.nec.co.jp>
|
2000-10-13 Miles Bader <miles@lsi.nec.co.jp>
|
||||||
|
|
||||||
* image-file.el (image-file-name-extensions)
|
* image-file.el (image-file-name-extensions)
|
||||||
@ -347,6 +426,8 @@
|
|||||||
* files.el (set-auto-mode): Ignore unknown -*- mode -*- rather than
|
* files.el (set-auto-mode): Ignore unknown -*- mode -*- rather than
|
||||||
raise an error. This way it can still default to a sane value.
|
raise an error. This way it can still default to a sane value.
|
||||||
|
|
||||||
|
2000-10-06 Stefan Monnier <monnier@cs.yale.edu>
|
||||||
|
|
||||||
* startup.el (fancy-splash-screens): Use local rather than global map.
|
* startup.el (fancy-splash-screens): Use local rather than global map.
|
||||||
Don't use `update-menu-bindings' any more.
|
Don't use `update-menu-bindings' any more.
|
||||||
Get rid of assumptions about keymap representation.
|
Get rid of assumptions about keymap representation.
|
||||||
@ -1362,9 +1443,6 @@
|
|||||||
|
|
||||||
2000-09-16 Andrew Innes <andrewi@gnu.org>
|
2000-09-16 Andrew Innes <andrewi@gnu.org>
|
||||||
|
|
||||||
* makefile.nt (compile-files): No need to make .elc files
|
|
||||||
read-only, since they aren't under VC now.
|
|
||||||
|
|
||||||
* makefile.w32-in (compile-files-CMD): No need to make .elc files
|
* makefile.w32-in (compile-files-CMD): No need to make .elc files
|
||||||
read-only, since they aren't under VC now.
|
read-only, since they aren't under VC now.
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ resulting regular expression."
|
|||||||
|
|
||||||
(INCLUDE-REGEXP EXCLUDE-REGEXP (PRED-FUNC-LIST) (MOD-FUNC-LIST))"
|
(INCLUDE-REGEXP EXCLUDE-REGEXP (PRED-FUNC-LIST) (MOD-FUNC-LIST))"
|
||||||
(let ((paths (eshell-split-path glob))
|
(let ((paths (eshell-split-path glob))
|
||||||
matches message-shown)
|
matches message-shown ange-cache)
|
||||||
(unwind-protect
|
(unwind-protect
|
||||||
(if (and (cdr paths)
|
(if (and (cdr paths)
|
||||||
(file-name-absolute-p (car paths)))
|
(file-name-absolute-p (car paths)))
|
||||||
|
@ -192,9 +192,15 @@ really need to stick around for very long."
|
|||||||
"Test whether, for ATTRS, the user UID can do what corresponds to INDEX.
|
"Test whether, for ATTRS, the user UID can do what corresponds to INDEX.
|
||||||
This is really just for efficiency, to avoid having to stat the file
|
This is really just for efficiency, to avoid having to stat the file
|
||||||
yet again."
|
yet again."
|
||||||
`(if (= (user-uid) (nth 2 ,attrs))
|
`(if (numberp (nth 2 ,attrs))
|
||||||
(not (eq (aref (nth 8 ,attrs) ,index) ?-))
|
(if (= (user-uid) (nth 2 ,attrs))
|
||||||
(,(eval func) ,file)))
|
(not (eq (aref (nth 8 ,attrs) ,index) ?-))
|
||||||
|
(,(eval func) ,file))
|
||||||
|
(not (eq (aref (nth 8 ,attrs)
|
||||||
|
(+ ,index (if (member (nth 2 ,attrs)
|
||||||
|
(eshell-current-ange-uids))
|
||||||
|
0 6)))
|
||||||
|
?-))))
|
||||||
|
|
||||||
(defcustom eshell-ls-highlight-alist nil
|
(defcustom eshell-ls-highlight-alist nil
|
||||||
"*This alist correlates test functions to color.
|
"*This alist correlates test functions to color.
|
||||||
@ -265,7 +271,8 @@ instead."
|
|||||||
(defvar show-all)
|
(defvar show-all)
|
||||||
(defvar show-recursive)
|
(defvar show-recursive)
|
||||||
(defvar show-size)
|
(defvar show-size)
|
||||||
(defvar sort-method))
|
(defvar sort-method)
|
||||||
|
(defvar ange-cache))
|
||||||
|
|
||||||
(defun eshell-do-ls (&rest args)
|
(defun eshell-do-ls (&rest args)
|
||||||
"Implementation of \"ls\" in Lisp, passing ARGS."
|
"Implementation of \"ls\" in Lisp, passing ARGS."
|
||||||
@ -328,7 +335,7 @@ Sort entries alphabetically across.")
|
|||||||
(setq listing-style 'by-columns))
|
(setq listing-style 'by-columns))
|
||||||
(unless args
|
(unless args
|
||||||
(setq args (list ".")))
|
(setq args (list ".")))
|
||||||
(let ((eshell-ls-exclude-regexp eshell-ls-exclude-regexp))
|
(let ((eshell-ls-exclude-regexp eshell-ls-exclude-regexp) ange-cache)
|
||||||
(when ignore-pattern
|
(when ignore-pattern
|
||||||
(unless (eshell-using-module 'eshell-glob)
|
(unless (eshell-using-module 'eshell-glob)
|
||||||
(error (concat "-I option requires that `eshell-glob'"
|
(error (concat "-I option requires that `eshell-glob'"
|
||||||
@ -347,7 +354,7 @@ Sort entries alphabetically across.")
|
|||||||
(file-name-absolute-p arg))
|
(file-name-absolute-p arg))
|
||||||
(expand-file-name arg)
|
(expand-file-name arg)
|
||||||
arg)
|
arg)
|
||||||
(file-attributes arg)))) args)
|
(eshell-file-attributes arg)))) args)
|
||||||
t (expand-file-name default-directory)))
|
t (expand-file-name default-directory)))
|
||||||
(funcall flush-func)))
|
(funcall flush-func)))
|
||||||
|
|
||||||
@ -379,7 +386,7 @@ name should be displayed as, etc. Think of it as cooking a FILEINFO."
|
|||||||
(file-name-directory
|
(file-name-directory
|
||||||
(expand-file-name (car fileinfo))))))
|
(expand-file-name (car fileinfo))))))
|
||||||
(setq attr
|
(setq attr
|
||||||
(file-attributes
|
(eshell-file-attributes
|
||||||
(let ((target (if dir
|
(let ((target (if dir
|
||||||
(expand-file-name (cadr fileinfo) dir)
|
(expand-file-name (cadr fileinfo) dir)
|
||||||
(cadr fileinfo))))
|
(cadr fileinfo))))
|
||||||
@ -425,16 +432,22 @@ whose cdr is the list of file attributes."
|
|||||||
"%s%4d %-8s %-8s "
|
"%s%4d %-8s %-8s "
|
||||||
(or (nth 8 attrs) "??????????")
|
(or (nth 8 attrs) "??????????")
|
||||||
(or (nth 1 attrs) 0)
|
(or (nth 1 attrs) 0)
|
||||||
(or (and (not numeric-uid-gid)
|
(or (let ((user (nth 2 attrs)))
|
||||||
(nth 2 attrs)
|
(and (not numeric-uid-gid)
|
||||||
(eshell-substring
|
user
|
||||||
(user-login-name (nth 2 attrs)) 8))
|
(eshell-substring
|
||||||
|
(if (numberp user)
|
||||||
|
(user-login-name user)
|
||||||
|
user) 8)))
|
||||||
(nth 2 attrs)
|
(nth 2 attrs)
|
||||||
"")
|
"")
|
||||||
(or (and (not numeric-uid-gid)
|
(or (let ((group (nth 3 attrs)))
|
||||||
(nth 3 attrs)
|
(and (not numeric-uid-gid)
|
||||||
(eshell-substring
|
group
|
||||||
(eshell-group-name (nth 3 attrs)) 8))
|
(eshell-substring
|
||||||
|
(if (numberp group)
|
||||||
|
(eshell-group-name group)
|
||||||
|
group) 8)))
|
||||||
(nth 3 attrs)
|
(nth 3 attrs)
|
||||||
""))
|
""))
|
||||||
(let* ((str (eshell-ls-printable-size (nth 7 attrs)))
|
(let* ((str (eshell-ls-printable-size (nth 7 attrs)))
|
||||||
|
@ -464,7 +464,7 @@ that 'ls -l' will show in the first column of its display. "
|
|||||||
(forward-char)
|
(forward-char)
|
||||||
(setq type ?%)))
|
(setq type ?%)))
|
||||||
`(lambda (file)
|
`(lambda (file)
|
||||||
(let ((attrs (file-attributes (directory-file-name file))))
|
(let ((attrs (eshell-file-attributes (directory-file-name file))))
|
||||||
(if attrs
|
(if attrs
|
||||||
(memq (aref (nth 8 attrs) 0)
|
(memq (aref (nth 8 attrs) 0)
|
||||||
,(if (eq type ?%)
|
,(if (eq type ?%)
|
||||||
@ -489,7 +489,7 @@ that 'ls -l' will show in the first column of its display. "
|
|||||||
(setq amount (string-to-number (match-string 0)))
|
(setq amount (string-to-number (match-string 0)))
|
||||||
(goto-char (match-end 0))
|
(goto-char (match-end 0))
|
||||||
`(lambda (file)
|
`(lambda (file)
|
||||||
(let ((attrs (file-attributes file)))
|
(let ((attrs (eshell-file-attributes file)))
|
||||||
(if attrs
|
(if attrs
|
||||||
(,(if (eq qual ?-)
|
(,(if (eq qual ?-)
|
||||||
'<
|
'<
|
||||||
@ -518,7 +518,7 @@ that 'ls -l' will show in the first column of its display. "
|
|||||||
(setq amount (* (string-to-number (match-string 0)) quantum))
|
(setq amount (* (string-to-number (match-string 0)) quantum))
|
||||||
(goto-char (match-end 0))
|
(goto-char (match-end 0))
|
||||||
`(lambda (file)
|
`(lambda (file)
|
||||||
(let ((attrs (file-attributes file)))
|
(let ((attrs (eshell-file-attributes file)))
|
||||||
(if attrs
|
(if attrs
|
||||||
(,(if (eq qual ?-)
|
(,(if (eq qual ?-)
|
||||||
'<
|
'<
|
||||||
|
@ -232,7 +232,7 @@ lock it at that."
|
|||||||
Sends an EOF only if point is at the end of the buffer and there is no
|
Sends an EOF only if point is at the end of the buffer and there is no
|
||||||
input."
|
input."
|
||||||
(interactive "p")
|
(interactive "p")
|
||||||
(let ((proc (get-buffer-process (current-buffer))))
|
(let ((proc (eshell-interactive-process)))
|
||||||
(if (eobp)
|
(if (eobp)
|
||||||
(cond
|
(cond
|
||||||
((/= (point) eshell-last-output-end)
|
((/= (point) eshell-last-output-end)
|
||||||
|
@ -122,6 +122,12 @@ Otherwise, `rmdir' is required."
|
|||||||
:type 'boolean
|
:type 'boolean
|
||||||
:group 'eshell-unix)
|
:group 'eshell-unix)
|
||||||
|
|
||||||
|
(defcustom eshell-du-prefer-over-ange nil
|
||||||
|
"*Use Eshell's du in ange-ftp remote directories.
|
||||||
|
Otherwise, Emacs will attempt to use rsh to invoke du the machine."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'eshell-unix)
|
||||||
|
|
||||||
(require 'esh-opt)
|
(require 'esh-opt)
|
||||||
|
|
||||||
;;; Functions:
|
;;; Functions:
|
||||||
@ -296,7 +302,7 @@ Remove the DIRECTORY(ies), if they are empty.")
|
|||||||
"Shuffle around some filesystem entries, using FUNC to do the work."
|
"Shuffle around some filesystem entries, using FUNC to do the work."
|
||||||
(if (null target)
|
(if (null target)
|
||||||
(error "%s: missing destination file" command))
|
(error "%s: missing destination file" command))
|
||||||
(let ((attr-target (file-attributes target))
|
(let ((attr-target (eshell-file-attributes target))
|
||||||
(is-dir (or (file-directory-p target)
|
(is-dir (or (file-directory-p target)
|
||||||
(and preview (not eshell-warn-dot-directories))))
|
(and preview (not eshell-warn-dot-directories))))
|
||||||
attr)
|
attr)
|
||||||
@ -315,8 +321,10 @@ Remove the DIRECTORY(ies), if they are empty.")
|
|||||||
((and attr-target
|
((and attr-target
|
||||||
(or (not (eshell-under-windows-p))
|
(or (not (eshell-under-windows-p))
|
||||||
(eq system-type 'ms-dos))
|
(eq system-type 'ms-dos))
|
||||||
(setq attr (file-attributes (car files)))
|
(setq attr (eshell-file-attributes (car files)))
|
||||||
|
(nth 10 attr-target) (nth 10 attr)
|
||||||
(= (nth 10 attr-target) (nth 10 attr))
|
(= (nth 10 attr-target) (nth 10 attr))
|
||||||
|
(nth 11 attr-target) (nth 11 attr)
|
||||||
(= (nth 11 attr-target) (nth 11 attr)))
|
(= (nth 11 attr-target) (nth 11 attr)))
|
||||||
(eshell-error (format "%s: `%s' and `%s' are the same file\n"
|
(eshell-error (format "%s: `%s' and `%s' are the same file\n"
|
||||||
command (car files) target)))
|
command (car files) target)))
|
||||||
@ -339,10 +347,10 @@ Remove the DIRECTORY(ies), if they are empty.")
|
|||||||
(let (eshell-warn-dot-directories)
|
(let (eshell-warn-dot-directories)
|
||||||
(if (and (not deep)
|
(if (and (not deep)
|
||||||
(eq func 'rename-file)
|
(eq func 'rename-file)
|
||||||
(= (nth 11 (file-attributes
|
(= (nth 11 (eshell-file-attributes
|
||||||
(file-name-directory
|
(file-name-directory
|
||||||
(expand-file-name source))))
|
(expand-file-name source))))
|
||||||
(nth 11 (file-attributes
|
(nth 11 (eshell-file-attributes
|
||||||
(file-name-directory
|
(file-name-directory
|
||||||
(expand-file-name target))))))
|
(expand-file-name target))))))
|
||||||
(apply 'eshell-funcalln func source target args)
|
(apply 'eshell-funcalln func source target args)
|
||||||
@ -415,7 +423,7 @@ Remove the DIRECTORY(ies), if they are empty.")
|
|||||||
(or (not no-dereference)
|
(or (not no-dereference)
|
||||||
(not (file-symlink-p (car args)))))))
|
(not (file-symlink-p (car args)))))))
|
||||||
(eshell-shorthand-tar-command ,command args)
|
(eshell-shorthand-tar-command ,command args)
|
||||||
(let (target)
|
(let (target ange-cache)
|
||||||
(if (> (length args) 1)
|
(if (> (length args) 1)
|
||||||
(progn
|
(progn
|
||||||
(setq target (car (last args)))
|
(setq target (car (last args)))
|
||||||
@ -508,7 +516,7 @@ Create a link to the specified TARGET with optional LINK_NAME. If there is
|
|||||||
more than one TARGET, the last argument must be a directory; create links
|
more than one TARGET, the last argument must be a directory; create links
|
||||||
in DIRECTORY to each TARGET. Create hard links by default, symbolic links
|
in DIRECTORY to each TARGET. Create hard links by default, symbolic links
|
||||||
with '--symbolic'. When creating hard links, each TARGET must exist.")
|
with '--symbolic'. When creating hard links, each TARGET must exist.")
|
||||||
(let (target no-dereference)
|
(let (target no-dereference ange-cache)
|
||||||
(if (> (length args) 1)
|
(if (> (length args) 1)
|
||||||
(progn
|
(progn
|
||||||
(setq target (car (last args)))
|
(setq target (car (last args)))
|
||||||
@ -525,10 +533,24 @@ with '--symbolic'. When creating hard links, each TARGET must exist.")
|
|||||||
nil))
|
nil))
|
||||||
|
|
||||||
(defun eshell/cat (&rest args)
|
(defun eshell/cat (&rest args)
|
||||||
"Implementation of cat in Lisp."
|
"Implementation of cat in Lisp.
|
||||||
(if eshell-in-pipeline-p
|
If in a pipeline, or the file is not a regular file, directory or
|
||||||
(throw 'eshell-replace-command
|
symlink, then revert to the system's definition of cat."
|
||||||
(eshell-parse-command "*cat" (eshell-flatten-list args)))
|
(setq args (eshell-flatten-list args))
|
||||||
|
(if (or eshell-in-pipeline-p
|
||||||
|
(catch 'special
|
||||||
|
(eshell-for arg args
|
||||||
|
(unless (let ((attrs (eshell-file-attributes arg)))
|
||||||
|
(and attrs (memq (aref (nth 8 attrs) 0)
|
||||||
|
'(?d ?l ?-))))
|
||||||
|
(throw 'special t)))))
|
||||||
|
(let ((ext-cat (eshell-search-path "cat")))
|
||||||
|
(if ext-cat
|
||||||
|
(throw 'eshell-replace-command
|
||||||
|
(eshell-parse-command ext-cat args))
|
||||||
|
(if eshell-in-pipeline-p
|
||||||
|
(error "Eshell's `cat' does not work in pipelines")
|
||||||
|
(error "Eshell's `cat' cannot display one of the files given"))))
|
||||||
(eshell-init-print-buffer)
|
(eshell-init-print-buffer)
|
||||||
(eshell-eval-using-options
|
(eshell-eval-using-options
|
||||||
"cat" args
|
"cat" args
|
||||||
@ -772,61 +794,69 @@ external command."
|
|||||||
|
|
||||||
(defun eshell/du (&rest args)
|
(defun eshell/du (&rest args)
|
||||||
"Implementation of \"du\" in Lisp, passing ARGS."
|
"Implementation of \"du\" in Lisp, passing ARGS."
|
||||||
(if (eshell-search-path "du")
|
(setq args (if args
|
||||||
(throw 'eshell-replace-command
|
(eshell-flatten-list args)
|
||||||
(eshell-parse-command "*du" (eshell-flatten-list args)))
|
'(".")))
|
||||||
(eshell-eval-using-options
|
(let ((ext-du (eshell-search-path "du")))
|
||||||
"du" args
|
(if (and ext-du
|
||||||
'((?a "all" nil show-all
|
(not (catch 'have-ange-path
|
||||||
"write counts for all files, not just directories")
|
(eshell-for arg args
|
||||||
(nil "block-size" t block-size
|
(if (eq (find-file-name-handler (expand-file-name arg)
|
||||||
"use SIZE-byte blocks (i.e., --block-size SIZE)")
|
'directory-files)
|
||||||
(?b "bytes" nil by-bytes
|
'ange-ftp-hook-function)
|
||||||
"print size in bytes")
|
(throw 'have-ange-path t))))))
|
||||||
(?c "total" nil grand-total
|
(throw 'eshell-replace-command
|
||||||
"produce a grand total")
|
(eshell-parse-command ext-du args))
|
||||||
(?d "max-depth" t max-depth
|
(eshell-eval-using-options
|
||||||
"display data only this many levels of data")
|
"du" args
|
||||||
(?h "human-readable" 1024 human-readable
|
'((?a "all" nil show-all
|
||||||
"print sizes in human readable format")
|
"write counts for all files, not just directories")
|
||||||
(?H "is" 1000 human-readable
|
(nil "block-size" t block-size
|
||||||
"likewise, but use powers of 1000 not 1024")
|
"use SIZE-byte blocks (i.e., --block-size SIZE)")
|
||||||
(?k "kilobytes" 1024 block-size
|
(?b "bytes" nil by-bytes
|
||||||
"like --block-size 1024")
|
"print size in bytes")
|
||||||
(?L "dereference" nil dereference-links
|
(?c "total" nil grand-total
|
||||||
"dereference all symbolic links")
|
"produce a grand total")
|
||||||
(?m "megabytes" 1048576 block-size
|
(?d "max-depth" t max-depth
|
||||||
"like --block-size 1048576")
|
"display data only this many levels of data")
|
||||||
(?s "summarize" 0 max-depth
|
(?h "human-readable" 1024 human-readable
|
||||||
"display only a total for each argument")
|
"print sizes in human readable format")
|
||||||
(?x "one-file-system" nil only-one-filesystem
|
(?H "is" 1000 human-readable
|
||||||
"skip directories on different filesystems")
|
"likewise, but use powers of 1000 not 1024")
|
||||||
(nil "help" nil nil
|
(?k "kilobytes" 1024 block-size
|
||||||
"show this usage screen")
|
"like --block-size 1024")
|
||||||
:external "du"
|
(?L "dereference" nil dereference-links
|
||||||
:usage "[OPTION]... FILE...
|
"dereference all symbolic links")
|
||||||
|
(?m "megabytes" 1048576 block-size
|
||||||
|
"like --block-size 1048576")
|
||||||
|
(?s "summarize" 0 max-depth
|
||||||
|
"display only a total for each argument")
|
||||||
|
(?x "one-file-system" nil only-one-filesystem
|
||||||
|
"skip directories on different filesystems")
|
||||||
|
(nil "help" nil nil
|
||||||
|
"show this usage screen")
|
||||||
|
:external "du"
|
||||||
|
:usage "[OPTION]... FILE...
|
||||||
Summarize disk usage of each FILE, recursively for directories.")
|
Summarize disk usage of each FILE, recursively for directories.")
|
||||||
(unless by-bytes
|
(unless by-bytes
|
||||||
(setq block-size (or block-size 1024)))
|
(setq block-size (or block-size 1024)))
|
||||||
(if (and max-depth (stringp max-depth))
|
(if (and max-depth (stringp max-depth))
|
||||||
(setq max-depth (string-to-int max-depth)))
|
(setq max-depth (string-to-int max-depth)))
|
||||||
;; filesystem support means nothing under Windows
|
;; filesystem support means nothing under Windows
|
||||||
(if (eshell-under-windows-p)
|
(if (eshell-under-windows-p)
|
||||||
(setq only-one-filesystem nil))
|
(setq only-one-filesystem nil))
|
||||||
(unless args
|
(let ((size 0.0) ange-cache)
|
||||||
(setq args '(".")))
|
(while args
|
||||||
(let ((size 0.0))
|
(if only-one-filesystem
|
||||||
(while args
|
(setq only-one-filesystem
|
||||||
(if only-one-filesystem
|
(nth 11 (eshell-file-attributes
|
||||||
(setq only-one-filesystem
|
(file-name-as-directory (car args))))))
|
||||||
(nth 11 (file-attributes
|
(setq size (+ size (eshell-du-sum-directory
|
||||||
(file-name-as-directory (car args))))))
|
(directory-file-name (car args)) 0)))
|
||||||
(setq size (+ size (eshell-du-sum-directory
|
(setq args (cdr args)))
|
||||||
(directory-file-name (car args)) 0)))
|
(if grand-total
|
||||||
(setq args (cdr args)))
|
(eshell-print (concat (eshell-du-size-string size)
|
||||||
(if grand-total
|
"total\n"))))))))
|
||||||
(eshell-print (concat (eshell-du-size-string size)
|
|
||||||
"total\n")))))))
|
|
||||||
|
|
||||||
(defvar eshell-time-start nil)
|
(defvar eshell-time-start nil)
|
||||||
|
|
||||||
|
@ -328,13 +328,13 @@ special character that is not itself a backslash."
|
|||||||
(defun eshell-parse-double-quote ()
|
(defun eshell-parse-double-quote ()
|
||||||
"Parse a double quoted string, which allows for variable interpolation."
|
"Parse a double quoted string, which allows for variable interpolation."
|
||||||
(when (eq (char-after) ?\")
|
(when (eq (char-after) ?\")
|
||||||
(forward-char)
|
|
||||||
(let* ((end (eshell-find-delimiter ?\" ?\" nil nil t))
|
(let* ((end (eshell-find-delimiter ?\" ?\" nil nil t))
|
||||||
(eshell-current-quoted t))
|
(eshell-current-quoted t))
|
||||||
(if (not end)
|
(if (not end)
|
||||||
(throw 'eshell-incomplete ?\")
|
(throw 'eshell-incomplete ?\")
|
||||||
(prog1
|
(prog1
|
||||||
(save-restriction
|
(save-restriction
|
||||||
|
(forward-char)
|
||||||
(narrow-to-region (point) end)
|
(narrow-to-region (point) end)
|
||||||
(list 'eshell-escape-arg
|
(list 'eshell-escape-arg
|
||||||
(eshell-parse-argument)))
|
(eshell-parse-argument)))
|
||||||
|
@ -524,8 +524,9 @@ sessions, such as when using `eshell-command'.")
|
|||||||
(interactive)
|
(interactive)
|
||||||
(require 'etags)
|
(require 'etags)
|
||||||
(let ((inhibit-read-only t)
|
(let ((inhibit-read-only t)
|
||||||
(no-default (eobp)))
|
(no-default (eobp))
|
||||||
(setq tagname (find-tag-interactive "Find tag: " no-default))
|
(find-tag-default-function 'ignore))
|
||||||
|
(setq tagname (car (find-tag-interactive "Find tag: ")))
|
||||||
(find-tag tagname next-p regexp-p)))
|
(find-tag tagname next-p regexp-p)))
|
||||||
|
|
||||||
(defun eshell-move-argument (limit func property arg)
|
(defun eshell-move-argument (limit func property arg)
|
||||||
|
@ -86,6 +86,15 @@ function `string-to-number'."
|
|||||||
:type 'regexp
|
:type 'regexp
|
||||||
:group 'eshell-util)
|
:group 'eshell-util)
|
||||||
|
|
||||||
|
(defcustom eshell-ange-ls-uids nil
|
||||||
|
"*List of user/host/id strings, used to determine remote ownership."
|
||||||
|
:type '(list (cons :tag "Host/User Pair"
|
||||||
|
(string :tag "Hostname")
|
||||||
|
(repeat (cons :tag "User/UID List"
|
||||||
|
(string :tag "Username")
|
||||||
|
(repeat :tag "UIDs" string)))))
|
||||||
|
:group 'eshell-util)
|
||||||
|
|
||||||
;;; Internal Variables:
|
;;; Internal Variables:
|
||||||
|
|
||||||
(defvar eshell-group-names nil
|
(defvar eshell-group-names nil
|
||||||
@ -558,28 +567,123 @@ Unless optional argument INPLACE is non-nil, return a new string."
|
|||||||
(unless (fboundp 'directory-files-and-attributes)
|
(unless (fboundp 'directory-files-and-attributes)
|
||||||
(defun directory-files-and-attributes (dir &optional full match nosort)
|
(defun directory-files-and-attributes (dir &optional full match nosort)
|
||||||
(documentation 'directory-files)
|
(documentation 'directory-files)
|
||||||
(let* ((dir (expand-file-name dir))
|
(let ((dir (expand-file-name dir)) ange-cache)
|
||||||
(default-directory dir))
|
|
||||||
(mapcar
|
(mapcar
|
||||||
(function
|
(function
|
||||||
(lambda (file)
|
(lambda (file)
|
||||||
(cons file (file-attributes file))))
|
(cons file (eshell-file-attributes (expand-file-name file dir)))))
|
||||||
(directory-files dir full match nosort)))))
|
(directory-files dir full match nosort)))))
|
||||||
|
|
||||||
|
(eval-when-compile
|
||||||
|
(defvar ange-cache))
|
||||||
|
|
||||||
(defun eshell-directory-files-and-attributes (dir &optional full match nosort)
|
(defun eshell-directory-files-and-attributes (dir &optional full match nosort)
|
||||||
"Make sure to use the handler for `directory-file-and-attributes'."
|
"Make sure to use the handler for `directory-file-and-attributes'."
|
||||||
(let ((dfh (find-file-name-handler dir 'directory-files)))
|
(let* ((dir (expand-file-name dir))
|
||||||
|
(dfh (find-file-name-handler dir 'directory-files)))
|
||||||
(if (not dfh)
|
(if (not dfh)
|
||||||
(directory-files-and-attributes dir full match nosort)
|
(directory-files-and-attributes dir full match nosort)
|
||||||
(let* ((files (funcall dfh 'directory-files dir full match nosort))
|
(let ((files (funcall dfh 'directory-files dir full match nosort))
|
||||||
(fah (find-file-name-handler dir 'file-attributes))
|
(fah (find-file-name-handler dir 'file-attributes)))
|
||||||
(default-directory (expand-file-name dir)))
|
|
||||||
(mapcar
|
(mapcar
|
||||||
(function
|
(function
|
||||||
(lambda (file)
|
(lambda (file)
|
||||||
(cons file (funcall fah 'file-attributes file))))
|
(cons file (if fah
|
||||||
|
(eshell-file-attributes
|
||||||
|
(expand-file-name file dir))
|
||||||
|
(file-attributes (expand-file-name file dir))))))
|
||||||
files)))))
|
files)))))
|
||||||
|
|
||||||
|
(defun eshell-current-ange-uids ()
|
||||||
|
(if (string-match "/\\([^@]+\\)@\\([^:]+\\):" default-directory)
|
||||||
|
(let* ((host (match-string 2 default-directory))
|
||||||
|
(user (match-string 1 default-directory))
|
||||||
|
(host-users (assoc host eshell-ange-ls-uids)))
|
||||||
|
(when host-users
|
||||||
|
(setq host-users (cdr host-users))
|
||||||
|
(cdr (assoc user host-users))))))
|
||||||
|
|
||||||
|
;; Add an autoload for parse-time-string
|
||||||
|
(if (and (not (fboundp 'parse-time-string))
|
||||||
|
(locate-library "parse-time"))
|
||||||
|
(autoload 'parse-time-string "parse-time"))
|
||||||
|
|
||||||
|
(defun eshell-parse-ange-ls (dir)
|
||||||
|
(let (entry)
|
||||||
|
(with-temp-buffer
|
||||||
|
(insert (ange-ftp-ls dir "-la" nil))
|
||||||
|
(goto-char (point-min))
|
||||||
|
(if (looking-at "^total [0-9]+$")
|
||||||
|
(forward-line 1))
|
||||||
|
;; Some systems put in a blank line here.
|
||||||
|
(if (eolp) (forward-line 1))
|
||||||
|
(while (looking-at
|
||||||
|
`,(concat "\\([dlscb-][rwxst-]+\\)"
|
||||||
|
"\\s-*" "\\([0-9]+\\)" "\\s-+"
|
||||||
|
"\\(\\S-+\\)" "\\s-+"
|
||||||
|
"\\(\\S-+\\)" "\\s-+"
|
||||||
|
"\\([0-9]+\\)" "\\s-+" "\\(.*\\)"))
|
||||||
|
(let* ((perms (match-string 1))
|
||||||
|
(links (string-to-number (match-string 2)))
|
||||||
|
(user (match-string 3))
|
||||||
|
(group (match-string 4))
|
||||||
|
(size (string-to-number (match-string 5)))
|
||||||
|
(mtime
|
||||||
|
(if (fboundp 'parse-time-string)
|
||||||
|
(let ((moment (parse-time-string
|
||||||
|
(match-string 6))))
|
||||||
|
(if (nth 0 moment)
|
||||||
|
(setcar (nthcdr 5 moment)
|
||||||
|
(nth 5 (decode-time (current-time))))
|
||||||
|
(setcar (nthcdr 0 moment) 0)
|
||||||
|
(setcar (nthcdr 1 moment) 0)
|
||||||
|
(setcar (nthcdr 2 moment) 0))
|
||||||
|
(apply 'encode-time moment))
|
||||||
|
(ange-ftp-file-modtime (expand-file-name name dir))))
|
||||||
|
(name (ange-ftp-parse-filename))
|
||||||
|
symlink)
|
||||||
|
(if (string-match "\\(.+\\) -> \\(.+\\)" name)
|
||||||
|
(setq symlink (match-string 2 name)
|
||||||
|
name (match-string 1 name)))
|
||||||
|
(setq entry
|
||||||
|
(cons
|
||||||
|
(cons name
|
||||||
|
(list (if (eq (aref perms 0) ?d)
|
||||||
|
t
|
||||||
|
symlink)
|
||||||
|
links user group
|
||||||
|
nil mtime nil
|
||||||
|
size perms nil nil)) entry)))
|
||||||
|
(forward-line)))
|
||||||
|
entry))
|
||||||
|
|
||||||
|
(defun eshell-file-attributes (file)
|
||||||
|
"Return the attributes of FILE, playing tricks if it's over ange-ftp."
|
||||||
|
(let* ((file (expand-file-name file))
|
||||||
|
(handler (find-file-name-handler file 'file-attributes))
|
||||||
|
entry)
|
||||||
|
(if (not handler)
|
||||||
|
(file-attributes file)
|
||||||
|
(if (eq (find-file-name-handler (file-name-directory file)
|
||||||
|
'directory-files)
|
||||||
|
'ange-ftp-hook-function)
|
||||||
|
(let ((base (file-name-nondirectory file))
|
||||||
|
(dir (file-name-directory file)))
|
||||||
|
(if (boundp 'ange-cache)
|
||||||
|
(setq entry (cdr (assoc base (cdr (assoc dir ange-cache))))))
|
||||||
|
(unless entry
|
||||||
|
(setq entry (eshell-parse-ange-ls dir))
|
||||||
|
(if (boundp 'ange-cache)
|
||||||
|
(setq ange-cache
|
||||||
|
(cons (cons dir entry)
|
||||||
|
ange-cache)))
|
||||||
|
(if entry
|
||||||
|
(let ((fentry (assoc base (cdr entry))))
|
||||||
|
(if fentry
|
||||||
|
(setq entry (cdr fentry))
|
||||||
|
(setq entry nil)))))))
|
||||||
|
(or entry (funcall handler 'file-attributes file)))))
|
||||||
|
|
||||||
(defun eshell-copy-list (list)
|
(defun eshell-copy-list (list)
|
||||||
"Return a copy of a list, which may be a dotted list.
|
"Return a copy of a list, which may be a dotted list.
|
||||||
The elements of the list are not copied, just the list structure itself."
|
The elements of the list are not copied, just the list structure itself."
|
||||||
|
Loading…
Reference in New Issue
Block a user