Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
emacs
emacs
Commits
8c6b1d83
Commit
8c6b1d83
authored
Oct 13, 2000
by
John Wiegley
Browse files
Added better remote directory support to Eshell, as well as a few bug
fixes. See the ChangeLog.
parent
e2c06b17
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
324 additions
and
98 deletions
+324
-98
lisp/ChangeLog
lisp/ChangeLog
+81
-3
lisp/eshell/em-glob.el
lisp/eshell/em-glob.el
+1
-1
lisp/eshell/em-ls.el
lisp/eshell/em-ls.el
+28
-15
lisp/eshell/em-pred.el
lisp/eshell/em-pred.el
+3
-3
lisp/eshell/em-rebind.el
lisp/eshell/em-rebind.el
+1
-1
lisp/eshell/em-unix.el
lisp/eshell/em-unix.el
+94
-64
lisp/eshell/esh-arg.el
lisp/eshell/esh-arg.el
+1
-1
lisp/eshell/esh-mode.el
lisp/eshell/esh-mode.el
+3
-2
lisp/eshell/esh-util.el
lisp/eshell/esh-util.el
+112
-8
No files found.
lisp/ChangeLog
View file @
8c6b1d83
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>
* image-file.el (image-file-name-extensions)
...
...
@@ -347,6 +426,8 @@
* files.el (set-auto-mode): Ignore unknown -*- mode -*- rather than
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.
Don't use `update-menu-bindings' any more.
Get rid of assumptions about keymap representation.
...
...
@@ -1362,9 +1443,6 @@
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
read-only, since they aren't under VC now.
...
...
lisp/eshell/em-glob.el
View file @
8c6b1d83
...
...
@@ -243,7 +243,7 @@ resulting regular expression."
(INCLUDE-REGEXP EXCLUDE-REGEXP (PRED-FUNC-LIST) (MOD-FUNC-LIST))"
(
let
((
paths
(
eshell-split-path
glob
))
matches
message-shown
)
matches
message-shown
ange-cache
)
(
unwind-protect
(
if
(
and
(
cdr
paths
)
(
file-name-absolute-p
(
car
paths
)))
...
...
lisp/eshell/em-ls.el
View file @
8c6b1d83
...
...
@@ -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.
This is really just for efficiency, to avoid having to stat the file
yet again."
`
(
if
(
=
(
user-uid
)
(
nth
2
,
attrs
))
(
not
(
eq
(
aref
(
nth
8
,
attrs
)
,
index
)
?-
))
(
,
(
eval
func
)
,
file
)))
`
(
if
(
numberp
(
nth
2
,
attrs
))
(
if
(
=
(
user-uid
)
(
nth
2
,
attrs
))
(
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
"*This alist correlates test functions to color.
...
...
@@ -265,7 +271,8 @@ instead."
(
defvar
show-all
)
(
defvar
show-recursive
)
(
defvar
show-size
)
(
defvar
sort-method
))
(
defvar
sort-method
)
(
defvar
ange-cache
))
(
defun
eshell-do-ls
(
&rest
args
)
"Implementation of \"ls\" in Lisp, passing ARGS."
...
...
@@ -328,7 +335,7 @@ Sort entries alphabetically across.")
(
setq
listing-style
'by-columns
))
(
unless
args
(
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
(
unless
(
eshell-using-module
'eshell-glob
)
(
error
(
concat
"-I option requires that `eshell-glob'"
...
...
@@ -347,7 +354,7 @@ Sort entries alphabetically across.")
(
file-name-absolute-p
arg
))
(
expand-file-name
arg
)
arg
)
(
file-attributes
arg
))))
args
)
(
eshell-
file-attributes
arg
))))
args
)
t
(
expand-file-name
default-directory
)))
(
funcall
flush-func
)))
...
...
@@ -379,7 +386,7 @@ name should be displayed as, etc. Think of it as cooking a FILEINFO."
(
file-name-directory
(
expand-file-name
(
car
fileinfo
))))))
(
setq
attr
(
file-attributes
(
eshell-
file-attributes
(
let
((
target
(
if
dir
(
expand-file-name
(
cadr
fileinfo
)
dir
)
(
cadr
fileinfo
))))
...
...
@@ -425,16 +432,22 @@ whose cdr is the list of file attributes."
"%s%4d %-8s %-8s "
(
or
(
nth
8
attrs
)
"??????????"
)
(
or
(
nth
1
attrs
)
0
)
(
or
(
and
(
not
numeric-uid-gid
)
(
nth
2
attrs
)
(
eshell-substring
(
user-login-name
(
nth
2
attrs
))
8
))
(
or
(
let
((
user
(
nth
2
attrs
)))
(
and
(
not
numeric-uid-gid
)
user
(
eshell-substring
(
if
(
numberp
user
)
(
user-login-name
user
)
user
)
8
)))
(
nth
2
attrs
)
""
)
(
or
(
and
(
not
numeric-uid-gid
)
(
nth
3
attrs
)
(
eshell-substring
(
eshell-group-name
(
nth
3
attrs
))
8
))
(
or
(
let
((
group
(
nth
3
attrs
)))
(
and
(
not
numeric-uid-gid
)
group
(
eshell-substring
(
if
(
numberp
group
)
(
eshell-group-name
group
)
group
)
8
)))
(
nth
3
attrs
)
""
))
(
let*
((
str
(
eshell-ls-printable-size
(
nth
7
attrs
)))
...
...
lisp/eshell/em-pred.el
View file @
8c6b1d83
...
...
@@ -464,7 +464,7 @@ that 'ls -l' will show in the first column of its display. "
(forward-char)
(setq type ?%)))
`(lambda (file)
(let ((attrs (file-attributes (directory-file-name file))))
(let ((attrs (
eshell-
file-attributes (directory-file-name file))))
(if attrs
(memq (aref (nth 8 attrs) 0)
,(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)))
(goto-char (match-end 0))
`(lambda (file)
(let ((attrs (file-attributes file)))
(let ((attrs (
eshell-
file-attributes file)))
(if attrs
(,(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))
(goto-char (match-end 0))
`(lambda (file)
(let ((attrs (file-attributes file)))
(let ((attrs (
eshell-
file-attributes file)))
(if attrs
(,(if (eq qual ?-)
'<
...
...
lisp/eshell/em-rebind.el
View file @
8c6b1d83
...
...
@@ -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
input."
(
interactive
"p"
)
(
let
((
proc
(
get-buffer-process
(
current-buffer
)
)))
(
let
((
proc
(
eshell-interactive-process
)))
(
if
(
eobp
)
(
cond
((
/=
(
point
)
eshell-last-output-end
)
...
...
lisp/eshell/em-unix.el
View file @
8c6b1d83
...
...
@@ -122,6 +122,12 @@ Otherwise, `rmdir' is required."
:type
'boolean
: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
)
;;; Functions:
...
...
@@ -296,7 +302,7 @@ Remove the DIRECTORY(ies), if they are empty.")
"Shuffle around some filesystem entries, using FUNC to do the work."
(
if
(
null
target
)
(
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
)
(
and
preview
(
not
eshell-warn-dot-directories
))))
attr
)
...
...
@@ -315,8 +321,10 @@ Remove the DIRECTORY(ies), if they are empty.")
((
and
attr-target
(
or
(
not
(
eshell-under-windows-p
))
(
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
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"
command
(
car
files
)
target
)))
...
...
@@ -339,10 +347,10 @@ Remove the DIRECTORY(ies), if they are empty.")
(
let
(
eshell-warn-dot-directories
)
(
if
(
and
(
not
deep
)
(
eq
func
'rename-file
)
(
=
(
nth
11
(
file-attributes
(
=
(
nth
11
(
eshell-
file-attributes
(
file-name-directory
(
expand-file-name
source
))))
(
nth
11
(
file-attributes
(
nth
11
(
eshell-
file-attributes
(
file-name-directory
(
expand-file-name
target
))))))
(
apply
'eshell-funcalln
func
source
target
args
)
...
...
@@ -415,7 +423,7 @@ Remove the DIRECTORY(ies), if they are empty.")
(
or
(
not
no-dereference
)
(
not
(
file-symlink-p
(
car
args
)))))))
(
eshell-shorthand-tar-command
,
command
args
)
(
let
(
target
)
(
let
(
target
ange-cache
)
(
if
(
>
(
length
args
)
1
)
(
progn
(
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
in DIRECTORY to each TARGET. Create hard links by default, symbolic links
with '--symbolic'. When creating hard links, each TARGET must exist."
)
(
let
(
target
no-dereference
)
(
let
(
target
no-dereference
ange-cache
)
(
if
(
>
(
length
args
)
1
)
(
progn
(
setq
target
(
car
(
last
args
)))
...
...
@@ -525,10 +533,24 @@ with '--symbolic'. When creating hard links, each TARGET must exist.")
nil
))
(
defun
eshell/cat
(
&rest
args
)
"Implementation of cat in Lisp."
(
if
eshell-in-pipeline-p
(
throw
'eshell-replace-command
(
eshell-parse-command
"*cat"
(
eshell-flatten-list
args
)))
"Implementation of cat in Lisp.
If in a pipeline, or the file is not a regular file, directory or
symlink, then revert to the system's definition of cat."
(
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-eval-using-options
"cat"
args
...
...
@@ -772,61 +794,69 @@ external command."
(
defun
eshell/du
(
&rest
args
)
"Implementation of \"du\" in Lisp, passing ARGS."
(
if
(
eshell-search-path
"du"
)
(
throw
'eshell-replace-command
(
eshell-parse-command
"*du"
(
eshell-flatten-list
args
)))
(
eshell-eval-using-options
"du"
args
'
((
?a
"all"
nil
show-all
"write counts for all files, not just directories"
)
(
nil
"block-size"
t
block-size
"use SIZE-byte blocks (i.e., --block-size SIZE)"
)
(
?b
"bytes"
nil
by-bytes
"print size in bytes"
)
(
?c
"total"
nil
grand-total
"produce a grand total"
)
(
?d
"max-depth"
t
max-depth
"display data only this many levels of data"
)
(
?h
"human-readable"
1024
human-readable
"print sizes in human readable format"
)
(
?H
"is"
1000
human-readable
"likewise, but use powers of 1000 not 1024"
)
(
?k
"kilobytes"
1024
block-size
"like --block-size 1024"
)
(
?L
"dereference"
nil
dereference-links
"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...
(
setq
args
(
if
args
(
eshell-flatten-list
args
)
'
(
"."
)))
(
let
((
ext-du
(
eshell-search-path
"du"
)))
(
if
(
and
ext-du
(
not
(
catch
'have-ange-path
(
eshell-for
arg
args
(
if
(
eq
(
find-file-name-handler
(
expand-file-name
arg
)
'directory-files
)
'ange-ftp-hook-function
)
(
throw
'have-ange-path
t
))))))
(
throw
'eshell-replace-command
(
eshell-parse-command
ext-du
args
))
(
eshell-eval-using-options
"du"
args
'
((
?a
"all"
nil
show-all
"write counts for all files, not just directories"
)
(
nil
"block-size"
t
block-size
"use SIZE-byte blocks (i.e., --block-size SIZE)"
)
(
?b
"bytes"
nil
by-bytes
"print size in bytes"
)
(
?c
"total"
nil
grand-total
"produce a grand total"
)
(
?d
"max-depth"
t
max-depth
"display data only this many levels of data"
)
(
?h
"human-readable"
1024
human-readable
"print sizes in human readable format"
)
(
?H
"is"
1000
human-readable
"likewise, but use powers of 1000 not 1024"
)
(
?k
"kilobytes"
1024
block-size
"like --block-size 1024"
)
(
?L
"dereference"
nil
dereference-links
"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."
)
(
unless
by-bytes
(
setq
block-size
(
or
block-size
1024
)))
(
if
(
and
max-depth
(
stringp
max-depth
))
(
setq
max-depth
(
string-to-int
max-depth
)))
;; filesystem support means nothing under Windows
(
if
(
eshell-under-windows-p
)
(
setq
only-one-filesystem
nil
))
(
unless
args
(
setq
args
'
(
"."
)))
(
let
((
size
0.0
))
(
while
args
(
if
only-one-filesystem
(
setq
only-one-filesystem
(
nth
11
(
file-attributes
(
file-name-as-directory
(
car
args
))))))
(
setq
size
(
+
size
(
eshell-du-sum-directory
(
directory-file-name
(
car
args
))
0
)))
(
setq
args
(
cdr
args
)))
(
if
grand-total
(
eshell-print
(
concat
(
eshell-du-size-string
size
)
"total\n"
)))))))
(
unless
by-bytes
(
setq
block-size
(
or
block-size
1024
)))
(
if
(
and
max-depth
(
stringp
max-depth
))
(
setq
max-depth
(
string-to-int
max-depth
)))
;; filesystem support means nothing under Windows
(
if
(
eshell-under-windows-p
)
(
setq
only-one-filesystem
nil
))
(
let
((
size
0.0
)
ange-cache
)
(
while
args
(
if
only-one-filesystem
(
setq
only-one-filesystem
(
nth
11
(
eshell-file-attributes
(
file-name-as-directory
(
car
args
))))))
(
setq
size
(
+
size
(
eshell-du-sum-directory
(
directory-file-name
(
car
args
))
0
)))
(
setq
args
(
cdr
args
)))
(
if
grand-total
(
eshell-print
(
concat
(
eshell-du-size-string
size
)
"total\n"
))))))))
(
defvar
eshell-time-start
nil
)
...
...
lisp/eshell/esh-arg.el
View file @
8c6b1d83
...
...
@@ -328,13 +328,13 @@ special character that is not itself a backslash."
(
defun
eshell-parse-double-quote
()
"Parse a double quoted string, which allows for variable interpolation."
(
when
(
eq
(
char-after
)
?\"
)
(
forward-char
)
(
let*
((
end
(
eshell-find-delimiter
?\"
?\"
nil
nil
t
))
(
eshell-current-quoted
t
))
(
if
(
not
end
)
(
throw
'eshell-incomplete
?\"
)
(
prog1
(
save-restriction
(
forward-char
)
(
narrow-to-region
(
point
)
end
)
(
list
'eshell-escape-arg
(
eshell-parse-argument
)))
...
...
lisp/eshell/esh-mode.el
View file @
8c6b1d83
...
...
@@ -524,8 +524,9 @@ sessions, such as when using `eshell-command'.")
(
interactive
)
(
require
'etags
)
(
let
((
inhibit-read-only
t
)
(
no-default
(
eobp
)))
(
setq
tagname
(
find-tag-interactive
"Find tag: "
no-default
))
(
no-default
(
eobp
))
(
find-tag-default-function
'ignore
))
(
setq
tagname
(
car
(
find-tag-interactive
"Find tag: "
)))
(
find-tag
tagname
next-p
regexp-p
)))
(
defun
eshell-move-argument
(
limit
func
property
arg
)
...
...
lisp/eshell/esh-util.el
View file @
8c6b1d83
...
...
@@ -86,6 +86,15 @@ function `string-to-number'."
:type
'regexp
: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:
(
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
)
(
defun
directory-files-and-attributes
(
dir
&optional
full
match
nosort
)
(
documentation
'directory-files
)
(
let*
((
dir
(
expand-file-name
dir
))
(
default-directory
dir
))
(
let
((
dir
(
expand-file-name
dir
))
ange-cache
)
(
mapcar
(
function
(
lambda
(
file
)
(
cons
file
(
file-attributes
file
))))
(
cons
file
(
eshell-
file-attributes
(
expand-file-name
file
dir
)
))))
(
directory-files
dir
full
match
nosort
)))))
(
eval-when-compile
(
defvar
ange-cache
))
(
defun
eshell-directory-files-and-attributes
(
dir
&optional
full
match
nosort
)
"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
)
(
directory-files-and-attributes
dir
full
match
nosort
)
(
let*
((
files
(
funcall
dfh
'directory-files
dir
full
match
nosort
))
(
fah
(
find-file-name-handler
dir
'file-attributes
))
(
default-directory
(
expand-file-name
dir
)))
(
let
((
files
(
funcall
dfh
'directory-files
dir
full
match
nosort
))
(
fah
(
find-file-name-handler
dir
'file-attributes
)))
(
mapcar
(
function
(
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
)))))
(
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
)