diff options
| author | John Wiegley | 2000-10-29 05:18:48 +0000 |
|---|---|---|
| committer | John Wiegley | 2000-10-29 05:18:48 +0000 |
| commit | dace60cfea488a9cc8a775109c56b66907aa6abb (patch) | |
| tree | 364b9c0114540a5f51a42e1e28a37b98714edaee | |
| parent | 657f9cb8b7f7c3a9687f3998319ce63346ef13a4 (diff) | |
| download | emacs-dace60cfea488a9cc8a775109c56b66907aa6abb.tar.gz emacs-dace60cfea488a9cc8a775109c56b66907aa6abb.zip | |
See ChangeLog
| -rw-r--r-- | etc/ChangeLog | 4 | ||||
| -rw-r--r-- | etc/NEWS | 5 | ||||
| -rw-r--r-- | lisp/ChangeLog | 123 | ||||
| -rw-r--r-- | lisp/calendar/timeclock.el | 434 | ||||
| -rw-r--r-- | lisp/eshell/em-alias.el | 7 | ||||
| -rw-r--r-- | lisp/eshell/em-dirs.el | 6 | ||||
| -rw-r--r-- | lisp/eshell/em-glob.el | 5 | ||||
| -rw-r--r-- | lisp/eshell/em-ls.el | 74 | ||||
| -rw-r--r-- | lisp/eshell/em-script.el | 3 | ||||
| -rw-r--r-- | lisp/eshell/em-smart.el | 35 | ||||
| -rw-r--r-- | lisp/eshell/em-unix.el | 129 | ||||
| -rw-r--r-- | lisp/eshell/esh-cmd.el | 120 | ||||
| -rw-r--r-- | lisp/eshell/esh-groups.el | 1 | ||||
| -rw-r--r-- | lisp/eshell/esh-maint.el | 68 | ||||
| -rw-r--r-- | lisp/eshell/esh-mode.el | 11 | ||||
| -rw-r--r-- | lisp/eshell/esh-module.el | 6 | ||||
| -rw-r--r-- | lisp/eshell/esh-test.el | 8 | ||||
| -rw-r--r-- | lisp/eshell/esh-util.el | 14 | ||||
| -rw-r--r-- | lisp/textmodes/flyspell.el | 56 | ||||
| -rw-r--r-- | man/ChangeLog | 4 | ||||
| -rw-r--r-- | man/eshell.texi | 825 |
21 files changed, 1302 insertions, 636 deletions
diff --git a/etc/ChangeLog b/etc/ChangeLog index 95f7d6442aa..c5717ed9e68 100644 --- a/etc/ChangeLog +++ b/etc/ChangeLog | |||
| @@ -1,3 +1,7 @@ | |||
| 1 | 2000-10-18 John Wiegley <johnw@gnu.org> | ||
| 2 | |||
| 3 | * NEWS: Added text for pcomplete.el. | ||
| 4 | |||
| 1 | 2000-10-16 Gerd Moellmann <gerd@gnu.org> | 5 | 2000-10-16 Gerd Moellmann <gerd@gnu.org> |
| 2 | 6 | ||
| 3 | * 3B-MAXMEM, AIX.DUMP, SUN-SUPPORT: Removed. | 7 | * 3B-MAXMEM, AIX.DUMP, SUN-SUPPORT: Removed. |
| @@ -1786,7 +1786,10 @@ Fill mode. | |||
| 1786 | *** gnus-mule.el is now just a compatibility layer over the built-in | 1786 | *** gnus-mule.el is now just a compatibility layer over the built-in |
| 1787 | Gnus facilities. | 1787 | Gnus facilities. |
| 1788 | 1788 | ||
| 1789 | *** pcomplete.el ?? | 1789 | *** pcomplete.el is a library that provides programmable completion |
| 1790 | facilities for Emacs, similar to what zsh and tcsh offer. The main | ||
| 1791 | difference is that completion functions are written in Lisp, meaning | ||
| 1792 | they can be profiled, debugged, etc. | ||
| 1790 | 1793 | ||
| 1791 | ** Withdrawn packages | 1794 | ** Withdrawn packages |
| 1792 | 1795 | ||
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 903612bed0b..706751d315a 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,124 @@ | |||
| 1 | 2000-10-28 John Wiegley <johnw@gnu.org> | ||
| 2 | |||
| 3 | * textmodes/flyspell.el (flyspell-maybe-correct-transposition): | ||
| 4 | Changed this function to operate on a temporary buffer instead of | ||
| 5 | the main buffer. This not only keeps flyspell from marking a | ||
| 6 | buffer as changed that wasn't, but it solves the jumpy cursor | ||
| 7 | problem when attempts are made to edit incorrect words. | ||
| 8 | (flyspell-maybe-correct-doubling): Same change as for | ||
| 9 | `flyspell-maybe-correct-transposition'. | ||
| 10 | |||
| 11 | * calendar/timeclock.el (timeclock-log): Doc fix. | ||
| 12 | (timeclock-last-event): Doc fix. | ||
| 13 | (timeclock-log): Kill the timelog buffer after appending a new | ||
| 14 | event. | ||
| 15 | (timeclock-find-discrep): Use a temp buffer to read in the | ||
| 16 | timelog, instead of visiting the file. | ||
| 17 | (timeclock-log-data): A new function, along with a host of helper | ||
| 18 | functions, for the purpose of making timelog data accessible to | ||
| 19 | programmers. | ||
| 20 | |||
| 21 | * eshell/esh-mode.el (window-height test): Make certain that | ||
| 22 | `eshell-stringify-t' is non-nil. | ||
| 23 | (eshell-password-prompt-regexp): Changed to a much simpler | ||
| 24 | password regexp. | ||
| 25 | (eshell-send-input): If `eshell-invoke-directly' returns t, | ||
| 26 | directly invoke the parsed command using `eval'. This improves | ||
| 27 | turn-around time on simple commands by a factor of three or | ||
| 28 | greater, such as cd, ls, pwd, etc. -- which get used very often. | ||
| 29 | It also conserves thousands of cons cells per call (since | ||
| 30 | `eshell-do-eval' consumes memory like a Cookie Monster set loose | ||
| 31 | in the Pacific Cookie Company). | ||
| 32 | |||
| 33 | * eshell/esh-test.el (eshell-test): Whitespace fix. | ||
| 34 | |||
| 35 | * eshell/em-ls.el (eshell-ls-insert-directory): Make | ||
| 36 | `eshell-ls-initial-args' nil when inserting directory contents. | ||
| 37 | |||
| 38 | * eshell/em-script.el (eshell-script-initialize): Add names to | ||
| 39 | `eshell-complex-commands, since `source' and `.' are complex. | ||
| 40 | |||
| 41 | * eshell/esh-cmd.el (eshell-rewrite-for-command, | ||
| 42 | eshell-rewrite-while-command): Use `eshell-protect' instead of | ||
| 43 | `eshell-copy-handles'. | ||
| 44 | (eshell-rewrite-if-command): Use `eshell-protect' to wrap the call | ||
| 45 | bodies. | ||
| 46 | (eshell-separate-commands): Whitespace fix. | ||
| 47 | (eshell-complex-commands): Added a new list of names, for | ||
| 48 | determining whether a given command is as simple as it looks. | ||
| 49 | (eshell-invoke-directly): New function. Returns t if a command | ||
| 50 | should be invoked directly (using `eval'), rather than indirectly | ||
| 51 | using `eshell-do-eval'. | ||
| 52 | (eshell-do-eval): Whitespace fix. | ||
| 53 | |||
| 54 | * eshell/em-unix.el (eshell-default-target-is-dot): New variable, | ||
| 55 | which provides an emulation of the DOS shell behavior of assuming | ||
| 56 | that cp/mv/ln should copy/move/link to the current directory. | ||
| 57 | (eshell-remove-entries): Added a doc string. | ||
| 58 | (eshell-shuffle-files): Removed the check for `target' being null. | ||
| 59 | (eshell-mvcp-template, eshell-mvcpln-template): Renamed | ||
| 60 | `eshell-mvcp-template' to `eshell-mvcpln-template', and extended | ||
| 61 | it to do a smarter check of whether a destination was provided. | ||
| 62 | (eshell/mv, eshell/cp): Enable `:preserve-args'. | ||
| 63 | (eshell/ln): Enable `:preserve-args', and use | ||
| 64 | `eshell-mvcpln-template' to implement the body of the function. | ||
| 65 | (eshell/cat, eshell/make, eshell-poor-mans-grep, eshell-grep, | ||
| 66 | eshell/du, eshell/diff, eshell/locate): Stringify the argument | ||
| 67 | list after flattening it. This makes it possible to cat files | ||
| 68 | with numerical names. | ||
| 69 | (eshell-unix-initialize): Added several names to | ||
| 70 | `eshell-complex-commands. | ||
| 71 | (eshell-unix-command-complex-p): Return t if a given command name | ||
| 72 | may result in external processes being invoked. | ||
| 73 | |||
| 74 | * eshell/em-glob.el (eshell-glob-show-progress): Make this | ||
| 75 | variable nil by default, since it slows down glob processing by a | ||
| 76 | factor of two or more, and increases memory consumption. | ||
| 77 | |||
| 78 | * eshell/em-smart.el: Added a note about how memory consumptive | ||
| 79 | smart display mode can be (at least this is true in Emacs 21). | ||
| 80 | (eshell-smart-initialize): Whitespace fix. | ||
| 81 | (eshell-refresh-windows): Use `if' instead of `when'. | ||
| 82 | (eshell-smart-scroll-window): Calling `save-current-buffer' was | ||
| 83 | not necessary. | ||
| 84 | (eshell-currently-handling-window): Added a missing global | ||
| 85 | variable. | ||
| 86 | |||
| 87 | * eshell/em-ls.el (eshell-do-ls): Code simplification. | ||
| 88 | (eshell-ls-sort-entries, eshell-ls-entries, eshell-ls-dir): | ||
| 89 | Whitespace fix. | ||
| 90 | (eshell-ls-exclude-hidden): Added this variable in addition to | ||
| 91 | `eshell-ls-exclude-regexp'. This one prevents files beginning | ||
| 92 | with . from even being read, which can improve memory consumption | ||
| 93 | quite a bit. | ||
| 94 | (eshell-ls-dir): If `eshell-ls-exclude-hidden' is non-nil, do not | ||
| 95 | read file entries beginning with a dot. In home directories with | ||
| 96 | lots of hidden files, fully two-thirds of the time spent in ls is | ||
| 97 | used to read directory entries that are immediately thrown away. | ||
| 98 | (eshell-ls-initial-args): Added back this configuration variable, | ||
| 99 | for specifying default initial arguments to every call to ls. | ||
| 100 | Much faster than using an alias to do the same thing. | ||
| 101 | (eshell-do-ls): Use `eshell-ls-initial-args', if set. | ||
| 102 | (eshell-ls-dir): Whitespace change. | ||
| 103 | |||
| 104 | * eshell/em-dirs.el (eshell/pwd): Small code simplification. | ||
| 105 | |||
| 106 | * eshell/esh-util.el: Don't require `ange-ftp' if it's not | ||
| 107 | available. | ||
| 108 | (eshell-stringify-t): Added a customization variable, to indicate | ||
| 109 | whether `t' should be rendered as a string at all. If not, one | ||
| 110 | can still determine if the result of an expression is true using | ||
| 111 | "file-exists-p FILE && echo true". | ||
| 112 | (eshell-stringify): If `eshell-stringify-t' is nil, don't | ||
| 113 | stringify t! | ||
| 114 | |||
| 115 | * eshell/esh-module.el: Whitespace fix. | ||
| 116 | |||
| 117 | * eshell/em-alias.el (eshell-alias-initialize): Added | ||
| 118 | `eshell-command-aliased-p' to `eshell-complex-commands'. | ||
| 119 | (eshell-command-aliased-p): New function that returns t if a | ||
| 120 | command name names an aliased. | ||
| 121 | |||
| 1 | 2000-10-29 Michael Kifer <kifer@cs.sunysb.edu> | 122 | 2000-10-29 Michael Kifer <kifer@cs.sunysb.edu> |
| 2 | 123 | ||
| 3 | * viper-cmd.el (viper-preserve-cursor-color): new test that avoids | 124 | * viper-cmd.el (viper-preserve-cursor-color): new test that avoids |
| @@ -865,7 +986,7 @@ | |||
| 865 | * align.el, pcomplete.el, calendar/timeclock.el, | 986 | * align.el, pcomplete.el, calendar/timeclock.el, |
| 866 | eshell/esh-module.el, eshell/eshell.el: Removed URL reference. | 987 | eshell/esh-module.el, eshell/eshell.el: Removed URL reference. |
| 867 | 988 | ||
| 868 | * calendar/timeclock.el (timeclock-find-discrep): A fix to same | 989 | * calendar/timeclock.el (timeclock-find-discrep): A fix to some |
| 869 | faulty math, where holiday hours were being computing as seconds. | 990 | faulty math, where holiday hours were being computing as seconds. |
| 870 | 991 | ||
| 871 | 2000-10-13 John Wiegley <johnw@gnu.org> | 992 | 2000-10-13 John Wiegley <johnw@gnu.org> |
diff --git a/lisp/calendar/timeclock.el b/lisp/calendar/timeclock.el index 265406d2e5f..d96250dde1d 100644 --- a/lisp/calendar/timeclock.el +++ b/lisp/calendar/timeclock.el | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | ;; Author: John Wiegley <johnw@gnu.org> | 5 | ;; Author: John Wiegley <johnw@gnu.org> |
| 6 | ;; Created: 25 Mar 1999 | 6 | ;; Created: 25 Mar 1999 |
| 7 | ;; Version: 2.2 | 7 | ;; Version: 2.3 |
| 8 | ;; Keywords: calendar data | 8 | ;; Keywords: calendar data |
| 9 | 9 | ||
| 10 | ;; This file is part of GNU Emacs. | 10 | ;; This file is part of GNU Emacs. |
| @@ -222,8 +222,7 @@ in the modeline. See the variable `timeclock-modeline-display'." | |||
| 222 | 222 | ||
| 223 | (defvar timeclock-last-event nil | 223 | (defvar timeclock-last-event nil |
| 224 | "A list containing the last event that was recorded. | 224 | "A list containing the last event that was recorded. |
| 225 | The format of this list is (CODE TIME PROJECT). PROJECT will be | 225 | The format of this list is (CODE TIME PROJECT).") |
| 226 | non-nil only if CODE is \"o\" or \"O\".") | ||
| 227 | 226 | ||
| 228 | (defvar timeclock-last-event-workday nil | 227 | (defvar timeclock-last-event-workday nil |
| 229 | "The number of seconds in the workday of `timeclock-last-event'.") | 228 | "The number of seconds in the workday of `timeclock-last-event'.") |
| @@ -455,7 +454,7 @@ as with time remaining, where negative time really means overtime)." | |||
| 455 | (truncate (/ (abs seconds) 60 60)) | 454 | (truncate (/ (abs seconds) 60 60)) |
| 456 | (% (truncate (/ (abs seconds) 60)) 60)))) | 455 | (% (truncate (/ (abs seconds) 60)) 60)))) |
| 457 | 456 | ||
| 458 | (defun timeclock-workday-remaining (&optional today-only) | 457 | (defsubst timeclock-workday-remaining (&optional today-only) |
| 459 | "Return a the number of seconds until the workday is complete. | 458 | "Return a the number of seconds until the workday is complete. |
| 460 | The amount returned is relative to the value of `timeclock-workday'. | 459 | The amount returned is relative to the value of `timeclock-workday'. |
| 461 | If TODAY-ONLY is non-nil, the value returned will be relative only to | 460 | If TODAY-ONLY is non-nil, the value returned will be relative only to |
| @@ -463,7 +462,7 @@ the time worked today, and not to past time. This argument only makes | |||
| 463 | a difference if `timeclock-relative' is non-nil." | 462 | a difference if `timeclock-relative' is non-nil." |
| 464 | (- (timeclock-find-discrep today-only))) | 463 | (- (timeclock-find-discrep today-only))) |
| 465 | 464 | ||
| 466 | (defun timeclock-currently-in-p () | 465 | (defsubst timeclock-currently-in-p () |
| 467 | "Return non-nil if the user is currently clocked in." | 466 | "Return non-nil if the user is currently clocked in." |
| 468 | (equal (car timeclock-last-event) "i")) | 467 | (equal (car timeclock-last-event) "i")) |
| 469 | 468 | ||
| @@ -483,7 +482,7 @@ See `timeclock-relative' for more information about the meaning of | |||
| 483 | (message string) | 482 | (message string) |
| 484 | string))) | 483 | string))) |
| 485 | 484 | ||
| 486 | (defun timeclock-workday-elapsed (&optional relative) | 485 | (defsubst timeclock-workday-elapsed (&optional relative) |
| 487 | "Return a the number of seconds worked so far today. | 486 | "Return a the number of seconds worked so far today. |
| 488 | If RELATIVE is non-nil, the amount returned will be relative to past | 487 | If RELATIVE is non-nil, the amount returned will be relative to past |
| 489 | time worked. The default is to return only the time that has elapsed | 488 | time worked. The default is to return only the time that has elapsed |
| @@ -505,7 +504,7 @@ non-nil, the amount returned will be relative to past time worked." | |||
| 505 | (message string) | 504 | (message string) |
| 506 | string))) | 505 | string))) |
| 507 | 506 | ||
| 508 | (defun timeclock-when-to-leave (&optional today-only) | 507 | (defsubst timeclock-when-to-leave (&optional today-only) |
| 509 | "Return a time value representing at when the workday ends today. | 508 | "Return a time value representing at when the workday ends today. |
| 510 | If TODAY-ONLY is non-nil, the value returned will be relative only to | 509 | If TODAY-ONLY is non-nil, the value returned will be relative only to |
| 511 | the time worked today, and not to past time. This argument only makes | 510 | the time worked today, and not to past time. This argument only makes |
| @@ -578,9 +577,8 @@ non-nil." | |||
| 578 | (defun timeclock-log (code &optional project) | 577 | (defun timeclock-log (code &optional project) |
| 579 | "Log the event CODE to the timeclock log, at the time of call. | 578 | "Log the event CODE to the timeclock log, at the time of call. |
| 580 | If PROJECT is a string, it represents the project which the event is | 579 | If PROJECT is a string, it represents the project which the event is |
| 581 | being logged for. Normally only \"out\" events specify a project." | 580 | being logged for. Normally only \"in\" events specify a project." |
| 582 | (save-excursion | 581 | (with-current-buffer (find-file-noselect timeclock-file) |
| 583 | (set-buffer (find-file-noselect timeclock-file)) | ||
| 584 | (goto-char (point-max)) | 582 | (goto-char (point-max)) |
| 585 | (if (not (bolp)) | 583 | (if (not (bolp)) |
| 586 | (insert "\n")) | 584 | (insert "\n")) |
| @@ -603,42 +601,40 @@ being logged for. Normally only \"out\" events specify a project." | |||
| 603 | timeclock-last-period))) | 601 | timeclock-last-period))) |
| 604 | (setq timeclock-last-event (list code now project))) | 602 | (setq timeclock-last-event (list code now project))) |
| 605 | (save-buffer) | 603 | (save-buffer) |
| 606 | (run-hooks 'timeclock-event-hook))) | 604 | (run-hooks 'timeclock-event-hook) |
| 605 | (kill-buffer (current-buffer)))) | ||
| 607 | 606 | ||
| 608 | (defun timeclock-read-moment () | 607 | (defvar timeclock-moment-regexp |
| 608 | (concat "\\([bhioO]\\)\\s-+" | ||
| 609 | "\\([0-9]+\\)/\\([0-9]+\\)/\\([0-9]+\\)\\s-+" | ||
| 610 | "\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)[ \t]*" "\\([^\n]*\\)")) | ||
| 611 | |||
| 612 | (defsubst timeclock-read-moment () | ||
| 609 | "Read the moment under point from the timelog." | 613 | "Read the moment under point from the timelog." |
| 610 | (save-excursion | 614 | (if (looking-at timeclock-moment-regexp) |
| 611 | (beginning-of-line) | 615 | (let ((code (match-string 1)) |
| 612 | (let ((eol (save-excursion (end-of-line) (point)))) | 616 | (year (string-to-number (match-string 2))) |
| 613 | (if (re-search-forward | 617 | (mon (string-to-number (match-string 3))) |
| 614 | (concat "^\\(.\\)\\s-+" | 618 | (mday (string-to-number (match-string 4))) |
| 615 | "\\([0-9]+\\)/\\([0-9]+\\)/\\([0-9]+\\)\\s-+" | 619 | (hour (string-to-number (match-string 5))) |
| 616 | "\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)\\s-*" | 620 | (min (string-to-number (match-string 6))) |
| 617 | "\\(.*\\)") eol t) | 621 | (sec (string-to-number (match-string 7))) |
| 618 | (let ((code (match-string 1)) | 622 | (project (match-string 8))) |
| 619 | (year (string-to-number (match-string 2))) | 623 | (list code (encode-time sec min hour mday mon year) project)))) |
| 620 | (mon (string-to-number (match-string 3))) | 624 | |
| 621 | (mday (string-to-number (match-string 4))) | 625 | (defsubst timeclock-time-to-seconds (time) |
| 622 | (hour (string-to-number (match-string 5))) | ||
| 623 | (min (string-to-number (match-string 6))) | ||
| 624 | (sec (string-to-number (match-string 7))) | ||
| 625 | (project (match-string 8))) | ||
| 626 | (list code (encode-time sec min hour mday mon year) | ||
| 627 | project)))))) | ||
| 628 | |||
| 629 | (defun timeclock-time-to-seconds (time) | ||
| 630 | "Convert TIME to a floating point number." | 626 | "Convert TIME to a floating point number." |
| 631 | (+ (* (car time) 65536.0) | 627 | (+ (* (car time) 65536.0) |
| 632 | (cadr time) | 628 | (cadr time) |
| 633 | (/ (or (car (cdr (cdr time))) 0) 1000000.0))) | 629 | (/ (or (car (cdr (cdr time))) 0) 1000000.0))) |
| 634 | 630 | ||
| 635 | (defun timeclock-seconds-to-time (seconds) | 631 | (defsubst timeclock-seconds-to-time (seconds) |
| 636 | "Convert SECONDS (a floating point number) to an Emacs time structure." | 632 | "Convert SECONDS (a floating point number) to an Emacs time structure." |
| 637 | (list (floor seconds 65536) | 633 | (list (floor seconds 65536) |
| 638 | (floor (mod seconds 65536)) | 634 | (floor (mod seconds 65536)) |
| 639 | (floor (* (- seconds (ffloor seconds)) 1000000)))) | 635 | (floor (* (- seconds (ffloor seconds)) 1000000)))) |
| 640 | 636 | ||
| 641 | (defun timeclock-time-to-date (time) | 637 | (defsubst timeclock-time-to-date (time) |
| 642 | "Convert the TIME value to a textual date string." | 638 | "Convert the TIME value to a textual date string." |
| 643 | (format-time-string "%Y/%m/%d" time)) | 639 | (format-time-string "%Y/%m/%d" time)) |
| 644 | 640 | ||
| @@ -655,49 +651,376 @@ This is only provided for coherency when used by | |||
| 655 | (cadr timeclock-last-event))) | 651 | (cadr timeclock-last-event))) |
| 656 | timeclock-last-period)) | 652 | timeclock-last-period)) |
| 657 | 653 | ||
| 654 | (defsubst timeclock-entry-length (entry) | ||
| 655 | (- (timeclock-time-to-seconds (cadr entry)) | ||
| 656 | (timeclock-time-to-seconds (car entry)))) | ||
| 657 | |||
| 658 | (defsubst timeclock-entry-begin (entry) | ||
| 659 | (car entry)) | ||
| 660 | |||
| 661 | (defsubst timeclock-entry-end (entry) | ||
| 662 | (cadr entry)) | ||
| 663 | |||
| 664 | (defsubst timeclock-entry-project (entry) | ||
| 665 | (nth 2 entry)) | ||
| 666 | |||
| 667 | (defsubst timeclock-entry-comment (entry) | ||
| 668 | (nth 3 entry)) | ||
| 669 | |||
| 670 | |||
| 671 | (defsubst timeclock-entry-list-length (entry-list) | ||
| 672 | (let ((length 0)) | ||
| 673 | (while entry-list | ||
| 674 | (setq length (+ length (timeclock-entry-length (car entry-list)))) | ||
| 675 | (setq entry-list (cdr entry-list))) | ||
| 676 | length)) | ||
| 677 | |||
| 678 | (defsubst timeclock-entry-list-begin (entry-list) | ||
| 679 | (timeclock-entry-begin (car entry-list))) | ||
| 680 | |||
| 681 | (defsubst timeclock-entry-list-end (entry-list) | ||
| 682 | (timeclock-entry-end (car (last entry-list)))) | ||
| 683 | |||
| 684 | (defsubst timeclock-entry-list-span (entry-list) | ||
| 685 | (- (timeclock-time-to-seconds (timeclock-entry-list-end entry-list)) | ||
| 686 | (timeclock-time-to-seconds (timeclock-entry-list-begin entry-list)))) | ||
| 687 | |||
| 688 | (defsubst timeclock-entry-list-break (entry-list) | ||
| 689 | (- (timeclock-entry-list-span entry-list) | ||
| 690 | (timeclock-entry-list-length entry-list))) | ||
| 691 | |||
| 692 | (defsubst timeclock-entry-list-projects (entry-list) | ||
| 693 | (let (projects) | ||
| 694 | (while entry-list | ||
| 695 | (let ((project (timeclock-entry-project (car entry-list)))) | ||
| 696 | (if projects | ||
| 697 | (add-to-list 'projects project) | ||
| 698 | (setq projects (list project)))) | ||
| 699 | (setq entry-list (cdr entry-list))) | ||
| 700 | projects)) | ||
| 701 | |||
| 702 | |||
| 703 | (defsubst timeclock-day-required (day) | ||
| 704 | (car day)) | ||
| 705 | |||
| 706 | (defsubst timeclock-day-length (day) | ||
| 707 | (timeclock-entry-list-length (cdr day))) | ||
| 708 | |||
| 709 | (defsubst timeclock-day-debt (day) | ||
| 710 | (- (timeclock-day-required day) | ||
| 711 | (timeclock-day-length day))) | ||
| 712 | |||
| 713 | (defsubst timeclock-day-begin (day) | ||
| 714 | (timeclock-entry-list-begin (cdr day))) | ||
| 715 | |||
| 716 | (defsubst timeclock-day-end (day) | ||
| 717 | (timeclock-entry-list-end (cdr day))) | ||
| 718 | |||
| 719 | (defsubst timeclock-day-span (day) | ||
| 720 | (timeclock-entry-list-span (cdr day))) | ||
| 721 | |||
| 722 | (defsubst timeclock-day-break (day) | ||
| 723 | (timeclock-entry-list-break (cdr day))) | ||
| 724 | |||
| 725 | (defsubst timeclock-day-projects (day) | ||
| 726 | (timeclock-entry-list-projects (cdr day))) | ||
| 727 | |||
| 728 | (defmacro timeclock-day-list-template (func) | ||
| 729 | `(let ((length 0)) | ||
| 730 | (while day-list | ||
| 731 | (setq length (+ length (,(eval func) (car day-list)))) | ||
| 732 | (setq day-list (cdr day-list))) | ||
| 733 | length)) | ||
| 734 | |||
| 735 | (defun timeclock-day-list-required (day-list) | ||
| 736 | (timeclock-day-list-template 'timeclock-day-required)) | ||
| 737 | |||
| 738 | (defun timeclock-day-list-length (day-list) | ||
| 739 | (timeclock-day-list-template 'timeclock-day-length)) | ||
| 740 | |||
| 741 | (defun timeclock-day-list-debt (day-list) | ||
| 742 | (timeclock-day-list-template 'timeclock-day-debt)) | ||
| 743 | |||
| 744 | (defsubst timeclock-day-list-begin (day-list) | ||
| 745 | (timeclock-day-begin (car day-list))) | ||
| 746 | |||
| 747 | (defsubst timeclock-day-list-end (day-list) | ||
| 748 | (timeclock-day-end (car (last day-list)))) | ||
| 749 | |||
| 750 | (defun timeclock-day-list-span (day-list) | ||
| 751 | (timeclock-day-list-template 'timeclock-day-span)) | ||
| 752 | |||
| 753 | (defun timeclock-day-list-break (day-list) | ||
| 754 | (timeclock-day-list-template 'timeclock-day-break)) | ||
| 755 | |||
| 756 | (defun timeclock-day-list-projects (day-list) | ||
| 757 | (let (projects) | ||
| 758 | (while day-list | ||
| 759 | (let ((projs (timeclock-day-projects (car day-list)))) | ||
| 760 | (while projs | ||
| 761 | (if projects | ||
| 762 | (add-to-list 'projects (car projs)) | ||
| 763 | (setq projects (list (car projs)))) | ||
| 764 | (setq projs (cdr projs)))) | ||
| 765 | (setq day-list (cdr day-list))) | ||
| 766 | projects)) | ||
| 767 | |||
| 768 | |||
| 769 | (defsubst timeclock-current-debt (&optional log-data) | ||
| 770 | (nth 0 (or log-data (timeclock-log-data)))) | ||
| 771 | |||
| 772 | (defsubst timeclock-day-alist (&optional log-data) | ||
| 773 | (nth 1 (or log-data (timeclock-log-data)))) | ||
| 774 | |||
| 775 | (defun timeclock-day-list (&optional log-data) | ||
| 776 | (let ((alist (timeclock-day-alist log-data)) | ||
| 777 | day-list) | ||
| 778 | (while alist | ||
| 779 | (setq day-list (cons (cdar alist) day-list) | ||
| 780 | alist (cdr alist))) | ||
| 781 | day-list)) | ||
| 782 | |||
| 783 | (defsubst timeclock-project-alist (&optional log-data) | ||
| 784 | (nth 2 (or log-data (timeclock-log-data)))) | ||
| 785 | |||
| 786 | |||
| 787 | (defun timeclock-log-data (&optional recent-only filename) | ||
| 788 | "Return the contents of the timelog file, in a useful format. | ||
| 789 | A timelog contains data in the form of a single entry per line. | ||
| 790 | Each entry has the form: | ||
| 791 | |||
| 792 | CODE YYYY/MM/DD HH:MM:SS [COMMENT] | ||
| 793 | |||
| 794 | CODE is one of: b, h, i, o or O. COMMENT is optional when the code is | ||
| 795 | i, o or O. The meanings of the codes are: | ||
| 796 | |||
| 797 | b Set the current time balance, or \"time debt\". Useful when | ||
| 798 | archiving old log data, when a debt must be carried forward. | ||
| 799 | The COMMENT here is the number of seconds of debt. | ||
| 800 | |||
| 801 | h Set the required working time for the given day. This must | ||
| 802 | be the first entry for that day. The COMMENT in this case is | ||
| 803 | the number of hours that must be worked. Floating point | ||
| 804 | amounts are allowed. | ||
| 805 | |||
| 806 | i Clock in. The COMMENT in this case should be the name of the | ||
| 807 | project worked on. | ||
| 808 | |||
| 809 | o Clock out. COMMENT is unnecessary, but can be used to provide | ||
| 810 | a description of how the period went, for example. | ||
| 811 | |||
| 812 | O Final clock out. Whatever project was being worked on, it is | ||
| 813 | now finished. Useful for creating summary reports. | ||
| 814 | |||
| 815 | When this function is called, it will return a data structure with the | ||
| 816 | following format: | ||
| 817 | |||
| 818 | (DEBT ENTRIES-BY-DAY ENTRIES-BY-PROJECT) | ||
| 819 | |||
| 820 | DEBT is a floating point number representing the number of seconds | ||
| 821 | \"owed\" before any work was done. For a new file (one without a 'b' | ||
| 822 | entry), this is always zero. | ||
| 823 | |||
| 824 | The two entries lists have similar formats. They are both alists, | ||
| 825 | where the CAR is the index, and the CDR is a list of time entries. | ||
| 826 | For ENTRIES-BY-DAY, the CAR is a textual date string, of the form | ||
| 827 | YYYY/MM/DD. For ENTRIES-BY-PROJECT, it is the name of the project | ||
| 828 | worked on, or t for the default project. | ||
| 829 | |||
| 830 | The CDR for ENTRIES-BY-DAY is slightly different than for | ||
| 831 | ENTRIES-BY-PROJECT. It has the following form: | ||
| 832 | |||
| 833 | (DAY-LENGTH TIME-ENTRIES...) | ||
| 834 | |||
| 835 | For ENTRIES-BY-PROJECT, there is no DAY-LENGTH member. It is simply a | ||
| 836 | list of TIME-ENTRIES. Note that if DAY-LENGTH is nil, it means | ||
| 837 | whatever is the default should be used. | ||
| 838 | |||
| 839 | A TIME-ENTRY is a recorded time interval. It has the following format | ||
| 840 | \(although generally one does not have to manipulate these entries | ||
| 841 | directly; see below): | ||
| 842 | |||
| 843 | (BEGIN-TIME END-TIME PROJECT [COMMENT] [FINAL-P]) | ||
| 844 | |||
| 845 | Anyway, suffice it to say there are a lot of structures. Typically | ||
| 846 | the user is expected to manipulate to the day(s) or project(s) that he | ||
| 847 | or she wants, at which point the following helper functions may be | ||
| 848 | used: | ||
| 849 | |||
| 850 | timeclock-day-required | ||
| 851 | timeclock-day-length | ||
| 852 | timeclock-day-debt | ||
| 853 | timeclock-day-begin | ||
| 854 | timeclock-day-end | ||
| 855 | timeclock-day-span | ||
| 856 | timeclock-day-break | ||
| 857 | timeclock-day-projects | ||
| 858 | |||
| 859 | timeclock-day-list-required | ||
| 860 | timeclock-day-list-length | ||
| 861 | timeclock-day-list-debt | ||
| 862 | timeclock-day-list-begin | ||
| 863 | timeclock-day-list-end | ||
| 864 | timeclock-day-list-span | ||
| 865 | timeclock-day-list-break | ||
| 866 | timeclock-day-list-projects | ||
| 867 | |||
| 868 | timeclock-entry-length | ||
| 869 | timeclock-entry-begin | ||
| 870 | timeclock-entry-end | ||
| 871 | timeclock-entry-project | ||
| 872 | timeclock-entry-comment | ||
| 873 | |||
| 874 | timeclock-entry-list-length | ||
| 875 | timeclock-entry-list-begin | ||
| 876 | timeclock-entry-list-end | ||
| 877 | timeclock-entry-list-span | ||
| 878 | timeclock-entry-list-break | ||
| 879 | timeclock-entry-list-projects | ||
| 880 | |||
| 881 | A few comments should make the use of the above functions obvious: | ||
| 882 | |||
| 883 | `required' is the amount of time that must be spent during a day, or | ||
| 884 | sequence of days, in order to have no debt. | ||
| 885 | |||
| 886 | `length' is the actual amount of time that was spent. | ||
| 887 | |||
| 888 | `debt' is the difference between required time and length. A | ||
| 889 | negative debt signifies overtime. | ||
| 890 | |||
| 891 | `begin' is the earliest moment at which work began. | ||
| 892 | |||
| 893 | `end' is the final moment work was done. | ||
| 894 | |||
| 895 | `span' is the difference between begin and end. | ||
| 896 | |||
| 897 | `break' is the difference between span and length. | ||
| 898 | |||
| 899 | `project' is the project that was worked on, and `projects' is a | ||
| 900 | list of all the projects that were worked on during a given period. | ||
| 901 | |||
| 902 | `comment', where it applies, could mean anything. | ||
| 903 | |||
| 904 | There are a few more functions available, for locating day and entry | ||
| 905 | lists: | ||
| 906 | |||
| 907 | timeclock-day-alist LOG-DATA | ||
| 908 | timeclock-project-alist LOG-DATA | ||
| 909 | timeclock-current-debt LOG-DATA | ||
| 910 | |||
| 911 | See the documentation for the given function if more info is needed." | ||
| 912 | (let* ((log-data (list 0.0 nil nil)) | ||
| 913 | (now (current-time)) | ||
| 914 | (todays-date (timeclock-time-to-date now)) | ||
| 915 | last-date-limited last-date-seconds last-date | ||
| 916 | (line 0) last beg day entry) | ||
| 917 | (with-temp-buffer | ||
| 918 | (insert-file-contents (or filename timeclock-file)) | ||
| 919 | (when recent-only | ||
| 920 | (goto-char (point-max)) | ||
| 921 | (unless (re-search-backward "^b\\s-+" nil t) | ||
| 922 | (goto-char (point-min)))) | ||
| 923 | (while (or (setq event (timeclock-read-moment)) | ||
| 924 | (and beg (not last) | ||
| 925 | (setq last t event (list "o" now)))) | ||
| 926 | (setq line (1+ line)) | ||
| 927 | (cond ((equal (car event) "b") | ||
| 928 | (setcar log-data (string-to-number (nth 2 event)))) | ||
| 929 | ((equal (car event) "h") | ||
| 930 | (setq last-date-limited (timeclock-time-to-date (cadr event)) | ||
| 931 | last-date-seconds (* (string-to-number (nth 2 event)) | ||
| 932 | 3600.0))) | ||
| 933 | ((equal (car event) "i") | ||
| 934 | (if beg | ||
| 935 | (error "Error in format of timelog file, line %d" line) | ||
| 936 | (setq beg t)) | ||
| 937 | (setq entry (list (cadr event) nil | ||
| 938 | (and (> (length (nth 2 event)) 0) | ||
| 939 | (nth 2 event)))) | ||
| 940 | (let ((date (timeclock-time-to-date (cadr event)))) | ||
| 941 | (if (and last-date | ||
| 942 | (not (equal date last-date))) | ||
| 943 | (setcar (cdr log-data) | ||
| 944 | (cons (cons last-date day) | ||
| 945 | (cadr log-data))) | ||
| 946 | (setq day (list (and last-date-limited | ||
| 947 | last-date-seconds)))) | ||
| 948 | (setq last-date date | ||
| 949 | last-date-limited nil))) | ||
| 950 | ((equal (downcase (car event)) "o") | ||
| 951 | (if (not beg) | ||
| 952 | (error "Error in format of timelog file, line %d" line) | ||
| 953 | (setq beg nil)) | ||
| 954 | (setcar (cdr entry) (cadr event)) | ||
| 955 | (let ((desc (and (> (length (nth 2 event)) 0) | ||
| 956 | (nth 2 event)))) | ||
| 957 | (if desc | ||
| 958 | (nconc entry (list (nth 2 event)))) | ||
| 959 | (if (equal (car event) "O") | ||
| 960 | (nconc entry (if desc | ||
| 961 | (list t) | ||
| 962 | (list nil t)))) | ||
| 963 | (nconc day (list entry)) | ||
| 964 | (setq desc (nth 2 entry)) | ||
| 965 | (let ((proj (assoc desc (nth 2 log-data)))) | ||
| 966 | (if (not proj) | ||
| 967 | (setcar (cddr log-data) | ||
| 968 | (cons (cons desc (list entry)) | ||
| 969 | (car (cddr log-data)))) | ||
| 970 | (nconc (cdr proj) (list entry))))))) | ||
| 971 | (forward-line)) | ||
| 972 | (if day | ||
| 973 | (setcar (cdr log-data) | ||
| 974 | (cons (cons last-date day) | ||
| 975 | (cadr log-data)))) | ||
| 976 | log-data))) | ||
| 977 | |||
| 658 | (defun timeclock-find-discrep (&optional today-only) | 978 | (defun timeclock-find-discrep (&optional today-only) |
| 659 | "Find overall discrepancy from `timeclock-workday' (in seconds). | 979 | "Find overall discrepancy from `timeclock-workday' (in seconds). |
| 660 | If TODAY-ONLY is non-nil, the discrepancy will be not be relative, and | 980 | If TODAY-ONLY is non-nil, the discrepancy will be not be relative, and |
| 661 | will correspond only to the amount of time elapsed today. This is | 981 | will correspond only to the amount of time elapsed today. This is |
| 662 | identical to what would be return if `timeclock-relative' were nil." | 982 | identical to what would be return if `timeclock-relative' were nil." |
| 663 | (let* ((now (current-time)) (first t) | 983 | ;; This is not implemented in terms of the functions above, because |
| 984 | ;; it's a bit wasteful to read all of that data in, just to throw | ||
| 985 | ;; away more than 90% of the information afterwards. | ||
| 986 | (let* ((now (current-time)) | ||
| 664 | (todays-date (timeclock-time-to-date now)) | 987 | (todays-date (timeclock-time-to-date now)) |
| 665 | accum event beg last-date | 988 | (first t) (accum 0) |
| 666 | last-date-limited last-date-seconds avg) | 989 | event beg last-date avg |
| 990 | last-date-limited last-date-seconds) | ||
| 667 | (unless timeclock-discrepancy | 991 | (unless timeclock-discrepancy |
| 668 | (setq timeclock-project-list nil | 992 | (setq timeclock-project-list nil |
| 669 | timeclock-last-project nil | 993 | timeclock-last-project nil |
| 670 | timeclock-reason-list nil) | 994 | timeclock-reason-list nil |
| 671 | (save-excursion | 995 | timeclock-elapsed 0) |
| 672 | (set-buffer (find-file-noselect timeclock-file)) | 996 | (with-temp-buffer |
| 673 | (goto-char (point-min)) | 997 | (insert-file-contents timeclock-file) |
| 674 | (setq accum 0) | 998 | (goto-char (point-max)) |
| 675 | (setq timeclock-elapsed 0) | 999 | (unless (re-search-backward "^b\\s-+" nil t) |
| 1000 | (goto-char (point-min))) | ||
| 676 | (while (setq event (timeclock-read-moment)) | 1001 | (while (setq event (timeclock-read-moment)) |
| 677 | (cond ((equal (car event) "h") | 1002 | (cond ((equal (car event) "b") |
| 1003 | (setq accum (string-to-number (nth 2 event)))) | ||
| 1004 | ((equal (car event) "h") | ||
| 678 | (setq last-date-limited | 1005 | (setq last-date-limited |
| 679 | (timeclock-time-to-date (cadr event)) | 1006 | (timeclock-time-to-date (cadr event)) |
| 680 | last-date-seconds | 1007 | last-date-seconds |
| 681 | (* (string-to-number (nth 2 event)) 3600))) | 1008 | (* (string-to-number (nth 2 event)) 3600.0))) |
| 682 | ((equal (car event) "i") | 1009 | ((equal (car event) "i") |
| 683 | (when (and (nth 2 event) | 1010 | (when (and (nth 2 event) |
| 684 | (> (length (nth 2 event)) 0)) | 1011 | (> (length (nth 2 event)) 0)) |
| 685 | (add-to-list 'timeclock-project-list (nth 2 event)) | 1012 | (add-to-list 'timeclock-project-list (nth 2 event)) |
| 686 | (setq timeclock-last-project (nth 2 event))) | 1013 | (setq timeclock-last-project (nth 2 event))) |
| 687 | (let ((date (timeclock-time-to-date (cadr event)))) | 1014 | (let ((date (timeclock-time-to-date (cadr event)))) |
| 688 | (if (and last-date | 1015 | (if (and timeclock-relative |
| 689 | timeclock-relative | 1016 | (if last-date |
| 690 | (not (equal date last-date))) | 1017 | (not (equal date last-date)) |
| 691 | (setq accum (- accum | 1018 | first)) |
| 692 | (if last-date-limited | ||
| 693 | last-date-seconds | ||
| 694 | timeclock-workday))) | ||
| 695 | (unless (or last-date (not first)) | ||
| 696 | (setq first nil | 1019 | (setq first nil |
| 697 | accum (- accum | 1020 | accum (- accum |
| 698 | (if last-date-limited | 1021 | (if last-date-limited |
| 699 | last-date-seconds | 1022 | last-date-seconds |
| 700 | timeclock-workday))))) | 1023 | timeclock-workday)))) |
| 701 | (setq last-date date | 1024 | (setq last-date date |
| 702 | last-date-limited nil) | 1025 | last-date-limited nil) |
| 703 | (if beg | 1026 | (if beg |
| @@ -712,8 +1035,7 @@ identical to what would be return if `timeclock-relative' were nil." | |||
| 712 | (if (not beg) | 1035 | (if (not beg) |
| 713 | (error "Error in format of timelog file!") | 1036 | (error "Error in format of timelog file!") |
| 714 | (setq timeclock-last-period | 1037 | (setq timeclock-last-period |
| 715 | (- (timeclock-time-to-seconds (cadr event)) | 1038 | (- (timeclock-time-to-seconds (cadr event)) beg) |
| 716 | beg) | ||
| 717 | accum (+ timeclock-last-period accum) | 1039 | accum (+ timeclock-last-period accum) |
| 718 | beg nil))) | 1040 | beg nil))) |
| 719 | (if (equal last-date todays-date) | 1041 | (if (equal last-date todays-date) |
diff --git a/lisp/eshell/em-alias.el b/lisp/eshell/em-alias.el index 85e4e97e692..a407bf5deb8 100644 --- a/lisp/eshell/em-alias.el +++ b/lisp/eshell/em-alias.el | |||
| @@ -151,7 +151,12 @@ command, which will automatically write them to the file named by | |||
| 151 | (add-hook 'eshell-alternate-command-hook 'eshell-fix-bad-commands t t) | 151 | (add-hook 'eshell-alternate-command-hook 'eshell-fix-bad-commands t t) |
| 152 | (eshell-read-aliases-list) | 152 | (eshell-read-aliases-list) |
| 153 | (make-local-hook 'eshell-named-command-hook) | 153 | (make-local-hook 'eshell-named-command-hook) |
| 154 | (add-hook 'eshell-named-command-hook 'eshell-maybe-replace-by-alias t t)) | 154 | (add-hook 'eshell-named-command-hook 'eshell-maybe-replace-by-alias t t) |
| 155 | (make-local-variable 'eshell-complex-commands) | ||
| 156 | (add-to-list 'eshell-complex-commands 'eshell-command-aliased-p)) | ||
| 157 | |||
| 158 | (defun eshell-command-aliased-p (name) | ||
| 159 | (member name eshell-command-aliases-list)) | ||
| 155 | 160 | ||
| 156 | (defun eshell/alias (&optional alias &rest definition) | 161 | (defun eshell/alias (&optional alias &rest definition) |
| 157 | "Define an ALIAS in the user's alias list using DEFINITION." | 162 | "Define an ALIAS in the user's alias list using DEFINITION." |
diff --git a/lisp/eshell/em-dirs.el b/lisp/eshell/em-dirs.el index 02d1eb3076b..0c147f14be6 100644 --- a/lisp/eshell/em-dirs.el +++ b/lisp/eshell/em-dirs.el | |||
| @@ -297,7 +297,7 @@ Thus, this does not include the current directory.") | |||
| 297 | (file-name-as-directory (cdr user)))) | 297 | (file-name-as-directory (cdr user)))) |
| 298 | eshell-user-names))))))) | 298 | eshell-user-names))))))) |
| 299 | 299 | ||
| 300 | (defun eshell/pwd (&rest args) ; ignored | 300 | (defun eshell/pwd (&rest args) |
| 301 | "Change output from `pwd` to be cleaner." | 301 | "Change output from `pwd` to be cleaner." |
| 302 | (let* ((path default-directory) | 302 | (let* ((path default-directory) |
| 303 | (len (length path))) | 303 | (len (length path))) |
| @@ -307,8 +307,8 @@ Thus, this does not include the current directory.") | |||
| 307 | (string-match "\\`[A-Za-z]:[\\\\/]\\'" path)))) | 307 | (string-match "\\`[A-Za-z]:[\\\\/]\\'" path)))) |
| 308 | (setq path (substring path 0 (1- (length path))))) | 308 | (setq path (substring path 0 (1- (length path))))) |
| 309 | (if eshell-pwd-convert-function | 309 | (if eshell-pwd-convert-function |
| 310 | (setq path (funcall eshell-pwd-convert-function path))) | 310 | (funcall eshell-pwd-convert-function path) |
| 311 | path)) | 311 | path))) |
| 312 | 312 | ||
| 313 | (defun eshell-expand-multiple-dots (path) | 313 | (defun eshell-expand-multiple-dots (path) |
| 314 | "Convert '...' to '../..', '....' to '../../..', etc.. | 314 | "Convert '...' to '../..', '....' to '../../..', etc.. |
diff --git a/lisp/eshell/em-glob.el b/lisp/eshell/em-glob.el index b281cee4fd7..f4f9ebbe5b6 100644 --- a/lisp/eshell/em-glob.el +++ b/lisp/eshell/em-glob.el | |||
| @@ -81,8 +81,9 @@ by zsh for filename generation." | |||
| 81 | :type 'boolean | 81 | :type 'boolean |
| 82 | :group 'eshell-glob) | 82 | :group 'eshell-glob) |
| 83 | 83 | ||
| 84 | (defcustom eshell-glob-show-progress t | 84 | (defcustom eshell-glob-show-progress nil |
| 85 | "*If non-nil, display progress messages during a recursive glob." | 85 | "*If non-nil, display progress messages during a recursive glob. |
| 86 | This option slows down recursive glob processing by quite a bit." | ||
| 86 | :type 'boolean | 87 | :type 'boolean |
| 87 | :group 'eshell-glob) | 88 | :group 'eshell-glob) |
| 88 | 89 | ||
diff --git a/lisp/eshell/em-ls.el b/lisp/eshell/em-ls.el index 2afef625f55..534ea932c3c 100644 --- a/lisp/eshell/em-ls.el +++ b/lisp/eshell/em-ls.el | |||
| @@ -57,6 +57,12 @@ properties to colorize its output based on the setting of | |||
| 57 | :type 'hook | 57 | :type 'hook |
| 58 | :group 'eshell-ls) | 58 | :group 'eshell-ls) |
| 59 | 59 | ||
| 60 | (defcustom eshell-ls-initial-args nil | ||
| 61 | "*If non-nil, this list of args is included before any call to `ls'. | ||
| 62 | This is useful for enabling human-readable format (-h), for example." | ||
| 63 | :type '(repeat :tag "Arguments" string) | ||
| 64 | :group 'eshell-ls) | ||
| 65 | |||
| 60 | (defcustom eshell-ls-use-in-dired nil | 66 | (defcustom eshell-ls-use-in-dired nil |
| 61 | "*If non-nil, use `eshell-ls' to read directories in dired." | 67 | "*If non-nil, use `eshell-ls' to read directories in dired." |
| 62 | :set (lambda (symbol value) | 68 | :set (lambda (symbol value) |
| @@ -77,11 +83,18 @@ properties to colorize its output based on the setting of | |||
| 77 | :type 'integer | 83 | :type 'integer |
| 78 | :group 'eshell-ls) | 84 | :group 'eshell-ls) |
| 79 | 85 | ||
| 80 | (defcustom eshell-ls-exclude-regexp "\\`\\." | 86 | (defcustom eshell-ls-exclude-regexp nil |
| 81 | "*Unless -a is specified, files matching this regexp will not be shown." | 87 | "*Unless -a is specified, files matching this regexp will not be shown." |
| 82 | :type 'regexp | 88 | :type 'regexp |
| 83 | :group 'eshell-ls) | 89 | :group 'eshell-ls) |
| 84 | 90 | ||
| 91 | (defcustom eshell-ls-exclude-hidden t | ||
| 92 | "*Unless -a is specified, files beginning with . will not be shown. | ||
| 93 | Using this boolean, instead of `eshell-ls-exclude-regexp', is both | ||
| 94 | faster and conserves more memory." | ||
| 95 | :type 'boolean | ||
| 96 | :group 'eshell-ls) | ||
| 97 | |||
| 85 | (defcustom eshell-ls-use-colors t | 98 | (defcustom eshell-ls-use-colors t |
| 86 | "*If non-nil, use colors in file listings." | 99 | "*If non-nil, use colors in file listings." |
| 87 | :type 'boolean | 100 | :type 'boolean |
| @@ -196,13 +209,13 @@ This is really just for efficiency, to avoid having to stat the file | |||
| 196 | yet again." | 209 | yet again." |
| 197 | `(if (numberp (nth 2 ,attrs)) | 210 | `(if (numberp (nth 2 ,attrs)) |
| 198 | (if (= (user-uid) (nth 2 ,attrs)) | 211 | (if (= (user-uid) (nth 2 ,attrs)) |
| 199 | (not (eq (aref (nth 8 ,attrs) ,index) ?-)) | 212 | (not (eq (aref (nth 8 ,attrs) ,index) ?-)) |
| 200 | (,(eval func) ,file)) | 213 | (,(eval func) ,file)) |
| 201 | (not (eq (aref (nth 8 ,attrs) | 214 | (not (eq (aref (nth 8 ,attrs) |
| 202 | (+ ,index (if (member (nth 2 ,attrs) | 215 | (+ ,index (if (member (nth 2 ,attrs) |
| 203 | (eshell-current-ange-uids)) | 216 | (eshell-current-ange-uids)) |
| 204 | 0 6))) | 217 | 0 6))) |
| 205 | ?-)))) | 218 | ?-)))) |
| 206 | 219 | ||
| 207 | (defcustom eshell-ls-highlight-alist nil | 220 | (defcustom eshell-ls-highlight-alist nil |
| 208 | "*This alist correlates test functions to color. | 221 | "*This alist correlates test functions to color. |
| @@ -248,7 +261,8 @@ instead." | |||
| 248 | (symbol-value 'font-lock-buffers))))) | 261 | (symbol-value 'font-lock-buffers))))) |
| 249 | (let ((insert-func 'insert) | 262 | (let ((insert-func 'insert) |
| 250 | (error-func 'insert) | 263 | (error-func 'insert) |
| 251 | (flush-func 'ignore)) | 264 | (flush-func 'ignore) |
| 265 | eshell-ls-initial-args) | ||
| 252 | (eshell-do-ls (append switches (list file)))))))) | 266 | (eshell-do-ls (append switches (list file)))))))) |
| 253 | 267 | ||
| 254 | (defsubst eshell/ls (&rest args) | 268 | (defsubst eshell/ls (&rest args) |
| @@ -281,7 +295,9 @@ instead." | |||
| 281 | (funcall flush-func -1) | 295 | (funcall flush-func -1) |
| 282 | ;; process the command arguments, and begin listing files | 296 | ;; process the command arguments, and begin listing files |
| 283 | (eshell-eval-using-options | 297 | (eshell-eval-using-options |
| 284 | "ls" args | 298 | "ls" (if eshell-ls-initial-args |
| 299 | (list eshell-ls-initial-args args) | ||
| 300 | args) | ||
| 285 | `((?a "all" nil show-all | 301 | `((?a "all" nil show-all |
| 286 | "show all files in directory") | 302 | "show all files in directory") |
| 287 | (?c nil by-ctime sort-method | 303 | (?c nil by-ctime sort-method |
| @@ -343,11 +359,11 @@ Sort entries alphabetically across.") | |||
| 343 | (error (concat "-I option requires that `eshell-glob'" | 359 | (error (concat "-I option requires that `eshell-glob'" |
| 344 | " be a member of `eshell-modules-list'"))) | 360 | " be a member of `eshell-modules-list'"))) |
| 345 | (set-text-properties 0 (length ignore-pattern) nil ignore-pattern) | 361 | (set-text-properties 0 (length ignore-pattern) nil ignore-pattern) |
| 346 | (if eshell-ls-exclude-regexp | 362 | (setq eshell-ls-exclude-regexp |
| 347 | (setq eshell-ls-exclude-regexp | 363 | (if eshell-ls-exclude-regexp |
| 348 | (concat "\\(" eshell-ls-exclude-regexp "\\|" | 364 | (concat "\\(" eshell-ls-exclude-regexp "\\|" |
| 349 | (eshell-glob-regexp ignore-pattern) "\\)")) | 365 | (eshell-glob-regexp ignore-pattern) "\\)") |
| 350 | (setq eshell-ls-exclude-regexp (eshell-glob-regexp ignore-pattern)))) | 366 | (eshell-glob-regexp ignore-pattern)))) |
| 351 | ;; list the files! | 367 | ;; list the files! |
| 352 | (eshell-ls-entries | 368 | (eshell-ls-entries |
| 353 | (mapcar (function | 369 | (mapcar (function |
| @@ -356,7 +372,8 @@ Sort entries alphabetically across.") | |||
| 356 | (file-name-absolute-p arg)) | 372 | (file-name-absolute-p arg)) |
| 357 | (expand-file-name arg) | 373 | (expand-file-name arg) |
| 358 | arg) | 374 | arg) |
| 359 | (eshell-file-attributes arg)))) args) | 375 | (eshell-file-attributes arg)))) |
| 376 | args) | ||
| 360 | t (expand-file-name default-directory))) | 377 | t (expand-file-name default-directory))) |
| 361 | (funcall flush-func))) | 378 | (funcall flush-func))) |
| 362 | 379 | ||
| @@ -491,12 +508,13 @@ relative to that directory." | |||
| 491 | (file-relative-name dir root-dir) | 508 | (file-relative-name dir root-dir) |
| 492 | (expand-file-name dir))) | 509 | (expand-file-name dir))) |
| 493 | (cdr dirinfo))) ":\n")) | 510 | (cdr dirinfo))) ":\n")) |
| 494 | (let ((entries | 511 | (let ((entries (eshell-directory-files-and-attributes |
| 495 | (eshell-directory-files-and-attributes dir nil nil t))) | 512 | dir nil (and (not show-all) |
| 496 | (unless show-all | 513 | eshell-ls-exclude-hidden |
| 497 | (while (and entries | 514 | "\\`[^.]") t))) |
| 498 | (string-match eshell-ls-exclude-regexp | 515 | (when (and (not show-all) eshell-ls-exclude-regexp) |
| 499 | (caar entries))) | 516 | (while (and entries (string-match eshell-ls-exclude-regexp |
| 517 | (caar entries))) | ||
| 500 | (setq entries (cdr entries))) | 518 | (setq entries (cdr entries))) |
| 501 | (let ((e entries)) | 519 | (let ((e entries)) |
| 502 | (while (cdr e) | 520 | (while (cdr e) |
| @@ -552,17 +570,13 @@ In Eshell's implementation of ls, ENTRIES is always reversed." | |||
| 552 | (let ((result | 570 | (let ((result |
| 553 | (cond | 571 | (cond |
| 554 | ((eq sort-method 'by-atime) | 572 | ((eq sort-method 'by-atime) |
| 555 | (eshell-ls-compare-entries | 573 | (eshell-ls-compare-entries l r 4 'eshell-time-less-p)) |
| 556 | l r 4 'eshell-time-less-p)) | ||
| 557 | ((eq sort-method 'by-mtime) | 574 | ((eq sort-method 'by-mtime) |
| 558 | (eshell-ls-compare-entries | 575 | (eshell-ls-compare-entries l r 5 'eshell-time-less-p)) |
| 559 | l r 5 'eshell-time-less-p)) | ||
| 560 | ((eq sort-method 'by-ctime) | 576 | ((eq sort-method 'by-ctime) |
| 561 | (eshell-ls-compare-entries | 577 | (eshell-ls-compare-entries l r 6 'eshell-time-less-p)) |
| 562 | l r 6 'eshell-time-less-p)) | ||
| 563 | ((eq sort-method 'by-size) | 578 | ((eq sort-method 'by-size) |
| 564 | (eshell-ls-compare-entries | 579 | (eshell-ls-compare-entries l r 7 '<)) |
| 565 | l r 7 '<)) | ||
| 566 | ((eq sort-method 'by-extension) | 580 | ((eq sort-method 'by-extension) |
| 567 | (let ((lx (file-name-extension | 581 | (let ((lx (file-name-extension |
| 568 | (directory-file-name (car l)))) | 582 | (directory-file-name (car l)))) |
| @@ -699,8 +713,8 @@ need to be printed." | |||
| 699 | (if (and need-return (not dir-literal)) | 713 | (if (and need-return (not dir-literal)) |
| 700 | (funcall insert-func "\n")) | 714 | (funcall insert-func "\n")) |
| 701 | (eshell-ls-dir dir show-names | 715 | (eshell-ls-dir dir show-names |
| 702 | (unless (file-name-absolute-p (car dir)) | 716 | (unless (file-name-absolute-p (car dir)) root-dir) |
| 703 | root-dir) size-width) | 717 | size-width) |
| 704 | (setq need-return t)))) | 718 | (setq need-return t)))) |
| 705 | 719 | ||
| 706 | (defun eshell-ls-find-column-widths (files) | 720 | (defun eshell-ls-find-column-widths (files) |
diff --git a/lisp/eshell/em-script.el b/lisp/eshell/em-script.el index d6a8ea54e2f..8967426cadf 100644 --- a/lisp/eshell/em-script.el +++ b/lisp/eshell/em-script.el | |||
| @@ -63,6 +63,9 @@ This includes when running `eshell-command'." | |||
| 63 | (string= (file-name-nondirectory file) | 63 | (string= (file-name-nondirectory file) |
| 64 | "eshell")) . eshell/source) | 64 | "eshell")) . eshell/source) |
| 65 | eshell-interpreter-alist)) | 65 | eshell-interpreter-alist)) |
| 66 | (make-local-variable 'eshell-complex-commands) | ||
| 67 | (setq eshell-complex-commands | ||
| 68 | (append '("source" ".") eshell-complex-commands)) | ||
| 66 | ;; these two variables are changed through usage, but we don't want | 69 | ;; these two variables are changed through usage, but we don't want |
| 67 | ;; to ruin it for other modules | 70 | ;; to ruin it for other modules |
| 68 | (let (eshell-inside-quote-regexp | 71 | (let (eshell-inside-quote-regexp |
diff --git a/lisp/eshell/em-smart.el b/lisp/eshell/em-smart.el index cc02f2fedc3..9bef8b10d20 100644 --- a/lisp/eshell/em-smart.el +++ b/lisp/eshell/em-smart.el | |||
| @@ -77,6 +77,11 @@ it to get a real sense of how it works." | |||
| 77 | ;; scroll, etc. | 77 | ;; scroll, etc. |
| 78 | ;; | 78 | ;; |
| 79 | ;; @ Like I said, it's not really comprehensible until you try it! ;) | 79 | ;; @ Like I said, it's not really comprehensible until you try it! ;) |
| 80 | ;; | ||
| 81 | ;; One disadvantage of this module is that it increases Eshell's | ||
| 82 | ;; memory consumption by a factor of two or more. With small commands | ||
| 83 | ;; (such as pwd), where the screen is mostly full, consumption can | ||
| 84 | ;; increase by orders of magnitude. | ||
| 80 | 85 | ||
| 81 | ;;; User Variables: | 86 | ;;; User Variables: |
| 82 | 87 | ||
| @@ -154,6 +159,7 @@ The options are `begin', `after' or `end'." | |||
| 154 | 159 | ||
| 155 | (defvar eshell-smart-displayed nil) | 160 | (defvar eshell-smart-displayed nil) |
| 156 | (defvar eshell-smart-command-done nil) | 161 | (defvar eshell-smart-command-done nil) |
| 162 | (defvar eshell-currently-handling-window nil) | ||
| 157 | 163 | ||
| 158 | ;;; Functions: | 164 | ;;; Functions: |
| 159 | 165 | ||
| @@ -175,19 +181,17 @@ The options are `begin', `after' or `end'." | |||
| 175 | 181 | ||
| 176 | (make-local-hook 'pre-command-hook) | 182 | (make-local-hook 'pre-command-hook) |
| 177 | (make-local-hook 'after-change-functions) | 183 | (make-local-hook 'after-change-functions) |
| 178 | (add-hook 'after-change-functions | 184 | (add-hook 'after-change-functions 'eshell-disable-after-change nil t) |
| 179 | 'eshell-disable-after-change nil t) | ||
| 180 | 185 | ||
| 181 | (make-local-hook 'eshell-input-filter-functions) | 186 | (make-local-hook 'eshell-input-filter-functions) |
| 182 | (add-hook 'eshell-input-filter-functions | 187 | (add-hook 'eshell-input-filter-functions 'eshell-smart-display-setup nil t) |
| 183 | 'eshell-smart-display-setup nil t) | ||
| 184 | 188 | ||
| 185 | (make-local-variable 'eshell-smart-command-done) | 189 | (make-local-variable 'eshell-smart-command-done) |
| 186 | (make-local-hook 'eshell-post-command-hook) | 190 | (make-local-hook 'eshell-post-command-hook) |
| 187 | (add-hook 'eshell-post-command-hook | 191 | (add-hook 'eshell-post-command-hook |
| 188 | (function | 192 | (function |
| 189 | (lambda () | 193 | (lambda () |
| 190 | (setq eshell-smart-command-done t))) t t) | 194 | (setq eshell-smart-command-done t))) t t) |
| 191 | 195 | ||
| 192 | (unless (eq eshell-review-quick-commands t) | 196 | (unless (eq eshell-review-quick-commands t) |
| 193 | (add-hook 'eshell-post-command-hook | 197 | (add-hook 'eshell-post-command-hook |
| @@ -198,10 +202,9 @@ The options are `begin', `after' or `end'." | |||
| 198 | (unless eshell-currently-handling-window | 202 | (unless eshell-currently-handling-window |
| 199 | (let ((inhibit-point-motion-hooks t) | 203 | (let ((inhibit-point-motion-hooks t) |
| 200 | (eshell-currently-handling-window t)) | 204 | (eshell-currently-handling-window t)) |
| 201 | (save-current-buffer | 205 | (save-selected-window |
| 202 | (save-selected-window | 206 | (select-window wind) |
| 203 | (select-window wind) | 207 | (eshell-smart-redisplay))))) |
| 204 | (eshell-smart-redisplay)))))) | ||
| 205 | 208 | ||
| 206 | (defun eshell-refresh-windows (&optional frame) | 209 | (defun eshell-refresh-windows (&optional frame) |
| 207 | "Refresh all visible Eshell buffers." | 210 | "Refresh all visible Eshell buffers." |
| @@ -210,10 +213,10 @@ The options are `begin', `after' or `end'." | |||
| 210 | (function | 213 | (function |
| 211 | (lambda (wind) | 214 | (lambda (wind) |
| 212 | (with-current-buffer (window-buffer wind) | 215 | (with-current-buffer (window-buffer wind) |
| 213 | (when eshell-mode | 216 | (if eshell-mode |
| 214 | (let (window-scroll-functions) | 217 | (let (window-scroll-functions) |
| 215 | (eshell-smart-scroll-window wind (window-start)) | 218 | (eshell-smart-scroll-window wind (window-start)) |
| 216 | (setq affected t)))))) | 219 | (setq affected t)))))) |
| 217 | 0 frame) | 220 | 0 frame) |
| 218 | (if affected | 221 | (if affected |
| 219 | (let (window-scroll-functions) | 222 | (let (window-scroll-functions) |
diff --git a/lisp/eshell/em-unix.el b/lisp/eshell/em-unix.el index 7f0414ef056..c9b3d418b83 100644 --- a/lisp/eshell/em-unix.el +++ b/lisp/eshell/em-unix.el | |||
| @@ -124,6 +124,11 @@ Otherwise, `rmdir' is required." | |||
| 124 | :type 'boolean | 124 | :type 'boolean |
| 125 | :group 'eshell-unix) | 125 | :group 'eshell-unix) |
| 126 | 126 | ||
| 127 | (defcustom eshell-default-target-is-dot nil | ||
| 128 | "*If non-nil, the default destination for cp, mv or ln is `.'." | ||
| 129 | :type 'boolean | ||
| 130 | :group 'eshell-unix) | ||
| 131 | |||
| 127 | (defcustom eshell-du-prefer-over-ange nil | 132 | (defcustom eshell-du-prefer-over-ange nil |
| 128 | "*Use Eshell's du in ange-ftp remote directories. | 133 | "*Use Eshell's du in ange-ftp remote directories. |
| 129 | Otherwise, Emacs will attempt to use rsh to invoke du on the remote machine." | 134 | Otherwise, Emacs will attempt to use rsh to invoke du on the remote machine." |
| @@ -140,7 +145,12 @@ Otherwise, Emacs will attempt to use rsh to invoke du on the remote machine." | |||
| 140 | (when (eshell-using-module 'eshell-cmpl) | 145 | (when (eshell-using-module 'eshell-cmpl) |
| 141 | (make-local-hook 'pcomplete-try-first-hook) | 146 | (make-local-hook 'pcomplete-try-first-hook) |
| 142 | (add-hook 'pcomplete-try-first-hook | 147 | (add-hook 'pcomplete-try-first-hook |
| 143 | 'eshell-complete-host-reference nil t))) | 148 | 'eshell-complete-host-reference nil t)) |
| 149 | (make-local-variable 'eshell-complex-commands) | ||
| 150 | (setq eshell-complex-commands | ||
| 151 | (append '("grep" "egrep" "fgrep" "agrep" "glimpse" "locate" | ||
| 152 | "cat" "time" "cp" "mv" "make" "du" "diff") | ||
| 153 | eshell-complex-commands))) | ||
| 144 | 154 | ||
| 145 | (defalias 'eshell/date 'current-time-string) | 155 | (defalias 'eshell/date 'current-time-string) |
| 146 | (defalias 'eshell/basename 'file-name-nondirectory) | 156 | (defalias 'eshell/basename 'file-name-nondirectory) |
| @@ -157,6 +167,7 @@ Otherwise, Emacs will attempt to use rsh to invoke du on the remote machine." | |||
| 157 | (funcall 'man (apply 'eshell-flatten-and-stringify args))) | 167 | (funcall 'man (apply 'eshell-flatten-and-stringify args))) |
| 158 | 168 | ||
| 159 | (defun eshell-remove-entries (path files &optional top-level) | 169 | (defun eshell-remove-entries (path files &optional top-level) |
| 170 | "From PATH, remove all of the given FILES, perhaps interactively." | ||
| 160 | (while files | 171 | (while files |
| 161 | (if (string-match "\\`\\.\\.?\\'" | 172 | (if (string-match "\\`\\.\\.?\\'" |
| 162 | (file-name-nondirectory (car files))) | 173 | (file-name-nondirectory (car files))) |
| @@ -302,8 +313,6 @@ Remove the DIRECTORY(ies), if they are empty.") | |||
| 302 | 313 | ||
| 303 | (defun eshell-shuffle-files (command action files target func deep &rest args) | 314 | (defun eshell-shuffle-files (command action files target func deep &rest args) |
| 304 | "Shuffle around some filesystem entries, using FUNC to do the work." | 315 | "Shuffle around some filesystem entries, using FUNC to do the work." |
| 305 | (if (null target) | ||
| 306 | (error "%s: missing destination file" command)) | ||
| 307 | (let ((attr-target (eshell-file-attributes target)) | 316 | (let ((attr-target (eshell-file-attributes target)) |
| 308 | (is-dir (or (file-directory-p target) | 317 | (is-dir (or (file-directory-p target) |
| 309 | (and preview (not eshell-warn-dot-directories)))) | 318 | (and preview (not eshell-warn-dot-directories)))) |
| @@ -417,30 +426,35 @@ Remove the DIRECTORY(ies), if they are empty.") | |||
| 417 | (format "tar %s %s" tar-args archive) args)))) | 426 | (format "tar %s %s" tar-args archive) args)))) |
| 418 | 427 | ||
| 419 | ;; this is to avoid duplicating code... | 428 | ;; this is to avoid duplicating code... |
| 420 | (defmacro eshell-mvcp-template | 429 | (defmacro eshell-mvcpln-template (command action func query-var |
| 421 | (command action func query-var force-var &optional preserve) | 430 | force-var &optional preserve) |
| 422 | `(if (and (string-match eshell-tar-regexp (car (last args))) | 431 | `(let ((len (length args))) |
| 423 | (or (> (length args) 2) | 432 | (if (or (= len 0) |
| 424 | (and (file-directory-p (car args)) | 433 | (and (= len 1) (null eshell-default-target-is-dot))) |
| 425 | (or (not no-dereference) | 434 | (error "%s: missing destination file or directory" ,command)) |
| 426 | (not (file-symlink-p (car args))))))) | 435 | (if (= len 1) |
| 427 | (eshell-shorthand-tar-command ,command args) | 436 | (nconc args '("."))) |
| 428 | (let (target ange-cache) | 437 | (setq args (eshell-stringify-list (eshell-flatten-list args))) |
| 429 | (if (> (length args) 1) | 438 | (if (and ,(not (equal command "ln")) |
| 430 | (progn | 439 | (string-match eshell-tar-regexp (car (last args))) |
| 431 | (setq target (car (last args))) | 440 | (or (> (length args) 2) |
| 432 | (setcdr (last args 2) nil)) | 441 | (and (file-directory-p (car args)) |
| 433 | (setq args nil)) | 442 | (or (not no-dereference) |
| 434 | (eshell-shuffle-files | 443 | (not (file-symlink-p (car args))))))) |
| 435 | ,command ,action args target ,func nil | 444 | (eshell-shorthand-tar-command ,command args) |
| 436 | ,@(append | 445 | (let ((target (car (last args))) |
| 437 | `((if (and (or interactive | 446 | ange-cache) |
| 438 | ,query-var) | 447 | (setcdr (last args 2) nil) |
| 439 | (not force)) | 448 | (eshell-shuffle-files |
| 440 | 1 (or force ,force-var))) | 449 | ,command ,action args target ,func nil |
| 441 | (if preserve | 450 | ,@(append |
| 442 | (list preserve))))) | 451 | `((if (and (or interactive |
| 443 | nil)) | 452 | ,query-var) |
| 453 | (not force)) | ||
| 454 | 1 (or force ,force-var))) | ||
| 455 | (if preserve | ||
| 456 | (list preserve))))) | ||
| 457 | nil))) | ||
| 444 | 458 | ||
| 445 | (defun eshell/mv (&rest args) | 459 | (defun eshell/mv (&rest args) |
| 446 | "Implementation of mv in Lisp." | 460 | "Implementation of mv in Lisp." |
| @@ -455,6 +469,7 @@ Remove the DIRECTORY(ies), if they are empty.") | |||
| 455 | (?v "verbose" nil verbose | 469 | (?v "verbose" nil verbose |
| 456 | "explain what is being done") | 470 | "explain what is being done") |
| 457 | (nil "help" nil nil "show this usage screen") | 471 | (nil "help" nil nil "show this usage screen") |
| 472 | :preserve-args | ||
| 458 | :external "mv" | 473 | :external "mv" |
| 459 | :show-usage | 474 | :show-usage |
| 460 | :usage "[OPTION]... SOURCE DEST | 475 | :usage "[OPTION]... SOURCE DEST |
| @@ -462,9 +477,9 @@ Remove the DIRECTORY(ies), if they are empty.") | |||
| 462 | Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY. | 477 | Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY. |
| 463 | \[OPTION] DIRECTORY...") | 478 | \[OPTION] DIRECTORY...") |
| 464 | (let ((no-dereference t)) | 479 | (let ((no-dereference t)) |
| 465 | (eshell-mvcp-template "mv" "moving" 'rename-file | 480 | (eshell-mvcpln-template "mv" "moving" 'rename-file |
| 466 | eshell-mv-interactive-query | 481 | eshell-mv-interactive-query |
| 467 | eshell-mv-overwrite-files)))) | 482 | eshell-mv-overwrite-files)))) |
| 468 | 483 | ||
| 469 | (defun eshell/cp (&rest args) | 484 | (defun eshell/cp (&rest args) |
| 470 | "Implementation of cp in Lisp." | 485 | "Implementation of cp in Lisp." |
| @@ -487,6 +502,7 @@ Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY. | |||
| 487 | (?v "verbose" nil verbose | 502 | (?v "verbose" nil verbose |
| 488 | "explain what is being done") | 503 | "explain what is being done") |
| 489 | (nil "help" nil nil "show this usage screen") | 504 | (nil "help" nil nil "show this usage screen") |
| 505 | :preserve-args | ||
| 490 | :external "cp" | 506 | :external "cp" |
| 491 | :show-usage | 507 | :show-usage |
| 492 | :usage "[OPTION]... SOURCE DEST | 508 | :usage "[OPTION]... SOURCE DEST |
| @@ -494,9 +510,9 @@ Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY. | |||
| 494 | Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.") | 510 | Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.") |
| 495 | (if archive | 511 | (if archive |
| 496 | (setq preserve t no-dereference t recursive t)) | 512 | (setq preserve t no-dereference t recursive t)) |
| 497 | (eshell-mvcp-template "cp" "copying" 'copy-file | 513 | (eshell-mvcpln-template "cp" "copying" 'copy-file |
| 498 | eshell-cp-interactive-query | 514 | eshell-cp-interactive-query |
| 499 | eshell-cp-overwrite-files preserve))) | 515 | eshell-cp-overwrite-files preserve))) |
| 500 | 516 | ||
| 501 | (defun eshell/ln (&rest args) | 517 | (defun eshell/ln (&rest args) |
| 502 | "Implementation of ln in Lisp." | 518 | "Implementation of ln in Lisp." |
| @@ -505,11 +521,13 @@ Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.") | |||
| 505 | '((?h "help" nil nil "show this usage screen") | 521 | '((?h "help" nil nil "show this usage screen") |
| 506 | (?s "symbolic" nil symbolic | 522 | (?s "symbolic" nil symbolic |
| 507 | "make symbolic links instead of hard links") | 523 | "make symbolic links instead of hard links") |
| 508 | (?i "interactive" nil interactive "request confirmation if target already exists") | 524 | (?i "interactive" nil interactive |
| 525 | "request confirmation if target already exists") | ||
| 509 | (?f "force" nil force "remove existing destinations, never prompt") | 526 | (?f "force" nil force "remove existing destinations, never prompt") |
| 510 | (?n "preview" nil preview | 527 | (?n "preview" nil preview |
| 511 | "don't change anything on disk") | 528 | "don't change anything on disk") |
| 512 | (?v "verbose" nil verbose "explain what is being done") | 529 | (?v "verbose" nil verbose "explain what is being done") |
| 530 | :preserve-args | ||
| 513 | :external "ln" | 531 | :external "ln" |
| 514 | :show-usage | 532 | :show-usage |
| 515 | :usage "[OPTION]... TARGET [LINK_NAME] | 533 | :usage "[OPTION]... TARGET [LINK_NAME] |
| @@ -518,27 +536,19 @@ Create a link to the specified TARGET with optional LINK_NAME. If there is | |||
| 518 | more than one TARGET, the last argument must be a directory; create links | 536 | more than one TARGET, the last argument must be a directory; create links |
| 519 | in DIRECTORY to each TARGET. Create hard links by default, symbolic links | 537 | in DIRECTORY to each TARGET. Create hard links by default, symbolic links |
| 520 | with '--symbolic'. When creating hard links, each TARGET must exist.") | 538 | with '--symbolic'. When creating hard links, each TARGET must exist.") |
| 521 | (let (target no-dereference ange-cache) | 539 | (let ((no-dereference t)) |
| 522 | (if (> (length args) 1) | 540 | (eshell-mvcpln-template "ln" "linking" |
| 523 | (progn | 541 | (if symbolic |
| 524 | (setq target (car (last args))) | 542 | 'make-symbolic-link |
| 525 | (setcdr (last args 2) nil)) | 543 | 'add-name-to-file) |
| 526 | (setq args nil)) | 544 | eshell-ln-interactive-query |
| 527 | (eshell-shuffle-files "ln" "linking" args target | 545 | eshell-ln-overwrite-files)))) |
| 528 | (if symbolic | ||
| 529 | 'make-symbolic-link | ||
| 530 | 'add-name-to-file) nil | ||
| 531 | (if (and (or interactive | ||
| 532 | eshell-ln-interactive-query) | ||
| 533 | (not force)) | ||
| 534 | 1 (or force eshell-ln-overwrite-files)))) | ||
| 535 | nil)) | ||
| 536 | 546 | ||
| 537 | (defun eshell/cat (&rest args) | 547 | (defun eshell/cat (&rest args) |
| 538 | "Implementation of cat in Lisp. | 548 | "Implementation of cat in Lisp. |
| 539 | If in a pipeline, or the file is not a regular file, directory or | 549 | If in a pipeline, or the file is not a regular file, directory or |
| 540 | symlink, then revert to the system's definition of cat." | 550 | symlink, then revert to the system's definition of cat." |
| 541 | (setq args (eshell-flatten-list args)) | 551 | (setq args (eshell-stringify-list (eshell-flatten-list args))) |
| 542 | (if (or eshell-in-pipeline-p | 552 | (if (or eshell-in-pipeline-p |
| 543 | (catch 'special | 553 | (catch 'special |
| 544 | (eshell-for arg args | 554 | (eshell-for arg args |
| @@ -593,7 +603,8 @@ Concatenate FILE(s), or standard input, to standard output.") | |||
| 593 | (list 'quote (eshell-copy-environment)))))) | 603 | (list 'quote (eshell-copy-environment)))))) |
| 594 | (compile (concat "make " (eshell-flatten-and-stringify args)))) | 604 | (compile (concat "make " (eshell-flatten-and-stringify args)))) |
| 595 | (throw 'eshell-replace-command | 605 | (throw 'eshell-replace-command |
| 596 | (eshell-parse-command "*make" (eshell-flatten-list args))))) | 606 | (eshell-parse-command "*make" (eshell-stringify-list |
| 607 | (eshell-flatten-list args)))))) | ||
| 597 | 608 | ||
| 598 | (defun eshell-occur-mode-goto-occurrence () | 609 | (defun eshell-occur-mode-goto-occurrence () |
| 599 | "Go to the occurrence the current line describes." | 610 | "Go to the occurrence the current line describes." |
| @@ -627,7 +638,8 @@ available..." | |||
| 627 | (default-directory default-dir)) | 638 | (default-directory default-dir)) |
| 628 | (erase-buffer) | 639 | (erase-buffer) |
| 629 | (occur-mode) | 640 | (occur-mode) |
| 630 | (let ((files (eshell-flatten-list (cdr args))) | 641 | (let ((files (eshell-stringify-list |
| 642 | (eshell-flatten-list (cdr args)))) | ||
| 631 | (inhibit-redisplay t) | 643 | (inhibit-redisplay t) |
| 632 | string) | 644 | string) |
| 633 | (when (car args) | 645 | (when (car args) |
| @@ -670,14 +682,16 @@ external command." | |||
| 670 | (not eshell-in-subcommand-p)))) | 682 | (not eshell-in-subcommand-p)))) |
| 671 | (throw 'eshell-replace-command | 683 | (throw 'eshell-replace-command |
| 672 | (eshell-parse-command (concat "*" command) | 684 | (eshell-parse-command (concat "*" command) |
| 673 | (eshell-flatten-list args))) | 685 | (eshell-stringify-list |
| 686 | (eshell-flatten-list args)))) | ||
| 674 | (let* ((compilation-process-setup-function | 687 | (let* ((compilation-process-setup-function |
| 675 | (list 'lambda nil | 688 | (list 'lambda nil |
| 676 | (list 'setq 'process-environment | 689 | (list 'setq 'process-environment |
| 677 | (list 'quote (eshell-copy-environment))))) | 690 | (list 'quote (eshell-copy-environment))))) |
| 678 | (args (mapconcat 'identity | 691 | (args (mapconcat 'identity |
| 679 | (mapcar 'shell-quote-argument | 692 | (mapcar 'shell-quote-argument |
| 680 | (eshell-flatten-list args)) | 693 | (eshell-stringify-list |
| 694 | (eshell-flatten-list args))) | ||
| 681 | " ")) | 695 | " ")) |
| 682 | (cmd (progn | 696 | (cmd (progn |
| 683 | (set-text-properties 0 (length args) | 697 | (set-text-properties 0 (length args) |
| @@ -797,7 +811,7 @@ external command." | |||
| 797 | (defun eshell/du (&rest args) | 811 | (defun eshell/du (&rest args) |
| 798 | "Implementation of \"du\" in Lisp, passing ARGS." | 812 | "Implementation of \"du\" in Lisp, passing ARGS." |
| 799 | (setq args (if args | 813 | (setq args (if args |
| 800 | (eshell-flatten-list args) | 814 | (eshell-stringify-list (eshell-flatten-list args)) |
| 801 | '("."))) | 815 | '("."))) |
| 802 | (let ((ext-du (eshell-search-path "du"))) | 816 | (let ((ext-du (eshell-search-path "du"))) |
| 803 | (if (and ext-du | 817 | (if (and ext-du |
| @@ -909,7 +923,7 @@ Show wall-clock time elapsed during execution of COMMAND.") | |||
| 909 | 923 | ||
| 910 | (defun eshell/diff (&rest args) | 924 | (defun eshell/diff (&rest args) |
| 911 | "Alias \"diff\" to call Emacs `diff' function." | 925 | "Alias \"diff\" to call Emacs `diff' function." |
| 912 | (let ((orig-args (eshell-flatten-list args))) | 926 | (let ((orig-args (eshell-stringify-list (eshell-flatten-list args)))) |
| 913 | (if (or eshell-plain-diff-behavior | 927 | (if (or eshell-plain-diff-behavior |
| 914 | (not (and (eshell-interactive-output-p) | 928 | (not (and (eshell-interactive-output-p) |
| 915 | (not eshell-in-pipeline-p) | 929 | (not eshell-in-pipeline-p) |
| @@ -951,7 +965,8 @@ Show wall-clock time elapsed during execution of COMMAND.") | |||
| 951 | (and (stringp (car args)) | 965 | (and (stringp (car args)) |
| 952 | (string-match "^-" (car args)))) | 966 | (string-match "^-" (car args)))) |
| 953 | (throw 'eshell-replace-command | 967 | (throw 'eshell-replace-command |
| 954 | (eshell-parse-command "*locate" (eshell-flatten-list args))) | 968 | (eshell-parse-command "*locate" (eshell-stringify-list |
| 969 | (eshell-flatten-list args)))) | ||
| 955 | (save-selected-window | 970 | (save-selected-window |
| 956 | (let ((locate-history-list (list (car args)))) | 971 | (let ((locate-history-list (list (car args)))) |
| 957 | (locate-with-filter (car args) (cadr args)))))) | 972 | (locate-with-filter (car args) (cadr args)))))) |
diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el index 6d2ede0a72c..7d5a53625f5 100644 --- a/lisp/eshell/esh-cmd.el +++ b/lisp/eshell/esh-cmd.el | |||
| @@ -203,6 +203,21 @@ which may be modified directly. Any return value is ignored." | |||
| 203 | :type 'hook | 203 | :type 'hook |
| 204 | :group 'eshell-cmd) | 204 | :group 'eshell-cmd) |
| 205 | 205 | ||
| 206 | (defcustom eshell-complex-commands nil | ||
| 207 | "*A list of commands names or functions, that determine complexity. | ||
| 208 | That is, if a command is defined by a function named eshell/NAME, | ||
| 209 | and NAME is part of this list, it is invoked as a complex command. | ||
| 210 | Complex commands are always correct, but run much slower. If a | ||
| 211 | command works fine without being part of this list, then it doesn't | ||
| 212 | need to be. | ||
| 213 | |||
| 214 | If an entry is a function, it will be called with the name, and should | ||
| 215 | return non-nil if the command is complex." | ||
| 216 | :type '(repeat :tag "Commands" | ||
| 217 | (choice (string :tag "Name") | ||
| 218 | (function :tag "Predicate"))) | ||
| 219 | :group 'eshell-cmd) | ||
| 220 | |||
| 206 | ;;; Code: | 221 | ;;; Code: |
| 207 | 222 | ||
| 208 | (require 'esh-util) | 223 | (require 'esh-util) |
| @@ -518,8 +533,8 @@ implemented via rewriting, rather than as a function." | |||
| 518 | (list 'car | 533 | (list 'car |
| 519 | (list 'symbol-value | 534 | (list 'symbol-value |
| 520 | (list 'quote 'for-items))))) | 535 | (list 'quote 'for-items))))) |
| 521 | (list 'eshell-copy-handles | 536 | (list 'eshell-protect |
| 522 | (eshell-invokify-arg body t))) | 537 | (eshell-invokify-arg body t))) |
| 523 | (list 'setcar 'for-items | 538 | (list 'setcar 'for-items |
| 524 | (list 'cadr | 539 | (list 'cadr |
| 525 | (list 'symbol-value | 540 | (list 'symbol-value |
| @@ -583,7 +598,7 @@ must be implemented via rewriting, rather than as a function." | |||
| 583 | (eshell-structure-basic-command | 598 | (eshell-structure-basic-command |
| 584 | 'while '("while" "until") (car terms) | 599 | 'while '("while" "until") (car terms) |
| 585 | (eshell-invokify-arg (cadr terms) nil t) | 600 | (eshell-invokify-arg (cadr terms) nil t) |
| 586 | (list 'eshell-copy-handles | 601 | (list 'eshell-protect |
| 587 | (eshell-invokify-arg (car (last terms)) t))))) | 602 | (eshell-invokify-arg (car (last terms)) t))))) |
| 588 | 603 | ||
| 589 | (defun eshell-rewrite-if-command (terms) | 604 | (defun eshell-rewrite-if-command (terms) |
| @@ -596,13 +611,15 @@ must be implemented via rewriting, rather than as a function." | |||
| 596 | (eshell-structure-basic-command | 611 | (eshell-structure-basic-command |
| 597 | 'if '("if" "unless") (car terms) | 612 | 'if '("if" "unless") (car terms) |
| 598 | (eshell-invokify-arg (cadr terms) nil t) | 613 | (eshell-invokify-arg (cadr terms) nil t) |
| 599 | (eshell-invokify-arg | 614 | (list 'eshell-protect |
| 600 | (if (= (length terms) 5) | 615 | (eshell-invokify-arg |
| 601 | (car (last terms 3)) | 616 | (if (= (length terms) 5) |
| 602 | (car (last terms))) t) | 617 | (car (last terms 3)) |
| 603 | (eshell-invokify-arg | 618 | (car (last terms))) t)) |
| 604 | (if (= (length terms) 5) | 619 | (if (= (length terms) 5) |
| 605 | (car (last terms))) t)))) | 620 | (list 'eshell-protect |
| 621 | (eshell-invokify-arg | ||
| 622 | (car (last terms)))) t)))) | ||
| 606 | 623 | ||
| 607 | (defun eshell-exit-success-p () | 624 | (defun eshell-exit-success-p () |
| 608 | "Return non-nil if the last command was \"successful\". | 625 | "Return non-nil if the last command was \"successful\". |
| @@ -651,8 +668,8 @@ For an external command, it means an exit code of 0." | |||
| 651 | (assert (car sep-terms)) | 668 | (assert (car sep-terms)) |
| 652 | (setq final (eshell-structure-basic-command | 669 | (setq final (eshell-structure-basic-command |
| 653 | 'if (string= (car sep-terms) "&&") "if" | 670 | 'if (string= (car sep-terms) "&&") "if" |
| 654 | (list 'eshell-commands (car results)) | 671 | (list 'eshell-protect (car results)) |
| 655 | final | 672 | (list 'eshell-protect final) |
| 656 | nil t) | 673 | nil t) |
| 657 | results (cdr results) | 674 | results (cdr results) |
| 658 | sep-terms (cdr sep-terms))) | 675 | sep-terms (cdr sep-terms))) |
| @@ -690,8 +707,8 @@ For an external command, it means an exit code of 0." | |||
| 690 | (list 'eshell-lisp-command (list 'quote obj))) | 707 | (list 'eshell-lisp-command (list 'quote obj))) |
| 691 | (ignore (goto-char here)))))) | 708 | (ignore (goto-char here)))))) |
| 692 | 709 | ||
| 693 | (defun eshell-separate-commands | 710 | (defun eshell-separate-commands (terms separator &optional |
| 694 | (terms separator &optional reversed last-terms-sym) | 711 | reversed last-terms-sym) |
| 695 | "Separate TERMS using SEPARATOR. | 712 | "Separate TERMS using SEPARATOR. |
| 696 | If REVERSED is non-nil, the list of separated term groups will be | 713 | If REVERSED is non-nil, the list of separated term groups will be |
| 697 | returned in reverse order. If LAST-TERMS-SYM is a symbol, it's value | 714 | returned in reverse order. If LAST-TERMS-SYM is a symbol, it's value |
| @@ -772,21 +789,6 @@ this grossness will be made to disappear by using `call/cc'..." | |||
| 772 | (eshell-errorn (error-message-string err)) | 789 | (eshell-errorn (error-message-string err)) |
| 773 | (eshell-close-handles 1))))) | 790 | (eshell-close-handles 1))))) |
| 774 | 791 | ||
| 775 | ;; (defun eshell-copy-or-protect-handles () | ||
| 776 | ;; (if (eshell-processp (car (aref eshell-current-handles | ||
| 777 | ;; eshell-output-handle))) | ||
| 778 | ;; (eshell-protect-handles eshell-current-handles) | ||
| 779 | ;; (eshell-create-handles | ||
| 780 | ;; (car (aref eshell-current-handles | ||
| 781 | ;; eshell-output-handle)) nil | ||
| 782 | ;; (car (aref eshell-current-handles | ||
| 783 | ;; eshell-error-handle)) nil))) | ||
| 784 | |||
| 785 | ;; (defmacro eshell-copy-handles (object) | ||
| 786 | ;; "Duplicate current I/O handles, so OBJECT works with its own copy." | ||
| 787 | ;; `(let ((eshell-current-handles (eshell-copy-or-protect-handles))) | ||
| 788 | ;; ,object)) | ||
| 789 | |||
| 790 | (defmacro eshell-copy-handles (object) | 792 | (defmacro eshell-copy-handles (object) |
| 791 | "Duplicate current I/O handles, so OBJECT works with its own copy." | 793 | "Duplicate current I/O handles, so OBJECT works with its own copy." |
| 792 | `(let ((eshell-current-handles | 794 | `(let ((eshell-current-handles |
| @@ -965,6 +967,22 @@ at the moment are: | |||
| 965 | (if subform | 967 | (if subform |
| 966 | (concat "\n\n" (eshell-stringify subform)) "")))))) | 968 | (concat "\n\n" (eshell-stringify subform)) "")))))) |
| 967 | 969 | ||
| 970 | (defun eshell-invoke-directly (command input) | ||
| 971 | (let ((base (cadr (nth 2 (nth 2 (cadr command))))) name) | ||
| 972 | (if (and (eq (car base) 'eshell-trap-errors) | ||
| 973 | (eq (car (cadr base)) 'eshell-named-command)) | ||
| 974 | (setq name (cadr (cadr base)))) | ||
| 975 | (and name (stringp name) | ||
| 976 | (not (member name eshell-complex-commands)) | ||
| 977 | (catch 'simple | ||
| 978 | (progn | ||
| 979 | (eshell-for pred eshell-complex-commands | ||
| 980 | (if (and (functionp pred) | ||
| 981 | (funcall pred name)) | ||
| 982 | (throw 'simple nil))) | ||
| 983 | t)) | ||
| 984 | (fboundp (intern-soft (concat "eshell/" name)))))) | ||
| 985 | |||
| 968 | (defun eshell-eval-command (command &optional input) | 986 | (defun eshell-eval-command (command &optional input) |
| 969 | "Evaluate the given COMMAND iteratively." | 987 | "Evaluate the given COMMAND iteratively." |
| 970 | (if eshell-current-command | 988 | (if eshell-current-command |
| @@ -1163,29 +1181,29 @@ be finished later after the completion of an asynchronous subprocess." | |||
| 1163 | ((eq (car form) 'prog1) | 1181 | ((eq (car form) 'prog1) |
| 1164 | (cadr form)) | 1182 | (cadr form)) |
| 1165 | (t | 1183 | (t |
| 1184 | ;; If a command desire to replace its execution form with | ||
| 1185 | ;; another command form, all it needs to do is throw the new | ||
| 1186 | ;; form using the exception tag `eshell-replace-command'. | ||
| 1187 | ;; For example, let's say that the form currently being | ||
| 1188 | ;; eval'd is: | ||
| 1189 | ;; | ||
| 1190 | ;; (eshell-named-command "hello") | ||
| 1191 | ;; | ||
| 1192 | ;; Now, let's assume the 'hello' command is an Eshell alias, | ||
| 1193 | ;; the definition of which yields the command: | ||
| 1194 | ;; | ||
| 1195 | ;; (eshell-named-command "echo" (list "Hello" "world")) | ||
| 1196 | ;; | ||
| 1197 | ;; What the alias code would like to do is simply substitute | ||
| 1198 | ;; the alias form for the original form. To accomplish | ||
| 1199 | ;; this, all it needs to do is to throw the substitution | ||
| 1200 | ;; form with the `eshell-replace-command' tag, and the form | ||
| 1201 | ;; will be replaced within the current command, and | ||
| 1202 | ;; execution will then resume (iteratively) as before. | ||
| 1203 | ;; Thus, aliases can even contain references to asynchronous | ||
| 1204 | ;; sub-commands, and things will still work out as they | ||
| 1205 | ;; should. | ||
| 1166 | (let (result new-form) | 1206 | (let (result new-form) |
| 1167 | ;; If a command desire to replace its execution form with | ||
| 1168 | ;; another command form, all it needs to do is throw the | ||
| 1169 | ;; new form using the exception tag | ||
| 1170 | ;; `eshell-replace-command'. For example, let's say that | ||
| 1171 | ;; the form currently being eval'd is: | ||
| 1172 | ;; | ||
| 1173 | ;; (eshell-named-command \"hello\") | ||
| 1174 | ;; | ||
| 1175 | ;; Now, let's assume the 'hello' command is an Eshell | ||
| 1176 | ;; alias, the definition of which yields the command: | ||
| 1177 | ;; | ||
| 1178 | ;; (eshell-named-command \"echo\" (list \"Hello\" \"world\")) | ||
| 1179 | ;; | ||
| 1180 | ;; What the alias code would like to do is simply | ||
| 1181 | ;; substitute the alias form for the original form. To | ||
| 1182 | ;; accomplish this, all it needs to do is to throw the | ||
| 1183 | ;; substitution form with the `eshell-replace-command' | ||
| 1184 | ;; tag, and the form will be replaced within the current | ||
| 1185 | ;; command, and execution will then resume (iteratively) | ||
| 1186 | ;; as before. Thus, aliases can even contain references | ||
| 1187 | ;; to asynchronous sub-commands, and things will still | ||
| 1188 | ;; work out as they should. | ||
| 1189 | (if (setq new-form | 1207 | (if (setq new-form |
| 1190 | (catch 'eshell-replace-command | 1208 | (catch 'eshell-replace-command |
| 1191 | (ignore | 1209 | (ignore |
diff --git a/lisp/eshell/esh-groups.el b/lisp/eshell/esh-groups.el index 218bd2a2e52..d82cdff4ffd 100644 --- a/lisp/eshell/esh-groups.el +++ b/lisp/eshell/esh-groups.el | |||
| @@ -132,4 +132,3 @@ functions, or as aliases which make some of Emacs' behavior more | |||
| 132 | naturally accessible within Emacs." | 132 | naturally accessible within Emacs." |
| 133 | :tag "Extra alias functions" | 133 | :tag "Extra alias functions" |
| 134 | :group 'eshell-module) | 134 | :group 'eshell-module) |
| 135 | |||
diff --git a/lisp/eshell/esh-maint.el b/lisp/eshell/esh-maint.el index 13b3597b4ce..89e50401c67 100644 --- a/lisp/eshell/esh-maint.el +++ b/lisp/eshell/esh-maint.el | |||
| @@ -48,7 +48,7 @@ | |||
| 48 | ;; (interactive) | 48 | ;; (interactive) |
| 49 | ;; (require 'autoload) | 49 | ;; (require 'autoload) |
| 50 | ;; (setq generated-autoload-file | 50 | ;; (setq generated-autoload-file |
| 51 | ;; (expand-file-name (car command-line-args-left))) | 51 | ;; (expand-file-name (car command-line-args-left))) |
| 52 | ;; (setq command-line-args-left (cdr command-line-args-left)) | 52 | ;; (setq command-line-args-left (cdr command-line-args-left)) |
| 53 | ;; (batch-update-autoloads)) | 53 | ;; (batch-update-autoloads)) |
| 54 | 54 | ||
| @@ -65,23 +65,23 @@ | |||
| 65 | ;; Core Functionality\n") | 65 | ;; Core Functionality\n") |
| 66 | ;; (eshell-for module | 66 | ;; (eshell-for module |
| 67 | ;; (sort (eshell-subgroups 'eshell) | 67 | ;; (sort (eshell-subgroups 'eshell) |
| 68 | ;; (function | 68 | ;; (function |
| 69 | ;; (lambda (a b) | 69 | ;; (lambda (a b) |
| 70 | ;; (string-lessp (symbol-name a) | 70 | ;; (string-lessp (symbol-name a) |
| 71 | ;; (symbol-name b))))) | 71 | ;; (symbol-name b))))) |
| 72 | ;; (insert (format "* %-34s" | 72 | ;; (insert (format "* %-34s" |
| 73 | ;; (concat (get module 'custom-tag) "::")) | 73 | ;; (concat (get module 'custom-tag) "::")) |
| 74 | ;; (symbol-name module) ".\n")) | 74 | ;; (symbol-name module) ".\n")) |
| 75 | ;; (insert "\nOptional Functionality\n") | 75 | ;; (insert "\nOptional Functionality\n") |
| 76 | ;; (eshell-for module | 76 | ;; (eshell-for module |
| 77 | ;; (sort (eshell-subgroups 'eshell-module) | 77 | ;; (sort (eshell-subgroups 'eshell-module) |
| 78 | ;; (function | 78 | ;; (function |
| 79 | ;; (lambda (a b) | 79 | ;; (lambda (a b) |
| 80 | ;; (string-lessp (symbol-name a) | 80 | ;; (string-lessp (symbol-name a) |
| 81 | ;; (symbol-name b))))) | 81 | ;; (symbol-name b))))) |
| 82 | ;; (insert (format "* %-34s" | 82 | ;; (insert (format "* %-34s" |
| 83 | ;; (concat (get module 'custom-tag) "::")) | 83 | ;; (concat (get module 'custom-tag) "::")) |
| 84 | ;; (symbol-name module) ".\n")) | 84 | ;; (symbol-name module) ".\n")) |
| 85 | ;; (insert "@end menu\n")) | 85 | ;; (insert "@end menu\n")) |
| 86 | 86 | ||
| 87 | ;; (defun eshell-make-texi () | 87 | ;; (defun eshell-make-texi () |
| @@ -91,27 +91,27 @@ | |||
| 91 | ;; (require 'texidoc) | 91 | ;; (require 'texidoc) |
| 92 | ;; (require 'pcomplete) | 92 | ;; (require 'pcomplete) |
| 93 | ;; (apply 'texidoc-files 'eshell-generate-main-menu "eshell.doci" | 93 | ;; (apply 'texidoc-files 'eshell-generate-main-menu "eshell.doci" |
| 94 | ;; (append | 94 | ;; (append |
| 95 | ;; (list "eshell.el") | 95 | ;; (list "eshell.el") |
| 96 | ;; (sort (mapcar | 96 | ;; (sort (mapcar |
| 97 | ;; (function | 97 | ;; (function |
| 98 | ;; (lambda (sym) | 98 | ;; (lambda (sym) |
| 99 | ;; (let ((name (symbol-name sym))) | 99 | ;; (let ((name (symbol-name sym))) |
| 100 | ;; (if (string-match "\\`eshell-\\(.*\\)" name) | 100 | ;; (if (string-match "\\`eshell-\\(.*\\)" name) |
| 101 | ;; (setq name (concat "esh-" (match-string 1 name)))) | 101 | ;; (setq name (concat "esh-" (match-string 1 name)))) |
| 102 | ;; (concat name ".el")))) | 102 | ;; (concat name ".el")))) |
| 103 | ;; (eshell-subgroups 'eshell)) | 103 | ;; (eshell-subgroups 'eshell)) |
| 104 | ;; 'string-lessp) | 104 | ;; 'string-lessp) |
| 105 | ;; (sort (mapcar | 105 | ;; (sort (mapcar |
| 106 | ;; (function | 106 | ;; (function |
| 107 | ;; (lambda (sym) | 107 | ;; (lambda (sym) |
| 108 | ;; (let ((name (symbol-name sym))) | 108 | ;; (let ((name (symbol-name sym))) |
| 109 | ;; (if (string-match "\\`eshell-\\(.*\\)" name) | 109 | ;; (if (string-match "\\`eshell-\\(.*\\)" name) |
| 110 | ;; (setq name (concat "em-" (match-string 1 name)))) | 110 | ;; (setq name (concat "em-" (match-string 1 name)))) |
| 111 | ;; (concat name ".el")))) | 111 | ;; (concat name ".el")))) |
| 112 | ;; (eshell-subgroups 'eshell-module)) | 112 | ;; (eshell-subgroups 'eshell-module)) |
| 113 | ;; 'string-lessp) | 113 | ;; 'string-lessp) |
| 114 | ;; (list "eshell.texi")))) | 114 | ;; (list "eshell.texi")))) |
| 115 | 115 | ||
| 116 | ;; (defun eshell-make-readme () | 116 | ;; (defun eshell-make-readme () |
| 117 | ;; "Make the README file from eshell.el." | 117 | ;; "Make the README file from eshell.el." |
diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el index ad513c47a0b..5da511626c5 100644 --- a/lisp/eshell/esh-mode.el +++ b/lisp/eshell/esh-mode.el | |||
| @@ -180,9 +180,7 @@ inserted. They return the string as it should be inserted." | |||
| 180 | :group 'eshell-mode) | 180 | :group 'eshell-mode) |
| 181 | 181 | ||
| 182 | (defcustom eshell-password-prompt-regexp | 182 | (defcustom eshell-password-prompt-regexp |
| 183 | "\\(\\([Oo]ld \\|[Nn]ew \\|Kerberos \\|CVS \\|'s \\|login \\|^\\)\ | 183 | "[Pp]ass\\(word\\|phrase\\).*:\\s *\\'" |
| 184 | [Pp]assword\\|pass phrase\\|\\(Enter\\|Repeat\\) passphrase\\)\ | ||
| 185 | \\( for [^@ \t\n]+@[^@ \t\n]+\\)?:\\s *\\'" | ||
| 186 | "*Regexp matching prompts for passwords in the inferior process. | 184 | "*Regexp matching prompts for passwords in the inferior process. |
| 187 | This is used by `eshell-watch-for-password-prompt'." | 185 | This is used by `eshell-watch-for-password-prompt'." |
| 188 | :type 'regexp | 186 | :type 'regexp |
| @@ -462,7 +460,8 @@ sessions, such as when using `eshell-command'.") | |||
| 462 | 460 | ||
| 463 | (eshell-deftest var window-height | 461 | (eshell-deftest var window-height |
| 464 | "LINES equals window height" | 462 | "LINES equals window height" |
| 465 | (eshell-command-result-p "= $LINES (window-height)" "t\n")) | 463 | (let ((eshell-stringify-t t)) |
| 464 | (eshell-command-result-p "= $LINES (window-height)" "t\n"))) | ||
| 466 | 465 | ||
| 467 | (defun eshell-command-started () | 466 | (defun eshell-command-started () |
| 468 | "Indicate in the modeline that a command has started." | 467 | "Indicate in the modeline that a command has started." |
| @@ -736,7 +735,9 @@ newline." | |||
| 736 | (run-hooks 'eshell-input-filter-functions) | 735 | (run-hooks 'eshell-input-filter-functions) |
| 737 | (and (catch 'eshell-terminal | 736 | (and (catch 'eshell-terminal |
| 738 | (ignore | 737 | (ignore |
| 739 | (eshell-eval-command cmd input))) | 738 | (if (eshell-invoke-directly cmd input) |
| 739 | (eval cmd) | ||
| 740 | (eshell-eval-command cmd input)))) | ||
| 740 | (eshell-life-is-too-much))))) | 741 | (eshell-life-is-too-much))))) |
| 741 | (quit | 742 | (quit |
| 742 | (eshell-reset t) | 743 | (eshell-reset t) |
diff --git a/lisp/eshell/esh-module.el b/lisp/eshell/esh-module.el index 3eab199201e..f09f1ac7b24 100644 --- a/lisp/eshell/esh-module.el +++ b/lisp/eshell/esh-module.el | |||
| @@ -24,7 +24,9 @@ | |||
| 24 | 24 | ||
| 25 | (provide 'esh-module) | 25 | (provide 'esh-module) |
| 26 | 26 | ||
| 27 | (eval-when-compile (require 'esh-maint) (require 'cl)) | 27 | (eval-when-compile |
| 28 | (require 'esh-maint) | ||
| 29 | (require 'cl)) | ||
| 28 | 30 | ||
| 29 | (defgroup eshell-module nil | 31 | (defgroup eshell-module nil |
| 30 | "The `eshell-module' group is for Eshell extension modules, which | 32 | "The `eshell-module' group is for Eshell extension modules, which |
| @@ -85,7 +87,7 @@ customizing the variable `eshell-modules-list'." | |||
| 85 | (equal (file-name-nondirectory byte-compile-current-file) | 87 | (equal (file-name-nondirectory byte-compile-current-file) |
| 86 | "esh-modu.el")))) | 88 | "esh-modu.el")))) |
| 87 | (let* ((directory (file-name-directory byte-compile-current-file)) | 89 | (let* ((directory (file-name-directory byte-compile-current-file)) |
| 88 | (elc-file (expand-file-name "esh-groups.elc" directory))) | 90 | (elc-file (expand-file-name "esh-groups.elc" directory))) |
| 89 | (eshell-load-defgroups directory) | 91 | (eshell-load-defgroups directory) |
| 90 | (if (file-exists-p elc-file) (delete-file elc-file))))) | 92 | (if (file-exists-p elc-file) (delete-file elc-file))))) |
| 91 | 93 | ||
diff --git a/lisp/eshell/esh-test.el b/lisp/eshell/esh-test.el index 6a14541ab39..acfb409da57 100644 --- a/lisp/eshell/esh-test.el +++ b/lisp/eshell/esh-test.el | |||
| @@ -173,12 +173,12 @@ | |||
| 173 | system-configuration | 173 | system-configuration |
| 174 | (cond ((featurep 'motif) ", Motif") | 174 | (cond ((featurep 'motif) ", Motif") |
| 175 | ((featurep 'x-toolkit) ", X toolkit") | 175 | ((featurep 'x-toolkit) ", X toolkit") |
| 176 | (t ""))) "\n") | 176 | (t "")))) |
| 177 | (switch-to-buffer test-buffer) | 177 | (switch-to-buffer test-buffer) |
| 178 | (delete-other-windows)) | 178 | (delete-other-windows)) |
| 179 | (eshell-for funcname | 179 | (eshell-for funcname (sort (all-completions "eshell-test--" |
| 180 | (sort (all-completions "eshell-test--" obarray 'functionp) | 180 | obarray 'functionp) |
| 181 | 'string-lessp) | 181 | 'string-lessp) |
| 182 | (with-current-buffer test-buffer | 182 | (with-current-buffer test-buffer |
| 183 | (insert "\n")) | 183 | (insert "\n")) |
| 184 | (funcall (intern-soft funcname))) | 184 | (funcall (intern-soft funcname))) |
diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el index 01c0ff2c76e..3d8dedc6bae 100644 --- a/lisp/eshell/esh-util.el +++ b/lisp/eshell/esh-util.el | |||
| @@ -36,6 +36,14 @@ | |||
| 36 | 36 | ||
| 37 | ;;; User Variables: | 37 | ;;; User Variables: |
| 38 | 38 | ||
| 39 | (defcustom eshell-stringify-t t | ||
| 40 | "*If non-nil, the string representation of t is 't'. | ||
| 41 | If nil, t will be represented only in the exit code of the function, | ||
| 42 | and not printed as a string. This causes Lisp functions to behave | ||
| 43 | similarly to external commands, as far as successful result output." | ||
| 44 | :type 'boolean | ||
| 45 | :group 'eshell-util) | ||
| 46 | |||
| 39 | (defcustom eshell-group-file "/etc/group" | 47 | (defcustom eshell-group-file "/etc/group" |
| 40 | "*If non-nil, the name of the group file on your system." | 48 | "*If non-nil, the name of the group file on your system." |
| 41 | :type '(choice (const :tag "No group file" nil) file) | 49 | :type '(choice (const :tag "No group file" nil) file) |
| @@ -305,7 +313,9 @@ If N or M is nil, it means the end of the list." | |||
| 305 | ((numberp object) | 313 | ((numberp object) |
| 306 | (number-to-string object)) | 314 | (number-to-string object)) |
| 307 | (t | 315 | (t |
| 308 | (pp-to-string object)))) | 316 | (unless (and (eq object t) |
| 317 | (not eshell-stringify-t)) | ||
| 318 | (pp-to-string object))))) | ||
| 309 | 319 | ||
| 310 | (defsubst eshell-stringify-list (args) | 320 | (defsubst eshell-stringify-list (args) |
| 311 | "Convert each element of ARGS into a string value." | 321 | "Convert each element of ARGS into a string value." |
| @@ -611,7 +621,7 @@ Unless optional argument INPLACE is non-nil, return a new string." | |||
| 611 | (autoload 'parse-time-string "parse-time")) | 621 | (autoload 'parse-time-string "parse-time")) |
| 612 | 622 | ||
| 613 | (eval-when-compile | 623 | (eval-when-compile |
| 614 | (require 'ange-ftp)) | 624 | (load "ange-ftp" t)) |
| 615 | 625 | ||
| 616 | (defun eshell-parse-ange-ls (dir) | 626 | (defun eshell-parse-ange-ls (dir) |
| 617 | (let (entry) | 627 | (let (entry) |
diff --git a/lisp/textmodes/flyspell.el b/lisp/textmodes/flyspell.el index fe95b3faa59..74c07f19602 100644 --- a/lisp/textmodes/flyspell.el +++ b/lisp/textmodes/flyspell.el | |||
| @@ -1986,7 +1986,7 @@ The word checked is the word at the mouse position." | |||
| 1986 | menu)))) | 1986 | menu)))) |
| 1987 | 1987 | ||
| 1988 | ;*---------------------------------------------------------------------*/ | 1988 | ;*---------------------------------------------------------------------*/ |
| 1989 | ;* Some example functions for real autocrrecting */ | 1989 | ;* Some example functions for real autocrrecting xb */ |
| 1990 | ;*---------------------------------------------------------------------*/ | 1990 | ;*---------------------------------------------------------------------*/ |
| 1991 | (defun flyspell-maybe-correct-transposition (beg end poss) | 1991 | (defun flyspell-maybe-correct-transposition (beg end poss) |
| 1992 | "Apply 'transpose-chars' to all points in the region BEG to END and | 1992 | "Apply 'transpose-chars' to all points in the region BEG to END and |
| @@ -1994,17 +1994,24 @@ return t if any those result in a possible replacement suggested by ispell | |||
| 1994 | in POSS. Otherwise the change is undone. | 1994 | in POSS. Otherwise the change is undone. |
| 1995 | 1995 | ||
| 1996 | This function is meant to be added to 'flyspell-incorrect-hook'." | 1996 | This function is meant to be added to 'flyspell-incorrect-hook'." |
| 1997 | (when (consp poss) | 1997 | (when (consp poss) |
| 1998 | (catch 'done | 1998 | (catch 'done |
| 1999 | (save-excursion | 1999 | (let ((str (buffer-substring beg end)) |
| 2000 | (goto-char (1+ beg)) | 2000 | (i 0) (len (- end beg)) tmp) |
| 2001 | (while (< (point) end) | 2001 | (while (< (1+ i) len) |
| 2002 | (transpose-chars 1) | 2002 | (setq tmp (aref str i)) |
| 2003 | (when (member (buffer-substring beg end) (nth 2 poss)) | 2003 | (aset str i (aref str (1+ i))) |
| 2004 | (throw 'done t)) | 2004 | (aset str (1+ i) tmp) |
| 2005 | (transpose-chars -1) | 2005 | (when (member str (nth 2 poss)) |
| 2006 | (forward-char)) | 2006 | (save-excursion |
| 2007 | nil)))) | 2007 | (goto-char (+ beg i 1)) |
| 2008 | (transpose-chars 1)) | ||
| 2009 | (throw 'done t)) | ||
| 2010 | (setq tmp (aref str i)) | ||
| 2011 | (aset str i (aref str (1+ i))) | ||
| 2012 | (aset str (1+ i) tmp) | ||
| 2013 | (setq i (1+ i)))) | ||
| 2014 | nil))) | ||
| 2008 | 2015 | ||
| 2009 | (defun flyspell-maybe-correct-doubling (beg end poss) | 2016 | (defun flyspell-maybe-correct-doubling (beg end poss) |
| 2010 | "For each doubled charachter in the region BEG to END, remove one and | 2017 | "For each doubled charachter in the region BEG to END, remove one and |
| @@ -2014,21 +2021,18 @@ in POSS. Otherwise the change is undone. | |||
| 2014 | This function is meant to be added to 'flyspell-incorrect-hook'." | 2021 | This function is meant to be added to 'flyspell-incorrect-hook'." |
| 2015 | (when (consp poss) | 2022 | (when (consp poss) |
| 2016 | (catch 'done | 2023 | (catch 'done |
| 2017 | (save-excursion | 2024 | (let ((str (buffer-substring beg end)) |
| 2018 | (let ((last (char-after beg)) | 2025 | (i 0) (len (- end beg))) |
| 2019 | this) | 2026 | (while (< (1+ i) len) |
| 2020 | (goto-char (1+ beg)) | 2027 | (when (and (= (aref str i) (aref str (1+ i))) |
| 2021 | (while (< (point) end) | 2028 | (member (concat (substring str 0 (1+ i)) |
| 2022 | (setq this (char-after)) | 2029 | (substring str (+ i 2))) |
| 2023 | (if (not (char-equal this last)) | 2030 | (nth 2 poss))) |
| 2024 | (forward-char) | 2031 | (goto-char (+ beg i)) |
| 2025 | (delete-char 1) | 2032 | (delete-char 1) |
| 2026 | (when (member (buffer-substring beg (1- end)) (nth 2 poss)) | 2033 | (throw 'done t)) |
| 2027 | (throw 'done t)) | 2034 | (setq i (1+ i)))) |
| 2028 | ;; undo | 2035 | nil))) |
| 2029 | (insert-char this 1)) | ||
| 2030 | (setq last this)) | ||
| 2031 | nil))))) | ||
| 2032 | 2036 | ||
| 2033 | ;*---------------------------------------------------------------------*/ | 2037 | ;*---------------------------------------------------------------------*/ |
| 2034 | ;* flyspell-already-abbrevp ... */ | 2038 | ;* flyspell-already-abbrevp ... */ |
diff --git a/man/ChangeLog b/man/ChangeLog index 7ad93bc9864..fb8a6adcd75 100644 --- a/man/ChangeLog +++ b/man/ChangeLog | |||
| @@ -1,3 +1,7 @@ | |||
| 1 | 2000-10-28 John Wiegley <johnw@gnu.org> | ||
| 2 | |||
| 3 | * eshell.texi: Further editing, and finished the "bugs" section. | ||
| 4 | |||
| 1 | 2000-10-28 Eli Zaretskii <eliz@is.elta.co.il> | 5 | 2000-10-28 Eli Zaretskii <eliz@is.elta.co.il> |
| 2 | 6 | ||
| 3 | * cmdargs.texi (Colors X): Document support for -fg, -bg, and -rv | 7 | * cmdargs.texi (Colors X): Document support for -fg, -bg, and -rv |
diff --git a/man/eshell.texi b/man/eshell.texi index de91933f2a4..c690909a94c 100644 --- a/man/eshell.texi +++ b/man/eshell.texi | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | \input texinfo @c -*-texinfo-*- | 1 | \input texinfo @c -*-texinfo-*- |
| 2 | 2 | ||
| 3 | @c "@(#)$Name: $:$Id: eshell.texi,v 1.2 2000/10/13 10:32:23 johnw Exp $" | 3 | @c "@(#)$Name: $:$Id: eshell.texi,v 1.3 2000/10/16 18:24:30 eliz Exp $" |
| 4 | 4 | ||
| 5 | @c Documentation for Eshell: The Emacs Shell. | 5 | @c Documentation for Eshell: The Emacs Shell. |
| 6 | @c Copyright (C) 1999-2000 Free Software Foundation, Inc. | 6 | @c Copyright (C) 1999-2000 Free Software Foundation, Inc. |
| @@ -28,7 +28,7 @@ | |||
| 28 | 28 | ||
| 29 | @dircategory Emacs | 29 | @dircategory Emacs |
| 30 | @direntry | 30 | @direntry |
| 31 | * Eshell: (eshell). A command shell implemented in Emacs Lisp. | 31 | * Eshell: (eshell). A command shell implemented in Emacs Lisp. |
| 32 | @end direntry | 32 | @end direntry |
| 33 | @setchapternewpage on | 33 | @setchapternewpage on |
| 34 | 34 | ||
| @@ -72,7 +72,7 @@ Software Foundation instead of in the original English. | |||
| 72 | @center @titlefont{Eshell: The Emacs Shell} | 72 | @center @titlefont{Eshell: The Emacs Shell} |
| 73 | @ignore | 73 | @ignore |
| 74 | @sp 2 | 74 | @sp 2 |
| 75 | @center release 2.3.2 | 75 | @center release 2.4 |
| 76 | @c -release- | 76 | @c -release- |
| 77 | @end ignore | 77 | @end ignore |
| 78 | @sp 3 | 78 | @sp 3 |
| @@ -114,18 +114,19 @@ Software Foundation instead of in the original English. | |||
| 114 | @top Eshell | 114 | @top Eshell |
| 115 | 115 | ||
| 116 | This manual documents Eshell, a shell-like command interpretor | 116 | This manual documents Eshell, a shell-like command interpretor |
| 117 | implemented entirely in Emacs Lisp. It invokes no external processes | 117 | implemented in Emacs Lisp. It invokes no external processes except for |
| 118 | beyond those requested by the user. It is intended to be a functional | 118 | those requested by the user. It is intended to be a functional |
| 119 | replacement for command shells such as @command{bash}, @command{zsh}, | 119 | replacement for command shells such as @command{bash}, @command{zsh}, |
| 120 | @command{rc}, @command{4dos}; since Emacs itself is capable of handling | 120 | @command{rc}, or @command{4dos}; since Emacs itself is capable of |
| 121 | most of the tasks accomplished by such tools. | 121 | handling the sort of tasks accomplished by those tools. |
| 122 | @c This manual is updated to release 2.3.2 of Eshell. | 122 | @c This manual is updated to release 2.4 of Eshell. |
| 123 | @end ifinfo | 123 | @end ifinfo |
| 124 | 124 | ||
| 125 | @menu | 125 | @menu |
| 126 | * What is Eshell?:: A brief introduction to the Emacs Shell. | 126 | * What is Eshell?:: A brief introduction to the Emacs Shell. |
| 127 | * Installation:: | 127 | * Installation:: For users of Emacs 20 and XEmacs. |
| 128 | * Bugs and ideas:: | 128 | * Command basics:: The basics of command usage. |
| 129 | * Bugs and ideas:: Known problems, and future ideas. | ||
| 129 | * Concept Index:: | 130 | * Concept Index:: |
| 130 | * Function and Variable Index:: | 131 | * Function and Variable Index:: |
| 131 | * Key Index:: | 132 | * Key Index:: |
| @@ -136,12 +137,12 @@ most of the tasks accomplished by such tools. | |||
| 136 | @cindex what is Eshell? | 137 | @cindex what is Eshell? |
| 137 | @cindex Eshell, what it is | 138 | @cindex Eshell, what it is |
| 138 | 139 | ||
| 139 | Eshell is a @dfn{command shell} written using Emacs Lisp. All of what it does | 140 | Eshell is a @dfn{command shell} written in Emacs Lisp. Everything it |
| 140 | it uses Emacs' facilities to do. This means Eshell is as portable as | 141 | does it uses Emacs' facilities to do. This means that Eshell is as |
| 141 | Emacs itself. It also means that cooperation with other Lisp code is | 142 | portable as Emacs itself. It also means that cooperation with Lisp code |
| 142 | natural and seamless. | 143 | is natural and seamless. |
| 143 | 144 | ||
| 144 | So what is a command shell? To properly understand the role of a shell, | 145 | What is a command shell? To properly understand the role of a shell, |
| 145 | it's necessary to visualize what a computer does for you. Basically, a | 146 | it's necessary to visualize what a computer does for you. Basically, a |
| 146 | computer is a tool; in order to use that tool, you must tell it what to | 147 | computer is a tool; in order to use that tool, you must tell it what to |
| 147 | do---or give it ``commands''. These commands take many forms, such as | 148 | do---or give it ``commands''. These commands take many forms, such as |
| @@ -149,22 +150,22 @@ clicking with a mouse on certain parts of the screen. But that is only | |||
| 149 | one form of command input. | 150 | one form of command input. |
| 150 | 151 | ||
| 151 | By far the most versatile way to express what you want the computer to | 152 | By far the most versatile way to express what you want the computer to |
| 152 | do is using an abbreviated language, called @dfn{a script}. In a | 153 | do is by using an abbreviated language called @dfn{script}. In script, |
| 153 | script, instead | 154 | instead of telling the computer, ``list my files, please'', one writes |
| 154 | of telling the computer, ``list my files, please'', we write just | 155 | just ``list''. In fact, this command is so commonly used that it is |
| 155 | ``list''. In fact, this command is so commonly used that we abbreviate | 156 | abbreviated to ``ls''. Typing @kbd{ls} in a command shell is a script |
| 156 | it to ``ls''. Typing @kbd{ls} in a command shell is a script way of | 157 | way of telling the computer to list your files.@footnote{This is |
| 157 | telling the computer to list your files. This is comparable to viewing | 158 | comparable to viewing the contents of a folder using a graphical |
| 158 | the contents of a folder using a graphical display. | 159 | display.} |
| 159 | 160 | ||
| 160 | The real flexibility is apparent only when you realize that there are | 161 | The real flexibility of this approach is apparent only when you realize |
| 161 | many, many ways to list your files. Perhaps you want them sorted by | 162 | that there are many, many different ways to list files. Perhaps you |
| 162 | name, or sorted by date, or in reverse order, or grouped by type. Most | 163 | want them sorted by name, sorted by date, in reverse order, or grouped |
| 163 | graphical browsers have simple ways to express this. But what about | 164 | by type. Most graphical browsers have simple ways to express this. But |
| 164 | showing only a few files, or only files that meet a certain criteria? | 165 | what about showing only a few files, or only files that meet a certain |
| 165 | In very complex and specific situations, the request becomes too | 166 | criteria? In very complex and specific situations, the request becomes |
| 166 | difficult to express with a mouse. It is just these kinds of requests | 167 | too difficult to express using a mouse or pointing device. It is just |
| 167 | that are solvable using a command shell. | 168 | these kinds of requests that are easily solved using a command shell. |
| 168 | 169 | ||
| 169 | For example, what if you want to list every Word file on your hard | 170 | For example, what if you want to list every Word file on your hard |
| 170 | drive, larger than 100 kilobytes in size, and which hasn't been looked | 171 | drive, larger than 100 kilobytes in size, and which hasn't been looked |
| @@ -173,13 +174,13 @@ you go to clean up your hard drive. But have you ever tried asking your | |||
| 173 | computer for such a list? There is no way to do it! At least, not | 174 | computer for such a list? There is no way to do it! At least, not |
| 174 | without using a command shell. | 175 | without using a command shell. |
| 175 | 176 | ||
| 176 | So the role of a command shell is to give you more control over what | 177 | The role of a command shell is to give you more control over what your |
| 177 | your computer does for you. Not everyone needs this amount of control, | 178 | computer does for you. Not everyone needs this amount of control, and |
| 178 | and it does come at a cost: Learning the necessary script commands to | 179 | it does come at a cost: Learning the necessary script commands to |
| 179 | express what you want done. A complicated query, such as the example | 180 | express what you want done. A complicated query, such as the example |
| 180 | above, takes time to learn. But if you find yourself using your | 181 | above, takes time to learn. But if you find yourself using your |
| 181 | computer frequently enough, it is more than worthwhile in the long run. | 182 | computer frequently enough, it is more than worthwhile in the long run. |
| 182 | Any tool you use often deserves your time in learning to master it. | 183 | Any tool you use often deserves the time spent learning to master it. |
| 183 | @footnote{For the understandably curious, here is what that command | 184 | @footnote{For the understandably curious, here is what that command |
| 184 | looks like: But don't let it fool you; once you know what's going on, | 185 | looks like: But don't let it fool you; once you know what's going on, |
| 185 | it's easier than it looks: @code{ls -lt **/*.doc(Lk+50aM+5)}.} | 186 | it's easier than it looks: @code{ls -lt **/*.doc(Lk+50aM+5)}.} |
| @@ -187,10 +188,10 @@ it's easier than it looks: @code{ls -lt **/*.doc(Lk+50aM+5)}.} | |||
| 187 | As of Emacs 21, Eshell is part of the standard Emacs distribution. | 188 | As of Emacs 21, Eshell is part of the standard Emacs distribution. |
| 188 | 189 | ||
| 189 | @menu | 190 | @menu |
| 190 | * Contributors to Eshell:: | 191 | * Contributors to Eshell:: People who have helped out! |
| 191 | @end menu | 192 | @end menu |
| 192 | 193 | ||
| 193 | @node Contributors to Eshell, , What is Eshell?, What is Eshell? | 194 | @node Contributors to Eshell, , What is Eshell?, What is Eshell? |
| 194 | @section Contributors to Eshell | 195 | @section Contributors to Eshell |
| 195 | @cindex contributors | 196 | @cindex contributors |
| 196 | @cindex authors | 197 | @cindex authors |
| @@ -230,16 +231,16 @@ Apart from these, a lot of people have sent suggestions, ideas, | |||
| 230 | requests, bug reports and encouragement. Thanks a lot! Without you | 231 | requests, bug reports and encouragement. Thanks a lot! Without you |
| 231 | there would be no new releases of Eshell. | 232 | there would be no new releases of Eshell. |
| 232 | 233 | ||
| 233 | @node Installation, Bugs and ideas, What is Eshell?, Top | 234 | @node Installation, Command basics, What is Eshell?, Top |
| 234 | @chapter Installation | 235 | @chapter Installation |
| 235 | @cindex installation | 236 | @cindex installation |
| 236 | 237 | ||
| 237 | As mentioned above, Eshell comes preinstalled since Emacs 21. If you're | 238 | As mentioned above, Eshell comes preinstalled as of Emacs 21. If you're |
| 238 | using Emacs 20.4 or later, or XEmacs 21, you can download the most | 239 | using Emacs 20.4 or later, or XEmacs 21, you can download the most |
| 239 | recent version of Eshell from | 240 | recent version of Eshell from |
| 240 | @url{http://www.gci-net.com/users/j/johnw/Emacs/eshell.tar.gz}. | 241 | @url{http://www.gci-net.com/users/j/johnw/Emacs/eshell.tar.gz}. |
| 241 | 242 | ||
| 242 | If you are using Emacs 21, please skip this section. | 243 | However, if you are using Emacs 21, you may skip this section. |
| 243 | 244 | ||
| 244 | @section Short Form | 245 | @section Short Form |
| 245 | 246 | ||
| @@ -420,57 +421,70 @@ you can use. For other printers, use a suitable DVI driver, | |||
| 420 | e.g., @code{dvilj4} for LaserJet-compatible printers. | 421 | e.g., @code{dvilj4} for LaserJet-compatible printers. |
| 421 | @end enumerate | 422 | @end enumerate |
| 422 | 423 | ||
| 423 | @c @node Forming commands, Known problems, What is Eshell?, Top | 424 | @node Command basics, Bugs and ideas, Installation, Top |
| 424 | @c @chapter Forming commands | 425 | @chapter Command basics |
| 425 | 426 | ||
| 426 | @c A command shell is nothing more than a place to enter commands. | 427 | A command shell is a mechanism for entering verbally-formed commands. |
| 428 | This is really all that it does, and every feature described in this | ||
| 429 | manual is a means to that end. Therefore, it's important to get a firm | ||
| 430 | grasp on exactly what a command is, and how it fits into the overall | ||
| 431 | picture of things. | ||
| 427 | 432 | ||
| 428 | @c What is a command? | 433 | @menu |
| 434 | * Commands verbs:: Commands always begin with a verb. | ||
| 435 | * Command arguments:: Some verbs require arguments. | ||
| 436 | @end menu | ||
| 437 | |||
| 438 | @node Commands verbs, Command arguments, Command basics, Command basics | ||
| 439 | @section Commands verbs | ||
| 429 | 440 | ||
| 430 | @c A command is piece of ``script''---or special shorthand | 441 | Commands are expressed using @dfn{script}, a special shorthand language |
| 431 | @c language---that the computer can understand. | 442 | that computers can understand without trouble. |
| 432 | 443 | ||
| 433 | @c What does script look like? | 444 | Script is an extremely simplified language. Oddly enough, this actually |
| 445 | makes it look more complicated than it is. Whereas normal languages use | ||
| 446 | a variety of embellishments, the form of a script command is always: | ||
| 434 | 447 | ||
| 435 | @c Script is an extremely simplified language. Oddly enough, this | 448 | @example |
| 436 | @c actually makes it look more complicated than it is. Whereas normal | 449 | VERB [ARGUMENTS] |
| 437 | @c languages can use many different embellishments, the form of a script | 450 | @end example |
| 438 | @c command is always: a command verb, following by its arguments. | ||
| 439 | 451 | ||
| 440 | @c A verb? Arguments? | 452 | The verb expresses what you want your computer to do. There are a fixed |
| 453 | number of verbs, although this number is usually quite large. On the | ||
| 454 | author's computer, it reaches almost 1400 in number. But of course, | ||
| 455 | only a handful of these are really necessary. | ||
| 441 | 456 | ||
| 442 | @c The verb is the thing you want your computer to do. There are a set | 457 | Sometimes, the verb is all that's written. A verb is always a single |
| 443 | @c number of verbs, although this number is quite large. On my | 458 | word, usually related to the task it will perform. @command{reboot} is |
| 444 | @c computer, it reaches almost 1400 in number! But of course, only a | 459 | a good example. Entering that will cause your computer to reboot, |
| 445 | @c handful of these are necessary most of the time. | 460 | assuming you have sufficient privileges. |
| 446 | 461 | ||
| 447 | @c Sometimes, the verb is all that's necessary. A verb is always a | 462 | Other verbs require more information. These are usually very capable of |
| 448 | @c single word, usually related to the task it will perform. | 463 | verbs, and must be told more specifically what to do. This extra |
| 449 | @c @command{reboot} is a good example. Entering that will cause your | 464 | information is given in the form of arguments. Arguments are also |
| 450 | @c computer to reboot, assuming you have sufficient privileges. | 465 | single words, that appear after the verb. For example, @command{echo} |
| 466 | is a command verb that prints back whatever you say. @command{echo} | ||
| 467 | requires arguments, so that it knows what to echo. A proper use of | ||
| 468 | @command{echo} looks like this: | ||
| 451 | 469 | ||
| 452 | @c Other verbs need more information. These are usually very capable of | 470 | @example |
| 453 | @c verbs, but they must be told more specifically what to do. This | 471 | echo This is an example of using echo! |
| 454 | @c extra information is given in the form of arguments. Arguments are | 472 | @end example |
| 455 | @c also words, that appear after the verb. For example, @command{echo} | ||
| 456 | @c is a command verb that will print back to you whatever you say. | ||
| 457 | @c @command{echo} requires a set of arguments, to know what you want it | ||
| 458 | @c to echo! So a proper use of echo might look like: | ||
| 459 | 473 | ||
| 460 | @c @example | 474 | This piece of script expresses a command that causes the computer to |
| 461 | @c echo This is an example of using echo! | 475 | print back: ``This is an example of using echo!''. |
| 462 | @c @end example | ||
| 463 | 476 | ||
| 464 | @c This command would result in the computer printing back to you, | 477 | Although command verbs always take the form of simple words, such as |
| 465 | @c ``This is an example of using echo!''. Pretty easy, no? | 478 | @command{reboot} and @command{echo}, arguments have a wide vaierty of |
| 479 | forms. There are textual arguments, numerical arguments---even Lisp | ||
| 480 | arguments. Distinguishing between these different types of arguments | ||
| 481 | requires special typing, since the computer needs to know exactly what | ||
| 482 | you mean. | ||
| 466 | 483 | ||
| 467 | @c Although commands are always simple words, arguments can take | 484 | @node Command arguments, , Commands verbs, Command basics |
| 468 | @c different forms. There are textual arguments, numeric arguments, | 485 | @section Command arguments |
| 469 | @c even Lisp arguments. Distinguishing among these different types of | ||
| 470 | @c arguments requires some special typing, because the computer needs | ||
| 471 | @c very specific directions to understand what you mean. | ||
| 472 | 486 | ||
| 473 | @node Bugs and ideas, Concept Index, Installation, Top | 487 | @node Bugs and ideas, Concept Index, Command basics, Top |
| 474 | @chapter Bugs and ideas | 488 | @chapter Bugs and ideas |
| 475 | @cindex reporting bugs and ideas | 489 | @cindex reporting bugs and ideas |
| 476 | @cindex bugs, how to report them | 490 | @cindex bugs, how to report them |
| @@ -498,10 +512,19 @@ find this package useful! | |||
| 498 | @cindex bugs, known | 512 | @cindex bugs, known |
| 499 | 513 | ||
| 500 | Below is a partial list of currently known problems with Eshell version | 514 | Below is a partial list of currently known problems with Eshell version |
| 501 | 2.3.2, which is the version distributed with Emacs 21.1. | 515 | 2.4, which is the version distributed with Emacs 21.1. |
| 502 | 516 | ||
| 503 | @table @asis | 517 | @table @asis |
| 504 | @item @samp{for i in 1 2 3 @{ grep -q a b && *echo has it @} | wc -l} fails | 518 | @item Differentiate between aliases and functions |
| 519 | |||
| 520 | Allow for a bash-compatible syntax, such as: | ||
| 521 | |||
| 522 | @example | ||
| 523 | alias arg=blah | ||
| 524 | function arg () { blah $* } | ||
| 525 | @end example | ||
| 526 | |||
| 527 | @item @samp{for i in 1 2 3 @{ grep -q a b && *echo has it @} | wc -l} outputs result after prompt | ||
| 505 | 528 | ||
| 506 | In fact, piping to a process from a looping construct doesn't work in | 529 | In fact, piping to a process from a looping construct doesn't work in |
| 507 | general. If I change the call to @code{eshell-copy-handles} in | 530 | general. If I change the call to @code{eshell-copy-handles} in |
| @@ -514,11 +537,6 @@ structured command thing is too complicated at present. | |||
| 514 | On some XEmacs system, the subprocess interaction test fails | 537 | On some XEmacs system, the subprocess interaction test fails |
| 515 | inexplicably, although @command{bc} works fine at the command prompt. | 538 | inexplicably, although @command{bc} works fine at the command prompt. |
| 516 | 539 | ||
| 517 | @item @command{ls} in remote directories sometimes fails | ||
| 518 | |||
| 519 | For XEmacs users, using @command{ls} in a remote directory sometimes | ||
| 520 | fails. The reason why has not yet been found. | ||
| 521 | |||
| 522 | @item Eshell does not delete @file{*Help*} buffers in XEmacs 21.1.8+ | 540 | @item Eshell does not delete @file{*Help*} buffers in XEmacs 21.1.8+ |
| 523 | 541 | ||
| 524 | In XEmacs 21.1.8, the @file{*Help*} buffer has been renamed such that | 542 | In XEmacs 21.1.8, the @file{*Help*} buffer has been renamed such that |
| @@ -563,266 +581,385 @@ since. | |||
| 563 | 581 | ||
| 564 | Make it so that the Lisp command on the right of the pipe is repeatedly | 582 | Make it so that the Lisp command on the right of the pipe is repeatedly |
| 565 | called with the input strings as arguments. This will require changing | 583 | called with the input strings as arguments. This will require changing |
| 566 | eshell-do-pipeline to handle non-process targets. | 584 | @code{eshell-do-pipeline} to handle non-process targets. |
| 567 | 585 | ||
| 568 | @item Input redirection is not supported | 586 | @item Input redirection is not supported |
| 569 | 587 | ||
| 570 | See the entry above. | 588 | See the above entry. |
| 571 | 589 | ||
| 572 | @c @item problem running "less" without argument on Windows | 590 | @item Problem running @command{less} without argument on Windows |
| 573 | @c Before running telnet, I noticed that 'less' (for example) was already | 591 | |
| 574 | @c configured as a visual command. So I invoked it from eshell to see what | 592 | The result in the Eshell buffer is: |
| 575 | @c would happen. | 593 | |
| 576 | @c | 594 | @example |
| 577 | @c Here's the result in the eshell buffer: | 595 | Spawning child process: invalid argument |
| 578 | @c | 596 | @end example |
| 579 | @c Spawning child process: invalid argument | 597 | |
| 580 | @c | 598 | Also a new @command{less} buffer was created with nothing in it@dots{} |
| 581 | @c Also a new 'less' buffer was created with nothing in it .. (presumably this | 599 | (presumably this holds the output of @command{less}). |
| 582 | @c holds the output of less) | 600 | |
| 583 | @c | 601 | If @command{less.exe} is invoked from the Eshell command line, the |
| 584 | @c If I run 'less.exe' from the eshell command line, I get the output I expect | 602 | expected output is written to the buffer. |
| 585 | @c simply written to the buffer. | 603 | |
| 586 | @c | 604 | Note that this happens on NT-Emacs 20.6.1 on Win2000. The term.el |
| 587 | @c Note that I'm using FSF NT-Emacs 20.6.1 on Win2000. The term.el package and | 605 | package and the supplied shell both use the @command{cmdproxy} for |
| 588 | @c the supplied shell both seem to use the 'cmdproxy' program to run things | 606 | running shells. |
| 589 | @c like shells. | 607 | |
| 590 | @c @item implement -r, -n and -s switches for cp | 608 | @item Implement @samp{-r}, @samp{-n} and @samp{-s} switches for @command{cp} |
| 591 | @c @item Make M-5 eshell -> switch to *eshell<5>*, creating it if need be | 609 | |
| 592 | @c @item mv DIR FILE.tar does not remove directories | 610 | @item Make @kbd{M-5 M-x eshell} switch to ``*eshell<5>*'', creating if need be |
| 593 | @c This is because the tar option --remove-files doesn't do so. Should | 611 | |
| 594 | @c it be Eshell's job? | 612 | @item @samp{mv DIR FILE.tar} does not remove directories |
| 595 | @c @item Write an article about Eshell for the LinuxWorld journal. | 613 | |
| 596 | @c @item bind standard-output and standard-error, so that if a Lisp function | 614 | This is because the tar option --remove-files doesn't do so. Should it |
| 597 | @c calls `print', everything will happen as it should (albeit slowly) | 615 | be Eshell's job? |
| 598 | @c @item when the extension modules fail to load, cd / gives a Lisp error | 616 | |
| 599 | @c @item if a globbing patterns returns only one match, should it still be a | 617 | @item Bind @code{standard-output} and @code{standard-error} |
| 600 | @c list? | 618 | |
| 601 | @c @item make sure that the syntax table correctly in eshell mode | 619 | This would be so that if a Lisp function calls @code{print}, everything |
| 602 | @c So that M-DEL acts in a predictable manner, etc. | 620 | will happen as it should (albeit slowly). |
| 603 | @c @item allow all Eshell buffers to share the same history and list-dir | 621 | |
| 604 | @c @item error with script commands and outputting to /dev/null | 622 | @item When an extension module fails to load, @samp{cd /} gives a Lisp error |
| 605 | @c If a script file, somewhere in the middle, does a "> /dev/null", | 623 | |
| 606 | @c output from all subsequent commands will be swallowed | 624 | @item If a globbing pattern returns one match, should it be a list? |
| 607 | @c @item split up parsing of the text after a $ in eshell-var | 625 | |
| 608 | @c Similar to way that eshell-arg is structured. Then add parsing of | 626 | @item Make sure syntax table is correct in Eshell mode |
| 609 | @c $[?\n] | 627 | |
| 610 | @c @item after pressing M-RET, redisplay before running the next command | 628 | So that @kbd{M-DEL} acts in a predictable manner, etc. |
| 611 | @c @item argument predicates and modifiers should work anywhere in a path | 629 | |
| 612 | @c /usr/local/src/editors/vim $ vi **/CVS(/)/Root(.) | 630 | @item Allow all Eshell buffers to share the same history and list-dir |
| 613 | @c Invalid regexp: "Unmatched ( or \\(" | 631 | |
| 614 | @c | 632 | @item There is a problem with script commands that output to @file{/dev/null} |
| 615 | @c with zsh, the glob above expands to all files named Root in | 633 | |
| 616 | @c directories named CVS. | 634 | If a script file, somewhere in the middle, uses @samp{> /dev/null}, |
| 617 | @c @item typing "echo ${locate locate}/bin<tab>" results in a Lisp error | 635 | output from all subsequent commands is swallowed. |
| 618 | @c Perhaps it should interpolate all permutations, and make that the | 636 | |
| 619 | @c globbing result, since otherwise hitting return here will result in | 637 | @item Split up parsing of text after @samp{$} in @file{esh-var.el} |
| 620 | @c "(list of filenames)/bin", which is never very valuable. Thus, one | 638 | |
| 621 | @c could cat only c backup files by using "ls ${identity *.c}~". In that | 639 | Make it similar to the way that @file{esh-arg.el} is structured. |
| 622 | @c case, having an alias command name `glob' for `identity' would be | 640 | Then add parsing of @samp{$[?\n]}. |
| 623 | @c useful | 641 | |
| 624 | @c @item for XEmacs on Win32, fix `file-name-all-completions' | 642 | @item After pressing @kbd{M-RET}, redisplay before running the next command |
| 625 | @c Make sure it returns directory names terminated by | 643 | |
| 626 | @c `directory-sep-char' (which is initialized to be ?/), rather than | 644 | @item Argument predicates and modifiers should work anywhere in a path |
| 627 | @c backslash | 645 | |
| 628 | @c @item once symbolic mode is supported for umask, implement chmod in Lisp | 646 | @example |
| 629 | @c @item create `eshell-expand-file-name' | 647 | /usr/local/src/editors/vim $ vi **/CVS(/)/Root(.) |
| 630 | @c Which uses a data table to transform things like "~+", "...", etc | 648 | Invalid regexp: "Unmatched ( or \\(" |
| 631 | @c @item abstract `eshell-smart.el' into `smart-scroll.el' | 649 | @end example |
| 632 | @c It only really needs: to be hooked onto the output filter and the | 650 | |
| 633 | @c pre-command hook, and to have the input-end and input-start markers. | 651 | With @command{zsh}, the glob above expands to all files named |
| 634 | @c And to know whether the last output group was "successful". | 652 | @file{Root} in directories named @file{CVS}. |
| 635 | @c @item allow for fully persisting the state of Eshell | 653 | |
| 636 | @c vars, history, buffer, input, dir stack, etc. | 654 | @item Typing @samp{echo ${locate locate}/bin<TAB>} results in a Lisp error |
| 637 | @c @item implement D in the predicate list | 655 | |
| 638 | @c It means that files beginning with a dot should be included in the | 656 | Perhaps it should interpolate all permutations, and make that the |
| 639 | @c glob match | 657 | globbing result, since otherwise hitting return here will result in |
| 640 | @c @item a comma in a predicate list means OR | 658 | ``(list of filenames)/bin'', which is never valuable. Thus, one could |
| 641 | @c @item error if a glob doesn't expand due to a predicate | 659 | @command{cat} only C backup files by using @samp{ls ${identity *.c}~}. |
| 642 | @c An error should be generated only if `eshell-error-if-no-glob' is | 660 | In that case, having an alias command name @command{glob} for |
| 643 | @c non-nil | 661 | @command{identity} would be useful. |
| 644 | @c @item the following doesn't cause an indent-according-to-mode to occur | 662 | |
| 645 | @c (+ RET SPC TAB | 663 | @item Fix `file-name-all-completions' for XEmacs on Win32 |
| 646 | @c @item create `eshell-auto-accumulate-list' | 664 | |
| 647 | @c It is a list of commands for which, if the user presses RET, the text | 665 | Make sure it returns directory names terminated by |
| 648 | @c gets staged as the next Eshell command, rather than being sent to the | 666 | @code{directory-sep-char} (which is initialized to be @samp{?/}), rather |
| 649 | @c current interactive | 667 | than backslash. |
| 650 | @c @item display file and line number if an error occurs in a script | 668 | |
| 651 | @c @item wait doesn't work with process ids at the moment | 669 | @item Once symbolic mode is supported for @command{umask}, implement @command{chmod} in Lisp |
| 652 | @c @item enable the direct-to-process input code in eshell-term.el | 670 | |
| 653 | @c @item problem with repeating "echo ${find /tmp}" | 671 | @item Create @code{eshell-expand-file-name} |
| 654 | @c With smart display active, if I hold down RET, after a while it can't | 672 | |
| 655 | @c keep up anymore and starts outputting blank lines. It only happens if | 673 | This would use a data table to transform things such as @samp{~+}, |
| 656 | @c an asynchronous process is involved... | 674 | @samp{...}, etc. |
| 657 | @c | 675 | |
| 658 | @c I think the problem is that `eshell-send-input' is resetting the input | 676 | @item Abstract @file{em-smart.el} into @file{smart-scroll.el} |
| 659 | @c target location, so that if the asynchronous process is not done by | 677 | |
| 660 | @c the time the next RET is received, the input processor thinks that the | 678 | It only really needs: to be hooked onto the output filter and the |
| 661 | @c input is meant for the process; which, because smart display is | 679 | pre-command hook, and to have the input-end and input-start markers. |
| 662 | @c enabled, will be the text of the last command line! That is a bug in | 680 | And to know whether the last output group was ``successful''. |
| 663 | @c itself. | 681 | |
| 664 | @c | 682 | @item Allow for fully persisting the state of Eshell |
| 665 | @c In holding down RET while an asynchronous process is running, there | 683 | |
| 666 | @c will be a point in between termination of the process, and the running | 684 | This would include: variables, history, buffer, input, dir stack, etc. |
| 667 | @c of eshell-post-command-hook, which would cause `eshell-send-input' to | 685 | |
| 668 | @c call `eshell-copy-old-input', and then process that text as a command | 686 | @item Implement D as an argument predicate |
| 669 | @c to be run after the process. Perhaps there should be a way of killing | 687 | |
| 670 | @c pending input between the death of the process, and the | 688 | It means that files beginning with a dot should be included in the |
| 671 | @c post-command-hook. | 689 | glob match. |
| 672 | @c @item allow for a more aggressive smart display mode | 690 | |
| 673 | @c Perhaps toggled by a command, that makes each output block a smart | 691 | @item A comma in a predicate list should mean OR |
| 674 | @c display block | 692 | |
| 675 | @c @item create more meta variables | 693 | At the moment, this is not supported. |
| 676 | @c $! -- the reason for the failure of the last disk command, or the text | 694 | |
| 677 | @c of the last Lisp error | 695 | @item Error if a glob doesn't expand due to a predicate |
| 678 | @c | 696 | |
| 679 | @c $= -- a special associate array, which can take references of the form | 697 | An error should be generated only if @code{eshell-error-if-no-glob} is |
| 680 | @c $=[REGEXP]. It also indexes into the directory ring | 698 | non-nil. |
| 681 | @c @item eshell scripts can't execute in the background | 699 | |
| 682 | @c @item support zsh's "Parameter Expansion" syntax, i.e. ${NAME:-VAL} | 700 | @item @samp{(+ RET SPC TAB} does not cause @code{indent-according-to-mode} to occur |
| 683 | @c @item write an `info' alias that can take arguments | 701 | |
| 684 | @c So that the user can enter "info chmod" | 702 | @item Create @code{eshell-auto-accumulate-list} |
| 685 | @c @item split off more generic code from Eshell | 703 | |
| 686 | @c parse-args.el --- parse a list of arguments | 704 | This is a list of commands for which, if the user presses @kbd{RET}, the |
| 687 | @c interpolate.el --- interpolate $variable $(lisp)... references | 705 | text is staged as the next Eshell command, rather than being sent to the |
| 688 | @c interp.el --- find which interpretor to run a script with | 706 | current interactive process. |
| 689 | @c sh-ring.el --- extend ring.el for persistant, searchable history | 707 | |
| 690 | @c zsh-glob.el --- zsh-style globbing and predicate/modifiers | 708 | @item Display file and line number if an error occurs in a script |
| 691 | @c smartdisp.el --- smart scrolling in input buffers | 709 | |
| 692 | @c egetopt.el --- `eshell-eval-using-options' | 710 | @item @command{wait} doesn't work with process ids at the moment |
| 693 | @c prompt.el --- code for outputting and navigating prompts | 711 | |
| 694 | @c cmd-rebind.el --- rebind certain keys in the input text | 712 | @item Enable the direct-to-process input code in @file{em-term.el} |
| 695 | @c unix.el --- provides Lispish UNIX command, such as unix-rm, etc. | 713 | |
| 696 | @c emacs-ls.el --- implementation of ls in Emacs Lisp | 714 | @item Problem with repeating @samp{echo $@{find /tmp@}} |
| 697 | @c texidoc.el | 715 | |
| 698 | @c pushd.el --- implementation of pushd/popd in Lisp | 716 | With smart display active, if @kbd{RET} is held down, after a while it |
| 699 | @c interface.el -- a mode for reading command-line input from the user | 717 | can't keep up anymore and starts outputting blank lines. It only |
| 700 | @c @item create a mode `eshell-browse' | 718 | happens if an asynchronous process is involved@dots{} |
| 701 | @c It would treat the Eshell buffer as a outline. Collapsing the outline | 719 | |
| 702 | @c hides all of the output text. Collapsing again would show only the | 720 | I think the problem is that @code{eshell-send-input} is resetting the |
| 703 | @c first command run in each directory | 721 | input target location, so that if the asynchronous process is not done |
| 704 | @c @item look through the Korn Shell book for feature ideas | 722 | by the time the next @kbd{RET} is received, the input processor thinks |
| 705 | @c @item allow other version of a file to be referenced by "file{rev}" | 723 | that the input is meant for the process; which, when smart display is |
| 706 | @c This would be expanded by `eshell-expand-file-name' | 724 | enabled, will be the text of the last command line! That is a bug in |
| 707 | @c @item print "You have new mail" when the "Mail" icon gets turned on | 725 | itself. |
| 708 | @c @item implement M-| | 726 | |
| 709 | @c @item implement input redirection | 727 | In holding down @kbd{RET} while an asynchronous process is running, |
| 710 | @c If it's a lisp function, input redirection implies "xargs" (in a | 728 | there will be a point in between termination of the process, and the |
| 711 | @c way..). And if input redirection is added, don't forget to update the | 729 | running of @code{eshell-post-command-hook}, which would cause |
| 712 | @c file-name-quote-list, and the delimiter list. | 730 | @code{eshell-send-input} to call @code{eshell-copy-old-input}, and then |
| 713 | @c @item allow #<WORD ARG> to be a generic syntax | 731 | process that text as a command to be run after the process. Perhaps |
| 714 | @c With the handling of "word" specified by an `eshell-special-alist'. | 732 | there should be a way of killing pending input between the death of the |
| 715 | @c @item in `eval-using-options', have a :complete tag | 733 | process, and the @code{post-command-hook}. |
| 716 | @c It would be used to provide completion rules for that command. Then | 734 | |
| 717 | @c the macro will automagically define the completion function | 735 | @item Allow for a more aggressive smart display mode |
| 718 | @c @item for `eshell-command-on-region', redirections apply to the result | 736 | |
| 719 | @c So that "+ > 'blah" will cause the result of the `+' (using input from | 737 | Perhaps toggled by a command, that makes each output block a smart |
| 720 | @c the current region) to be inserting in the symbol `blah'. | 738 | display block. |
| 721 | @c | 739 | |
| 722 | @c If a disk command is being invoked, the input is sent as standard | 740 | @item Create more meta variables |
| 723 | @c input, as if a "cat <region> |" were invoked. | 741 | |
| 724 | @c | 742 | @table @samp |
| 725 | @c If a lisp command, or an alias, is invoked, then: if the line has no | 743 | @item $! |
| 726 | @c ^J characters, it is divided by whitespace and passed as arguments to | 744 | The reason for the failure of the last disk command, or the text of the |
| 727 | @c the lisp function. Otherwise, it is divided at the ^J characters. | 745 | last Lisp error. |
| 728 | @c Thus, invoking `+' on a series of numbers will add them; `min' would | 746 | |
| 729 | @c display the smallest figure. | 747 | @item $= |
| 730 | @c @item write `eshell-script-mode' as a minor mode | 748 | A special associate array, which can take references of the form |
| 731 | @c It would provide syntax, abbrev, highlighting and indenting support | 749 | @samp{$=[REGEXP]}. It indexes into the directory ring. |
| 732 | @c like emacs-lisp-mode + shell-mode. | 750 | @end table |
| 733 | @c @item in the history mechanism, finish bash-style support | 751 | |
| 734 | @c For !n, !#, !:%, and !:1- as separate from !:1* | 752 | @item Eshell scripts can't execute in the background |
| 735 | @c @item support the -n command line option for "history" | 753 | |
| 736 | @c @item implement `fc' | 754 | @item Support zsh's ``Parameter Expansion'' syntax, i.e. @samp{$@{NAME:-VAL@}} |
| 737 | @c @item specifying a frame as a redirection target implies point's buffer | 755 | |
| 738 | @c @item implement ">FUNC-OR-FUNC-LIST" | 756 | @item Write an @command{info} alias that can take arguments |
| 739 | @c This would allow for an "output translator", that takes a function to | 757 | |
| 740 | @c modify output with, and the target. Devise a syntax that words well | 758 | So that the user can enter @samp{info chmod}, for example. |
| 741 | @c with pipes, and can accomodate multiple functions (i.e.,">'(upcase | 759 | |
| 742 | @c regexp-quote)" or ">'upcase"). | 760 | @item Create a mode @code{eshell-browse} |
| 743 | @c @item allow Eshell to read/write to/from standard input and output | 761 | |
| 744 | @c This would be optional, rather than always using the Eshell buffer. | 762 | It would treat the Eshell buffer as a outline. Collapsing the outline |
| 745 | @c This would allow it to be run from the command line. | 763 | hides all of the output text. Collapsing again would show only the |
| 746 | @c @item write a "help" command | 764 | first command run in each directory |
| 747 | @c It could even call subcommands with "--help" (or "-h" or "/?"). | 765 | |
| 748 | @c @item implement stty | 766 | @item Allow other revisions of a file to be referenced using @samp{file@{rev@}} |
| 749 | @c @item support rc's matching operator, "~ (list) regexp" | 767 | |
| 750 | @c @item implement "bg" and "fg" to edit `eshell-process-list' | 768 | This would be expanded by @code{eshell-expand-file-name} (see above). |
| 751 | @c Using "bg" on a process that is already in the background does | 769 | |
| 752 | @c nothing. Specifying redirection targets replaces (or adds) to the | 770 | @item Print ``You have new mail'' when the ``Mail'' icon is turned on |
| 753 | @c list current being used. | 771 | |
| 754 | @c @item have "jobs" print only the processes for the current eshell | 772 | @item Implement @kbd{M-|} for Eshell |
| 755 | @c @item how do I discover that a background process has requested input? | 773 | |
| 756 | @c @item support 2>&1 and >& and 2> and |& | 774 | @item Implement input redirection |
| 757 | @c The syntax table for parsing these should be customizable, such that | 775 | |
| 758 | @c the user could change it to use rc syntax: >[2=1]. | 776 | If it's a Lisp function, input redirection implies @command{xargs} (in a |
| 759 | @c @item allow $_[-1], which reads the last element of the array, etc. | 777 | way@dots{}). If input redirection is added, also update the |
| 760 | @c @item make $x[*] equal to listing out the full contents of x | 778 | @code{file-name-quote-list}, and the delimiter list. |
| 761 | @c Return them as a list, so that $_[*] is all the arguments of the last | 779 | |
| 762 | @c command. | 780 | @item Allow @samp{#<WORD ARG>} as a generic syntax |
| 763 | @c @item move ANSI code handling from `term' into `eshell-term' | 781 | |
| 764 | @c And make it possible for the user to send char-by-char to the | 782 | With the handling of @emph{word} specified by an |
| 765 | @c underlying process. Ultimately, I should be able to move away from | 783 | @code{eshell-special-alist}. |
| 766 | @c using term.el altogether, since everything but the ANSI code handling | 784 | |
| 767 | @c is already part of Eshell. Then, things would work correctly on Win32 | 785 | @item In @code{eshell-eval-using-options}, allow a @code{:complete} tag |
| 768 | @c as well (which doesn't have "/bin/sh", though term tries to use it) | 786 | |
| 769 | @c @item have other shell spawning commands be visual | 787 | It would be used to provide completion rules for that command. Then the |
| 770 | @c Make (su, bash, telnet, rlogin, rsh, etc.) be part of | 788 | macro will automagically define the completion function. |
| 771 | @c `eshell-visual-commands'. The only exception is if rsh/su/bash are | 789 | |
| 772 | @c simply being used to invoke a single command. Then, it should be | 790 | @item For @code{eshell-command-on-region}, apply redirections to the result |
| 773 | @c based on what that command is. | 791 | |
| 774 | @c @item create an alias "open" | 792 | So that @samp{+ > 'blah} would cause the result of the @code{+} (using |
| 775 | @c This will search for some way to open its argument (similar to opening | 793 | input from the current region) to be inserting into the symbol |
| 776 | @c a file in the Windows Explorer). Perhaps using ffap... | 794 | @code{blah}. |
| 777 | @c @item alias "read" to be the same as "open", except read-only | 795 | |
| 778 | @c @item write a "tail -f" alias which does a view-file | 796 | If an external command is being invoked, the input is sent as standard |
| 779 | @c I.e., it moves point to the end of the buffer, and then turns on | 797 | input, as if a @samp{cat <region> |} had been invoked. |
| 780 | @c auto-revert mode in that buffer at frequent intervals -- and a head | 798 | |
| 781 | @c alias which assums an upper limit of `eshell-maximum-line-length' | 799 | If a Lisp command, or an alias, is invoked, then if the line has no |
| 782 | @c characters per line. | 800 | newline characters, it is divided by whitespace and passed as arguments |
| 783 | @c @item make dgrep load dired, mark everything, then execute the A binding | 801 | to the Lisp function. Otherwise, it is divided at the newline |
| 784 | @c @item write emsh.c | 802 | characters. Thus, invoking @code{+} on a series of numbers will add |
| 785 | @c It just runs Emacs with the appropriate arguments to invoke eshell. | 803 | them; @code{min} would display the smallest figure, etc. |
| 786 | @c That way, it could be listed as a login shell. | 804 | |
| 787 | @c @item use an intangible PS2 string for multi-line input prompts | 805 | @item Write @code{eshell-script-mode} as a minor mode |
| 788 | @c @item auto-detect when a command is visual, by checking TERMCAP usage | 806 | |
| 789 | @c @item First keypress after M-x watson triggers `eshell-send-input' | 807 | It would provide syntax, abbrev, highlighting and indenting support like |
| 790 | @c @item Emacs 20.3: Figure out why pcomplete won't make | 808 | @code{emacs-lisp-mode} and @code{shell-mode}. |
| 791 | @c @item Make / electric | 809 | |
| 792 | @c So that it automatically expands and corrects pathnames. Or make | 810 | @item In the history mechanism, finish the @command{bash}-style support |
| 793 | @c pathname completion for pcomplete auto-expand "/u/i/std<TAB>" to | 811 | |
| 794 | @c "/usr/include/std<TAB>". | 812 | This means @samp{!n}, @samp{!#}, @samp{!:%}, and @samp{!:1-} as separate |
| 795 | @c @item Write pushd/popd out to disk along with last-dir-ring | 813 | from @samp{!:1*}. |
| 796 | @c @item add options to eshell/cat which would cause it to sort and uniq | 814 | |
| 797 | @c @item implement in Lisp: wc. Also count sentences, paragraphs, pages. | 815 | @item Support the -n command line option for @command{history} |
| 798 | @c @item once piping is added, implement sort and uniq | 816 | |
| 799 | @c @item implement touch | 817 | @item Implement @command{fc} in Lisp |
| 800 | @c @item implement epatch | 818 | |
| 801 | @c Calls ediff-patch-file, or ediff-patch-buffer, depending on its | 819 | @item Specifying a frame as a redirection target should imply the currently active window's buffer |
| 802 | @c argument. | 820 | |
| 803 | @c @item have an option for bringing up ls -l result in a dired buffer | 821 | @item Implement @samp{>FUNC-OR-FUNC-LIST} |
| 804 | @c @item write a version of xargs that's based on command rewriting | 822 | |
| 805 | @c find X | xargs Y == Y ${find X}. Maybe I could change | 823 | This would allow for an ``output translators'', that take a function to |
| 806 | @c eshell-do-pipelines to perform this on-thy-fly rewriting. | 824 | modify output with, and a target. Devise a syntax that works well with |
| 807 | @c @item implement head and tail in Lisp | 825 | pipes, and can accomodate multiple functions (i.e., @samp{>'(upcase |
| 808 | @c @item write an alias for less and more that brings up a view buffer | 826 | regexp-quote)} or @samp{>'upcase}). |
| 809 | @c Such that they can press SPC and DEL, and then q to return to eshell. | 827 | |
| 810 | @c The more command would be equivalent to: X > #<buffer Y>; view-buffer | 828 | @item Allow Eshell to read/write to/from standard input and output |
| 811 | @c #<buffer Y> | 829 | |
| 812 | @c @item differentiate between aliases and functions | 830 | This would be optional, rather than always using the Eshell buffer. |
| 813 | @c Allow for a bash-compatible syntax, such as: | 831 | This would allow it to be run from the command line (perhaps). |
| 814 | @c | 832 | |
| 815 | @c alias arg=blah | 833 | @item Write a @command{help} command |
| 816 | @c function arg () { blah $* } | 834 | |
| 817 | @c @item find the various references to shell-mode within Emacs | 835 | It would call subcommands with ``--help'', or ``-h'' or ``/?'', as |
| 818 | @c And add support for Eshell there, since now Eshell is going to be part | 836 | appropriate. |
| 819 | @c of Emacs. | 837 | |
| 820 | @c @item permit umask to be set on a cp target during the cp command | 838 | @item Implement @command{stty} in Lisp |
| 821 | @c @item if the first thing that I do after I enter Emacs | 839 | |
| 822 | @c is to run eshell-command and invoke ls, and then I use M-x eshell, it | 840 | @item Support @command{rc}'s matching operator, e.g. @samp{~ (list) regexp} |
| 823 | @c doesn't show me anything. | 841 | |
| 824 | @c @item M-RET during a long command doesn't quite work | 842 | @item Implement @command{bg} and @command{fg} as editors of @code{eshell-process-list} |
| 825 | @c Since it keeps the cursor up where the command was invoked. | 843 | |
| 844 | Using @command{bg} on a process that is already in the background does | ||
| 845 | nothing. Specifying redirection targets replaces (or adds) to the list | ||
| 846 | current being used. | ||
| 847 | |||
| 848 | @item Have @command{jobs} print only the processes for the current shell | ||
| 849 | |||
| 850 | @item How can Eshell learn if a background process has requested input? | ||
| 851 | |||
| 852 | @item Support @samp{2>&1} and @samp{>&} and @samp{2>} and @samp{|&} | ||
| 853 | |||
| 854 | The syntax table for parsing these should be customizable, such that the | ||
| 855 | user could change it to use rc syntax: @samp{>[2=1]}. | ||
| 856 | |||
| 857 | @item Allow @samp{$_[-1]}, which would indicate the last element of the array | ||
| 858 | |||
| 859 | @item Make @samp{$x[*]} equal to listing out the full contents of @samp{x} | ||
| 860 | |||
| 861 | Return them as a list, so that @samp{$_[*]} is all the arguments of the | ||
| 862 | last command. | ||
| 863 | |||
| 864 | @item Copy ANSI code handling from @file{term.el} into @file{em-term.el} | ||
| 865 | |||
| 866 | Make it possible for the user to send char-by-char to the underlying | ||
| 867 | process. Ultimately, I should be able to move away from using term.el | ||
| 868 | altogether, since everything but the ANSI code handling is already part | ||
| 869 | of Eshell. Then, things would work correctly on Win32 as well (which | ||
| 870 | doesn't have @file{/bin/sh}, although @file{term.el} tries to use it) | ||
| 871 | |||
| 872 | @item Make the shell spawning commands be visual | ||
| 873 | |||
| 874 | That is, make (@command{su}, @command{bash}, @command{telnet}, | ||
| 875 | @command{rlogin}, @command{rsh}, etc.) be part of | ||
| 876 | @code{eshell-visual-commands}. The only exception is if the shell is | ||
| 877 | being used to invoke a single command. Then, the behavior should be | ||
| 878 | based on what that command is. | ||
| 879 | |||
| 880 | @item Create an smart viewing command named @command{open} | ||
| 881 | |||
| 882 | This would search for some way to open its argument (similar to opening | ||
| 883 | a file in the Windows Explorer). | ||
| 884 | |||
| 885 | @item Alias @command{read} to be the same as @command{open}, only read-only | ||
| 886 | |||
| 887 | @item Write a @command{tail} command which uses @code{view-file} | ||
| 888 | |||
| 889 | It would move point to the end of the buffer, and then turns on | ||
| 890 | auto-revert mode in that buffer at frequent intervals---and a | ||
| 891 | @command{head} alias which assums an upper limit of | ||
| 892 | @code{eshell-maximum-line-length} characters per line. | ||
| 893 | |||
| 894 | @item Make @command{dgrep} load @code{dired}, mark everything, then invoke @code{dired-do-search} | ||
| 895 | |||
| 896 | @item Write emsh.c | ||
| 897 | |||
| 898 | This would run Emacs with the appropriate arguments to invoke Eshell | ||
| 899 | only. That way, it could be listed as a login shell. | ||
| 900 | |||
| 901 | @item Use an intangible @code{PS2} string for multi-line input prompts | ||
| 902 | |||
| 903 | @item Auto-detect when a command is visual, by checking @code{TERMCAP} usage | ||
| 904 | |||
| 905 | @item The first keypress after @kbd{M-x watson} triggers `eshell-send-input' | ||
| 906 | |||
| 907 | @item Make @kbd{/} electric | ||
| 908 | |||
| 909 | So that it automatically expands and corrects pathnames. Or make | ||
| 910 | pathname completion for Pcomplete auto-expand @samp{/u/i/std<TAB>} to | ||
| 911 | @samp{/usr/include/std<TAB>}. | ||
| 912 | |||
| 913 | @item Write the @command{pushd} stack to disk along with @code{last-dir-ring} | ||
| 914 | |||
| 915 | @item Add options to @code{eshell/cat} which would allow it to sort and uniq | ||
| 916 | |||
| 917 | @item Implement @command{wc} in Lisp | ||
| 918 | |||
| 919 | Add support for counting sentences, paragraphs, pages, etc. | ||
| 920 | |||
| 921 | @item Once piping is added, implement @command{sort} and @command{uniq} in Lisp | ||
| 922 | |||
| 923 | @item Implement @command{touch} in Lisp | ||
| 924 | |||
| 925 | @item Implement @command{comm} in Lisp | ||
| 926 | |||
| 927 | @item Implement an @command{epatch} command in Lisp | ||
| 928 | |||
| 929 | This would call @code{ediff-patch-file}, or @code{ediff-patch-buffer}, | ||
| 930 | depending on its argument. | ||
| 931 | |||
| 932 | @item Have an option such that @samp{ls -l} generates a dired buffer | ||
| 933 | |||
| 934 | @item Write a version of @command{xargs} based on command rewriting | ||
| 935 | |||
| 936 | That is, @samp{find X | xargs Y} would be indicated using @samp{Y | ||
| 937 | $@{find X@}}. Maybe @code{eshell-do-pipelines} could be changed to | ||
| 938 | perform this on-thy-fly rewriting. | ||
| 939 | |||
| 940 | @item Write an alias for @command{less} that brings up a @code{view-mode} buffer | ||
| 941 | |||
| 942 | Such that the user can press @kbd{SPC} and @kbd{DEL}, and then @kbd{q} | ||
| 943 | to return to Eshell. It would be equivalent to: | ||
| 944 | @samp{X > #<buffer Y>; view-buffer #<buffer Y>}. | ||
| 945 | |||
| 946 | @item Make @code{eshell-mode} as much a full citizen as @code{shell-mode} | ||
| 947 | |||
| 948 | Everywhere in Emacs where @code{shell-mode} is specially noticed, add | ||
| 949 | @code{eshell-mode} there. | ||
| 950 | |||
| 951 | @item Permit the umask to be selectively set on a @command{cp} target | ||
| 952 | |||
| 953 | @item Problem using @kbd{M-x eshell} after using @code{eshell-command} | ||
| 954 | |||
| 955 | If the first thing that I do after entering Emacs is to run | ||
| 956 | @code{eshell-command} and invoke @command{ls}, and then use @kbd{M-x | ||
| 957 | eshell}, it doesn't display anything. | ||
| 958 | |||
| 959 | @item @kbd{M-RET} during a long command (using smart display) doesn't work | ||
| 960 | |||
| 961 | Since it keeps the cursor up where the command was invoked. | ||
| 962 | |||
| 826 | @end table | 963 | @end table |
| 827 | 964 | ||
| 828 | @node Concept Index, Function and Variable Index, Bugs and ideas, Top | 965 | @node Concept Index, Function and Variable Index, Bugs and ideas, Top |
| @@ -835,7 +972,7 @@ See the entry above. | |||
| 835 | 972 | ||
| 836 | @printindex fn | 973 | @printindex fn |
| 837 | 974 | ||
| 838 | @node Key Index, , Function and Variable Index, Top | 975 | @node Key Index, , Function and Variable Index, Top |
| 839 | @unnumbered Key Index | 976 | @unnumbered Key Index |
| 840 | 977 | ||
| 841 | @printindex ky | 978 | @printindex ky |