diff options
| author | John Wiegley | 2000-10-13 09:02:39 +0000 |
|---|---|---|
| committer | John Wiegley | 2000-10-13 09:02:39 +0000 |
| commit | 8c6b1d83116d00e27f22e501e5ac4fea9a7ba182 (patch) | |
| tree | 7f624b71b8c6ec4c388bc34b92a8ebe8d2fb20e5 /lisp/eshell | |
| parent | e2c06b17a94a7b06cd27b643f8d5118243f06969 (diff) | |
| download | emacs-8c6b1d83116d00e27f22e501e5ac4fea9a7ba182.tar.gz emacs-8c6b1d83116d00e27f22e501e5ac4fea9a7ba182.zip | |
Added better remote directory support to Eshell, as well as a few bug
fixes. See the ChangeLog.
Diffstat (limited to 'lisp/eshell')
| -rw-r--r-- | lisp/eshell/em-glob.el | 2 | ||||
| -rw-r--r-- | lisp/eshell/em-ls.el | 43 | ||||
| -rw-r--r-- | lisp/eshell/em-pred.el | 6 | ||||
| -rw-r--r-- | lisp/eshell/em-rebind.el | 2 | ||||
| -rw-r--r-- | lisp/eshell/em-unix.el | 158 | ||||
| -rw-r--r-- | lisp/eshell/esh-arg.el | 2 | ||||
| -rw-r--r-- | lisp/eshell/esh-mode.el | 5 | ||||
| -rw-r--r-- | lisp/eshell/esh-util.el | 120 |
8 files changed, 243 insertions, 95 deletions
diff --git a/lisp/eshell/em-glob.el b/lisp/eshell/em-glob.el index 4cb3d1e40ce..ec8c1b2c37a 100644 --- a/lisp/eshell/em-glob.el +++ b/lisp/eshell/em-glob.el | |||
| @@ -243,7 +243,7 @@ resulting regular expression." | |||
| 243 | 243 | ||
| 244 | (INCLUDE-REGEXP EXCLUDE-REGEXP (PRED-FUNC-LIST) (MOD-FUNC-LIST))" | 244 | (INCLUDE-REGEXP EXCLUDE-REGEXP (PRED-FUNC-LIST) (MOD-FUNC-LIST))" |
| 245 | (let ((paths (eshell-split-path glob)) | 245 | (let ((paths (eshell-split-path glob)) |
| 246 | matches message-shown) | 246 | matches message-shown ange-cache) |
| 247 | (unwind-protect | 247 | (unwind-protect |
| 248 | (if (and (cdr paths) | 248 | (if (and (cdr paths) |
| 249 | (file-name-absolute-p (car paths))) | 249 | (file-name-absolute-p (car paths))) |
diff --git a/lisp/eshell/em-ls.el b/lisp/eshell/em-ls.el index cd16f049815..77e5d5577dc 100644 --- a/lisp/eshell/em-ls.el +++ b/lisp/eshell/em-ls.el | |||
| @@ -192,9 +192,15 @@ really need to stick around for very long." | |||
| 192 | "Test whether, for ATTRS, the user UID can do what corresponds to INDEX. | 192 | "Test whether, for ATTRS, the user UID can do what corresponds to INDEX. |
| 193 | This is really just for efficiency, to avoid having to stat the file | 193 | This is really just for efficiency, to avoid having to stat the file |
| 194 | yet again." | 194 | yet again." |
| 195 | `(if (= (user-uid) (nth 2 ,attrs)) | 195 | `(if (numberp (nth 2 ,attrs)) |
| 196 | (not (eq (aref (nth 8 ,attrs) ,index) ?-)) | 196 | (if (= (user-uid) (nth 2 ,attrs)) |
| 197 | (,(eval func) ,file))) | 197 | (not (eq (aref (nth 8 ,attrs) ,index) ?-)) |
| 198 | (,(eval func) ,file)) | ||
| 199 | (not (eq (aref (nth 8 ,attrs) | ||
| 200 | (+ ,index (if (member (nth 2 ,attrs) | ||
| 201 | (eshell-current-ange-uids)) | ||
| 202 | 0 6))) | ||
| 203 | ?-)))) | ||
| 198 | 204 | ||
| 199 | (defcustom eshell-ls-highlight-alist nil | 205 | (defcustom eshell-ls-highlight-alist nil |
| 200 | "*This alist correlates test functions to color. | 206 | "*This alist correlates test functions to color. |
| @@ -265,7 +271,8 @@ instead." | |||
| 265 | (defvar show-all) | 271 | (defvar show-all) |
| 266 | (defvar show-recursive) | 272 | (defvar show-recursive) |
| 267 | (defvar show-size) | 273 | (defvar show-size) |
| 268 | (defvar sort-method)) | 274 | (defvar sort-method) |
| 275 | (defvar ange-cache)) | ||
| 269 | 276 | ||
| 270 | (defun eshell-do-ls (&rest args) | 277 | (defun eshell-do-ls (&rest args) |
| 271 | "Implementation of \"ls\" in Lisp, passing ARGS." | 278 | "Implementation of \"ls\" in Lisp, passing ARGS." |
| @@ -328,7 +335,7 @@ Sort entries alphabetically across.") | |||
| 328 | (setq listing-style 'by-columns)) | 335 | (setq listing-style 'by-columns)) |
| 329 | (unless args | 336 | (unless args |
| 330 | (setq args (list "."))) | 337 | (setq args (list "."))) |
| 331 | (let ((eshell-ls-exclude-regexp eshell-ls-exclude-regexp)) | 338 | (let ((eshell-ls-exclude-regexp eshell-ls-exclude-regexp) ange-cache) |
| 332 | (when ignore-pattern | 339 | (when ignore-pattern |
| 333 | (unless (eshell-using-module 'eshell-glob) | 340 | (unless (eshell-using-module 'eshell-glob) |
| 334 | (error (concat "-I option requires that `eshell-glob'" | 341 | (error (concat "-I option requires that `eshell-glob'" |
| @@ -347,7 +354,7 @@ Sort entries alphabetically across.") | |||
| 347 | (file-name-absolute-p arg)) | 354 | (file-name-absolute-p arg)) |
| 348 | (expand-file-name arg) | 355 | (expand-file-name arg) |
| 349 | arg) | 356 | arg) |
| 350 | (file-attributes arg)))) args) | 357 | (eshell-file-attributes arg)))) args) |
| 351 | t (expand-file-name default-directory))) | 358 | t (expand-file-name default-directory))) |
| 352 | (funcall flush-func))) | 359 | (funcall flush-func))) |
| 353 | 360 | ||
| @@ -379,7 +386,7 @@ name should be displayed as, etc. Think of it as cooking a FILEINFO." | |||
| 379 | (file-name-directory | 386 | (file-name-directory |
| 380 | (expand-file-name (car fileinfo)))))) | 387 | (expand-file-name (car fileinfo)))))) |
| 381 | (setq attr | 388 | (setq attr |
| 382 | (file-attributes | 389 | (eshell-file-attributes |
| 383 | (let ((target (if dir | 390 | (let ((target (if dir |
| 384 | (expand-file-name (cadr fileinfo) dir) | 391 | (expand-file-name (cadr fileinfo) dir) |
| 385 | (cadr fileinfo)))) | 392 | (cadr fileinfo)))) |
| @@ -425,16 +432,22 @@ whose cdr is the list of file attributes." | |||
| 425 | "%s%4d %-8s %-8s " | 432 | "%s%4d %-8s %-8s " |
| 426 | (or (nth 8 attrs) "??????????") | 433 | (or (nth 8 attrs) "??????????") |
| 427 | (or (nth 1 attrs) 0) | 434 | (or (nth 1 attrs) 0) |
| 428 | (or (and (not numeric-uid-gid) | 435 | (or (let ((user (nth 2 attrs))) |
| 429 | (nth 2 attrs) | 436 | (and (not numeric-uid-gid) |
| 430 | (eshell-substring | 437 | user |
| 431 | (user-login-name (nth 2 attrs)) 8)) | 438 | (eshell-substring |
| 439 | (if (numberp user) | ||
| 440 | (user-login-name user) | ||
| 441 | user) 8))) | ||
| 432 | (nth 2 attrs) | 442 | (nth 2 attrs) |
| 433 | "") | 443 | "") |
| 434 | (or (and (not numeric-uid-gid) | 444 | (or (let ((group (nth 3 attrs))) |
| 435 | (nth 3 attrs) | 445 | (and (not numeric-uid-gid) |
| 436 | (eshell-substring | 446 | group |
| 437 | (eshell-group-name (nth 3 attrs)) 8)) | 447 | (eshell-substring |
| 448 | (if (numberp group) | ||
| 449 | (eshell-group-name group) | ||
| 450 | group) 8))) | ||
| 438 | (nth 3 attrs) | 451 | (nth 3 attrs) |
| 439 | "")) | 452 | "")) |
| 440 | (let* ((str (eshell-ls-printable-size (nth 7 attrs))) | 453 | (let* ((str (eshell-ls-printable-size (nth 7 attrs))) |
diff --git a/lisp/eshell/em-pred.el b/lisp/eshell/em-pred.el index c3e3de5adbd..9708e2d793a 100644 --- a/lisp/eshell/em-pred.el +++ b/lisp/eshell/em-pred.el | |||
| @@ -464,7 +464,7 @@ that 'ls -l' will show in the first column of its display. " | |||
| 464 | (forward-char) | 464 | (forward-char) |
| 465 | (setq type ?%))) | 465 | (setq type ?%))) |
| 466 | `(lambda (file) | 466 | `(lambda (file) |
| 467 | (let ((attrs (file-attributes (directory-file-name file)))) | 467 | (let ((attrs (eshell-file-attributes (directory-file-name file)))) |
| 468 | (if attrs | 468 | (if attrs |
| 469 | (memq (aref (nth 8 attrs) 0) | 469 | (memq (aref (nth 8 attrs) 0) |
| 470 | ,(if (eq type ?%) | 470 | ,(if (eq type ?%) |
| @@ -489,7 +489,7 @@ that 'ls -l' will show in the first column of its display. " | |||
| 489 | (setq amount (string-to-number (match-string 0))) | 489 | (setq amount (string-to-number (match-string 0))) |
| 490 | (goto-char (match-end 0)) | 490 | (goto-char (match-end 0)) |
| 491 | `(lambda (file) | 491 | `(lambda (file) |
| 492 | (let ((attrs (file-attributes file))) | 492 | (let ((attrs (eshell-file-attributes file))) |
| 493 | (if attrs | 493 | (if attrs |
| 494 | (,(if (eq qual ?-) | 494 | (,(if (eq qual ?-) |
| 495 | '< | 495 | '< |
| @@ -518,7 +518,7 @@ that 'ls -l' will show in the first column of its display. " | |||
| 518 | (setq amount (* (string-to-number (match-string 0)) quantum)) | 518 | (setq amount (* (string-to-number (match-string 0)) quantum)) |
| 519 | (goto-char (match-end 0)) | 519 | (goto-char (match-end 0)) |
| 520 | `(lambda (file) | 520 | `(lambda (file) |
| 521 | (let ((attrs (file-attributes file))) | 521 | (let ((attrs (eshell-file-attributes file))) |
| 522 | (if attrs | 522 | (if attrs |
| 523 | (,(if (eq qual ?-) | 523 | (,(if (eq qual ?-) |
| 524 | '< | 524 | '< |
diff --git a/lisp/eshell/em-rebind.el b/lisp/eshell/em-rebind.el index 0463a78ffb4..4caae2da425 100644 --- a/lisp/eshell/em-rebind.el +++ b/lisp/eshell/em-rebind.el | |||
| @@ -232,7 +232,7 @@ lock it at that." | |||
| 232 | Sends an EOF only if point is at the end of the buffer and there is no | 232 | Sends an EOF only if point is at the end of the buffer and there is no |
| 233 | input." | 233 | input." |
| 234 | (interactive "p") | 234 | (interactive "p") |
| 235 | (let ((proc (get-buffer-process (current-buffer)))) | 235 | (let ((proc (eshell-interactive-process))) |
| 236 | (if (eobp) | 236 | (if (eobp) |
| 237 | (cond | 237 | (cond |
| 238 | ((/= (point) eshell-last-output-end) | 238 | ((/= (point) eshell-last-output-end) |
diff --git a/lisp/eshell/em-unix.el b/lisp/eshell/em-unix.el index 17e110f65ed..07f14c6e30a 100644 --- a/lisp/eshell/em-unix.el +++ b/lisp/eshell/em-unix.el | |||
| @@ -122,6 +122,12 @@ Otherwise, `rmdir' is required." | |||
| 122 | :type 'boolean | 122 | :type 'boolean |
| 123 | :group 'eshell-unix) | 123 | :group 'eshell-unix) |
| 124 | 124 | ||
| 125 | (defcustom eshell-du-prefer-over-ange nil | ||
| 126 | "*Use Eshell's du in ange-ftp remote directories. | ||
| 127 | Otherwise, Emacs will attempt to use rsh to invoke du the machine." | ||
| 128 | :type 'boolean | ||
| 129 | :group 'eshell-unix) | ||
| 130 | |||
| 125 | (require 'esh-opt) | 131 | (require 'esh-opt) |
| 126 | 132 | ||
| 127 | ;;; Functions: | 133 | ;;; Functions: |
| @@ -296,7 +302,7 @@ Remove the DIRECTORY(ies), if they are empty.") | |||
| 296 | "Shuffle around some filesystem entries, using FUNC to do the work." | 302 | "Shuffle around some filesystem entries, using FUNC to do the work." |
| 297 | (if (null target) | 303 | (if (null target) |
| 298 | (error "%s: missing destination file" command)) | 304 | (error "%s: missing destination file" command)) |
| 299 | (let ((attr-target (file-attributes target)) | 305 | (let ((attr-target (eshell-file-attributes target)) |
| 300 | (is-dir (or (file-directory-p target) | 306 | (is-dir (or (file-directory-p target) |
| 301 | (and preview (not eshell-warn-dot-directories)))) | 307 | (and preview (not eshell-warn-dot-directories)))) |
| 302 | attr) | 308 | attr) |
| @@ -315,8 +321,10 @@ Remove the DIRECTORY(ies), if they are empty.") | |||
| 315 | ((and attr-target | 321 | ((and attr-target |
| 316 | (or (not (eshell-under-windows-p)) | 322 | (or (not (eshell-under-windows-p)) |
| 317 | (eq system-type 'ms-dos)) | 323 | (eq system-type 'ms-dos)) |
| 318 | (setq attr (file-attributes (car files))) | 324 | (setq attr (eshell-file-attributes (car files))) |
| 325 | (nth 10 attr-target) (nth 10 attr) | ||
| 319 | (= (nth 10 attr-target) (nth 10 attr)) | 326 | (= (nth 10 attr-target) (nth 10 attr)) |
| 327 | (nth 11 attr-target) (nth 11 attr) | ||
| 320 | (= (nth 11 attr-target) (nth 11 attr))) | 328 | (= (nth 11 attr-target) (nth 11 attr))) |
| 321 | (eshell-error (format "%s: `%s' and `%s' are the same file\n" | 329 | (eshell-error (format "%s: `%s' and `%s' are the same file\n" |
| 322 | command (car files) target))) | 330 | command (car files) target))) |
| @@ -339,10 +347,10 @@ Remove the DIRECTORY(ies), if they are empty.") | |||
| 339 | (let (eshell-warn-dot-directories) | 347 | (let (eshell-warn-dot-directories) |
| 340 | (if (and (not deep) | 348 | (if (and (not deep) |
| 341 | (eq func 'rename-file) | 349 | (eq func 'rename-file) |
| 342 | (= (nth 11 (file-attributes | 350 | (= (nth 11 (eshell-file-attributes |
| 343 | (file-name-directory | 351 | (file-name-directory |
| 344 | (expand-file-name source)))) | 352 | (expand-file-name source)))) |
| 345 | (nth 11 (file-attributes | 353 | (nth 11 (eshell-file-attributes |
| 346 | (file-name-directory | 354 | (file-name-directory |
| 347 | (expand-file-name target)))))) | 355 | (expand-file-name target)))))) |
| 348 | (apply 'eshell-funcalln func source target args) | 356 | (apply 'eshell-funcalln func source target args) |
| @@ -415,7 +423,7 @@ Remove the DIRECTORY(ies), if they are empty.") | |||
| 415 | (or (not no-dereference) | 423 | (or (not no-dereference) |
| 416 | (not (file-symlink-p (car args))))))) | 424 | (not (file-symlink-p (car args))))))) |
| 417 | (eshell-shorthand-tar-command ,command args) | 425 | (eshell-shorthand-tar-command ,command args) |
| 418 | (let (target) | 426 | (let (target ange-cache) |
| 419 | (if (> (length args) 1) | 427 | (if (> (length args) 1) |
| 420 | (progn | 428 | (progn |
| 421 | (setq target (car (last args))) | 429 | (setq target (car (last args))) |
| @@ -508,7 +516,7 @@ Create a link to the specified TARGET with optional LINK_NAME. If there is | |||
| 508 | more than one TARGET, the last argument must be a directory; create links | 516 | more than one TARGET, the last argument must be a directory; create links |
| 509 | in DIRECTORY to each TARGET. Create hard links by default, symbolic links | 517 | in DIRECTORY to each TARGET. Create hard links by default, symbolic links |
| 510 | with '--symbolic'. When creating hard links, each TARGET must exist.") | 518 | with '--symbolic'. When creating hard links, each TARGET must exist.") |
| 511 | (let (target no-dereference) | 519 | (let (target no-dereference ange-cache) |
| 512 | (if (> (length args) 1) | 520 | (if (> (length args) 1) |
| 513 | (progn | 521 | (progn |
| 514 | (setq target (car (last args))) | 522 | (setq target (car (last args))) |
| @@ -525,10 +533,24 @@ with '--symbolic'. When creating hard links, each TARGET must exist.") | |||
| 525 | nil)) | 533 | nil)) |
| 526 | 534 | ||
| 527 | (defun eshell/cat (&rest args) | 535 | (defun eshell/cat (&rest args) |
| 528 | "Implementation of cat in Lisp." | 536 | "Implementation of cat in Lisp. |
| 529 | (if eshell-in-pipeline-p | 537 | If in a pipeline, or the file is not a regular file, directory or |
| 530 | (throw 'eshell-replace-command | 538 | symlink, then revert to the system's definition of cat." |
| 531 | (eshell-parse-command "*cat" (eshell-flatten-list args))) | 539 | (setq args (eshell-flatten-list args)) |
| 540 | (if (or eshell-in-pipeline-p | ||
| 541 | (catch 'special | ||
| 542 | (eshell-for arg args | ||
| 543 | (unless (let ((attrs (eshell-file-attributes arg))) | ||
| 544 | (and attrs (memq (aref (nth 8 attrs) 0) | ||
| 545 | '(?d ?l ?-)))) | ||
| 546 | (throw 'special t))))) | ||
| 547 | (let ((ext-cat (eshell-search-path "cat"))) | ||
| 548 | (if ext-cat | ||
| 549 | (throw 'eshell-replace-command | ||
| 550 | (eshell-parse-command ext-cat args)) | ||
| 551 | (if eshell-in-pipeline-p | ||
| 552 | (error "Eshell's `cat' does not work in pipelines") | ||
| 553 | (error "Eshell's `cat' cannot display one of the files given")))) | ||
| 532 | (eshell-init-print-buffer) | 554 | (eshell-init-print-buffer) |
| 533 | (eshell-eval-using-options | 555 | (eshell-eval-using-options |
| 534 | "cat" args | 556 | "cat" args |
| @@ -772,61 +794,69 @@ external command." | |||
| 772 | 794 | ||
| 773 | (defun eshell/du (&rest args) | 795 | (defun eshell/du (&rest args) |
| 774 | "Implementation of \"du\" in Lisp, passing ARGS." | 796 | "Implementation of \"du\" in Lisp, passing ARGS." |
| 775 | (if (eshell-search-path "du") | 797 | (setq args (if args |
| 776 | (throw 'eshell-replace-command | 798 | (eshell-flatten-list args) |
| 777 | (eshell-parse-command "*du" (eshell-flatten-list args))) | 799 | '("."))) |
| 778 | (eshell-eval-using-options | 800 | (let ((ext-du (eshell-search-path "du"))) |
| 779 | "du" args | 801 | (if (and ext-du |
| 780 | '((?a "all" nil show-all | 802 | (not (catch 'have-ange-path |
| 781 | "write counts for all files, not just directories") | 803 | (eshell-for arg args |
| 782 | (nil "block-size" t block-size | 804 | (if (eq (find-file-name-handler (expand-file-name arg) |
| 783 | "use SIZE-byte blocks (i.e., --block-size SIZE)") | 805 | 'directory-files) |
| 784 | (?b "bytes" nil by-bytes | 806 | 'ange-ftp-hook-function) |
| 785 | "print size in bytes") | 807 | (throw 'have-ange-path t)))))) |
| 786 | (?c "total" nil grand-total | 808 | (throw 'eshell-replace-command |
| 787 | "produce a grand total") | 809 | (eshell-parse-command ext-du args)) |
| 788 | (?d "max-depth" t max-depth | 810 | (eshell-eval-using-options |
| 789 | "display data only this many levels of data") | 811 | "du" args |
| 790 | (?h "human-readable" 1024 human-readable | 812 | '((?a "all" nil show-all |
| 791 | "print sizes in human readable format") | 813 | "write counts for all files, not just directories") |
| 792 | (?H "is" 1000 human-readable | 814 | (nil "block-size" t block-size |
| 793 | "likewise, but use powers of 1000 not 1024") | 815 | "use SIZE-byte blocks (i.e., --block-size SIZE)") |
| 794 | (?k "kilobytes" 1024 block-size | 816 | (?b "bytes" nil by-bytes |
| 795 | "like --block-size 1024") | 817 | "print size in bytes") |
| 796 | (?L "dereference" nil dereference-links | 818 | (?c "total" nil grand-total |
| 797 | "dereference all symbolic links") | 819 | "produce a grand total") |
| 798 | (?m "megabytes" 1048576 block-size | 820 | (?d "max-depth" t max-depth |
| 799 | "like --block-size 1048576") | 821 | "display data only this many levels of data") |
| 800 | (?s "summarize" 0 max-depth | 822 | (?h "human-readable" 1024 human-readable |
| 801 | "display only a total for each argument") | 823 | "print sizes in human readable format") |
| 802 | (?x "one-file-system" nil only-one-filesystem | 824 | (?H "is" 1000 human-readable |
| 803 | "skip directories on different filesystems") | 825 | "likewise, but use powers of 1000 not 1024") |
| 804 | (nil "help" nil nil | 826 | (?k "kilobytes" 1024 block-size |
| 805 | "show this usage screen") | 827 | "like --block-size 1024") |
| 806 | :external "du" | 828 | (?L "dereference" nil dereference-links |
| 807 | :usage "[OPTION]... FILE... | 829 | "dereference all symbolic links") |
| 830 | (?m "megabytes" 1048576 block-size | ||
| 831 | "like --block-size 1048576") | ||
| 832 | (?s "summarize" 0 max-depth | ||
| 833 | "display only a total for each argument") | ||
| 834 | (?x "one-file-system" nil only-one-filesystem | ||
| 835 | "skip directories on different filesystems") | ||
| 836 | (nil "help" nil nil | ||
| 837 | "show this usage screen") | ||
| 838 | :external "du" | ||
| 839 | :usage "[OPTION]... FILE... | ||
| 808 | Summarize disk usage of each FILE, recursively for directories.") | 840 | Summarize disk usage of each FILE, recursively for directories.") |
| 809 | (unless by-bytes | 841 | (unless by-bytes |
| 810 | (setq block-size (or block-size 1024))) | 842 | (setq block-size (or block-size 1024))) |
| 811 | (if (and max-depth (stringp max-depth)) | 843 | (if (and max-depth (stringp max-depth)) |
| 812 | (setq max-depth (string-to-int max-depth))) | 844 | (setq max-depth (string-to-int max-depth))) |
| 813 | ;; filesystem support means nothing under Windows | 845 | ;; filesystem support means nothing under Windows |
| 814 | (if (eshell-under-windows-p) | 846 | (if (eshell-under-windows-p) |
| 815 | (setq only-one-filesystem nil)) | 847 | (setq only-one-filesystem nil)) |
| 816 | (unless args | 848 | (let ((size 0.0) ange-cache) |
| 817 | (setq args '("."))) | 849 | (while args |
| 818 | (let ((size 0.0)) | 850 | (if only-one-filesystem |
| 819 | (while args | 851 | (setq only-one-filesystem |
| 820 | (if only-one-filesystem | 852 | (nth 11 (eshell-file-attributes |
| 821 | (setq only-one-filesystem | 853 | (file-name-as-directory (car args)))))) |
| 822 | (nth 11 (file-attributes | 854 | (setq size (+ size (eshell-du-sum-directory |
| 823 | (file-name-as-directory (car args)))))) | 855 | (directory-file-name (car args)) 0))) |
| 824 | (setq size (+ size (eshell-du-sum-directory | 856 | (setq args (cdr args))) |
| 825 | (directory-file-name (car args)) 0))) | 857 | (if grand-total |
| 826 | (setq args (cdr args))) | 858 | (eshell-print (concat (eshell-du-size-string size) |
| 827 | (if grand-total | 859 | "total\n")))))))) |
| 828 | (eshell-print (concat (eshell-du-size-string size) | ||
| 829 | "total\n"))))))) | ||
| 830 | 860 | ||
| 831 | (defvar eshell-time-start nil) | 861 | (defvar eshell-time-start nil) |
| 832 | 862 | ||
diff --git a/lisp/eshell/esh-arg.el b/lisp/eshell/esh-arg.el index 8364ca9a7f6..985401fbe37 100644 --- a/lisp/eshell/esh-arg.el +++ b/lisp/eshell/esh-arg.el | |||
| @@ -328,13 +328,13 @@ special character that is not itself a backslash." | |||
| 328 | (defun eshell-parse-double-quote () | 328 | (defun eshell-parse-double-quote () |
| 329 | "Parse a double quoted string, which allows for variable interpolation." | 329 | "Parse a double quoted string, which allows for variable interpolation." |
| 330 | (when (eq (char-after) ?\") | 330 | (when (eq (char-after) ?\") |
| 331 | (forward-char) | ||
| 332 | (let* ((end (eshell-find-delimiter ?\" ?\" nil nil t)) | 331 | (let* ((end (eshell-find-delimiter ?\" ?\" nil nil t)) |
| 333 | (eshell-current-quoted t)) | 332 | (eshell-current-quoted t)) |
| 334 | (if (not end) | 333 | (if (not end) |
| 335 | (throw 'eshell-incomplete ?\") | 334 | (throw 'eshell-incomplete ?\") |
| 336 | (prog1 | 335 | (prog1 |
| 337 | (save-restriction | 336 | (save-restriction |
| 337 | (forward-char) | ||
| 338 | (narrow-to-region (point) end) | 338 | (narrow-to-region (point) end) |
| 339 | (list 'eshell-escape-arg | 339 | (list 'eshell-escape-arg |
| 340 | (eshell-parse-argument))) | 340 | (eshell-parse-argument))) |
diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el index 1d79c8af701..4d32da81f05 100644 --- a/lisp/eshell/esh-mode.el +++ b/lisp/eshell/esh-mode.el | |||
| @@ -524,8 +524,9 @@ sessions, such as when using `eshell-command'.") | |||
| 524 | (interactive) | 524 | (interactive) |
| 525 | (require 'etags) | 525 | (require 'etags) |
| 526 | (let ((inhibit-read-only t) | 526 | (let ((inhibit-read-only t) |
| 527 | (no-default (eobp))) | 527 | (no-default (eobp)) |
| 528 | (setq tagname (find-tag-interactive "Find tag: " no-default)) | 528 | (find-tag-default-function 'ignore)) |
| 529 | (setq tagname (car (find-tag-interactive "Find tag: "))) | ||
| 529 | (find-tag tagname next-p regexp-p))) | 530 | (find-tag tagname next-p regexp-p))) |
| 530 | 531 | ||
| 531 | (defun eshell-move-argument (limit func property arg) | 532 | (defun eshell-move-argument (limit func property arg) |
diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el index 3d650928c62..84416893107 100644 --- a/lisp/eshell/esh-util.el +++ b/lisp/eshell/esh-util.el | |||
| @@ -86,6 +86,15 @@ function `string-to-number'." | |||
| 86 | :type 'regexp | 86 | :type 'regexp |
| 87 | :group 'eshell-util) | 87 | :group 'eshell-util) |
| 88 | 88 | ||
| 89 | (defcustom eshell-ange-ls-uids nil | ||
| 90 | "*List of user/host/id strings, used to determine remote ownership." | ||
| 91 | :type '(list (cons :tag "Host/User Pair" | ||
| 92 | (string :tag "Hostname") | ||
| 93 | (repeat (cons :tag "User/UID List" | ||
| 94 | (string :tag "Username") | ||
| 95 | (repeat :tag "UIDs" string))))) | ||
| 96 | :group 'eshell-util) | ||
| 97 | |||
| 89 | ;;; Internal Variables: | 98 | ;;; Internal Variables: |
| 90 | 99 | ||
| 91 | (defvar eshell-group-names nil | 100 | (defvar eshell-group-names nil |
| @@ -558,28 +567,123 @@ Unless optional argument INPLACE is non-nil, return a new string." | |||
| 558 | (unless (fboundp 'directory-files-and-attributes) | 567 | (unless (fboundp 'directory-files-and-attributes) |
| 559 | (defun directory-files-and-attributes (dir &optional full match nosort) | 568 | (defun directory-files-and-attributes (dir &optional full match nosort) |
| 560 | (documentation 'directory-files) | 569 | (documentation 'directory-files) |
| 561 | (let* ((dir (expand-file-name dir)) | 570 | (let ((dir (expand-file-name dir)) ange-cache) |
| 562 | (default-directory dir)) | ||
| 563 | (mapcar | 571 | (mapcar |
| 564 | (function | 572 | (function |
| 565 | (lambda (file) | 573 | (lambda (file) |
| 566 | (cons file (file-attributes file)))) | 574 | (cons file (eshell-file-attributes (expand-file-name file dir))))) |
| 567 | (directory-files dir full match nosort))))) | 575 | (directory-files dir full match nosort))))) |
| 568 | 576 | ||
| 577 | (eval-when-compile | ||
| 578 | (defvar ange-cache)) | ||
| 579 | |||
| 569 | (defun eshell-directory-files-and-attributes (dir &optional full match nosort) | 580 | (defun eshell-directory-files-and-attributes (dir &optional full match nosort) |
| 570 | "Make sure to use the handler for `directory-file-and-attributes'." | 581 | "Make sure to use the handler for `directory-file-and-attributes'." |
| 571 | (let ((dfh (find-file-name-handler dir 'directory-files))) | 582 | (let* ((dir (expand-file-name dir)) |
| 583 | (dfh (find-file-name-handler dir 'directory-files))) | ||
| 572 | (if (not dfh) | 584 | (if (not dfh) |
| 573 | (directory-files-and-attributes dir full match nosort) | 585 | (directory-files-and-attributes dir full match nosort) |
| 574 | (let* ((files (funcall dfh 'directory-files dir full match nosort)) | 586 | (let ((files (funcall dfh 'directory-files dir full match nosort)) |
| 575 | (fah (find-file-name-handler dir 'file-attributes)) | 587 | (fah (find-file-name-handler dir 'file-attributes))) |
| 576 | (default-directory (expand-file-name dir))) | ||
| 577 | (mapcar | 588 | (mapcar |
| 578 | (function | 589 | (function |
| 579 | (lambda (file) | 590 | (lambda (file) |
| 580 | (cons file (funcall fah 'file-attributes file)))) | 591 | (cons file (if fah |
| 592 | (eshell-file-attributes | ||
| 593 | (expand-file-name file dir)) | ||
| 594 | (file-attributes (expand-file-name file dir)))))) | ||
| 581 | files))))) | 595 | files))))) |
| 582 | 596 | ||
| 597 | (defun eshell-current-ange-uids () | ||
| 598 | (if (string-match "/\\([^@]+\\)@\\([^:]+\\):" default-directory) | ||
| 599 | (let* ((host (match-string 2 default-directory)) | ||
| 600 | (user (match-string 1 default-directory)) | ||
| 601 | (host-users (assoc host eshell-ange-ls-uids))) | ||
| 602 | (when host-users | ||
| 603 | (setq host-users (cdr host-users)) | ||
| 604 | (cdr (assoc user host-users)))))) | ||
| 605 | |||
| 606 | ;; Add an autoload for parse-time-string | ||
| 607 | (if (and (not (fboundp 'parse-time-string)) | ||
| 608 | (locate-library "parse-time")) | ||
| 609 | (autoload 'parse-time-string "parse-time")) | ||
| 610 | |||
| 611 | (defun eshell-parse-ange-ls (dir) | ||
| 612 | (let (entry) | ||
| 613 | (with-temp-buffer | ||
| 614 | (insert (ange-ftp-ls dir "-la" nil)) | ||
| 615 | (goto-char (point-min)) | ||
| 616 | (if (looking-at "^total [0-9]+$") | ||
| 617 | (forward-line 1)) | ||
| 618 | ;; Some systems put in a blank line here. | ||
| 619 | (if (eolp) (forward-line 1)) | ||
| 620 | (while (looking-at | ||
| 621 | `,(concat "\\([dlscb-][rwxst-]+\\)" | ||
| 622 | "\\s-*" "\\([0-9]+\\)" "\\s-+" | ||
| 623 | "\\(\\S-+\\)" "\\s-+" | ||
| 624 | "\\(\\S-+\\)" "\\s-+" | ||
| 625 | "\\([0-9]+\\)" "\\s-+" "\\(.*\\)")) | ||
| 626 | (let* ((perms (match-string 1)) | ||
| 627 | (links (string-to-number (match-string 2))) | ||
| 628 | (user (match-string 3)) | ||
| 629 | (group (match-string 4)) | ||
| 630 | (size (string-to-number (match-string 5))) | ||
| 631 | (mtime | ||
| 632 | (if (fboundp 'parse-time-string) | ||
| 633 | (let ((moment (parse-time-string | ||
| 634 | (match-string 6)))) | ||
| 635 | (if (nth 0 moment) | ||
| 636 | (setcar (nthcdr 5 moment) | ||
| 637 | (nth 5 (decode-time (current-time)))) | ||
| 638 | (setcar (nthcdr 0 moment) 0) | ||
| 639 | (setcar (nthcdr 1 moment) 0) | ||
| 640 | (setcar (nthcdr 2 moment) 0)) | ||
| 641 | (apply 'encode-time moment)) | ||
| 642 | (ange-ftp-file-modtime (expand-file-name name dir)))) | ||
| 643 | (name (ange-ftp-parse-filename)) | ||
| 644 | symlink) | ||
| 645 | (if (string-match "\\(.+\\) -> \\(.+\\)" name) | ||
| 646 | (setq symlink (match-string 2 name) | ||
| 647 | name (match-string 1 name))) | ||
| 648 | (setq entry | ||
| 649 | (cons | ||
| 650 | (cons name | ||
| 651 | (list (if (eq (aref perms 0) ?d) | ||
| 652 | t | ||
| 653 | symlink) | ||
| 654 | links user group | ||
| 655 | nil mtime nil | ||
| 656 | size perms nil nil)) entry))) | ||
| 657 | (forward-line))) | ||
| 658 | entry)) | ||
| 659 | |||
| 660 | (defun eshell-file-attributes (file) | ||
| 661 | "Return the attributes of FILE, playing tricks if it's over ange-ftp." | ||
| 662 | (let* ((file (expand-file-name file)) | ||
| 663 | (handler (find-file-name-handler file 'file-attributes)) | ||
| 664 | entry) | ||
| 665 | (if (not handler) | ||
| 666 | (file-attributes file) | ||
| 667 | (if (eq (find-file-name-handler (file-name-directory file) | ||
| 668 | 'directory-files) | ||
| 669 | 'ange-ftp-hook-function) | ||
| 670 | (let ((base (file-name-nondirectory file)) | ||
| 671 | (dir (file-name-directory file))) | ||
| 672 | (if (boundp 'ange-cache) | ||
| 673 | (setq entry (cdr (assoc base (cdr (assoc dir ange-cache)))))) | ||
| 674 | (unless entry | ||
| 675 | (setq entry (eshell-parse-ange-ls dir)) | ||
| 676 | (if (boundp 'ange-cache) | ||
| 677 | (setq ange-cache | ||
| 678 | (cons (cons dir entry) | ||
| 679 | ange-cache))) | ||
| 680 | (if entry | ||
| 681 | (let ((fentry (assoc base (cdr entry)))) | ||
| 682 | (if fentry | ||
| 683 | (setq entry (cdr fentry)) | ||
| 684 | (setq entry nil))))))) | ||
| 685 | (or entry (funcall handler 'file-attributes file))))) | ||
| 686 | |||
| 583 | (defun eshell-copy-list (list) | 687 | (defun eshell-copy-list (list) |
| 584 | "Return a copy of a list, which may be a dotted list. | 688 | "Return a copy of a list, which may be a dotted list. |
| 585 | The elements of the list are not copied, just the list structure itself." | 689 | The elements of the list are not copied, just the list structure itself." |