aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Wiegley2000-10-29 05:18:48 +0000
committerJohn Wiegley2000-10-29 05:18:48 +0000
commitdace60cfea488a9cc8a775109c56b66907aa6abb (patch)
tree364b9c0114540a5f51a42e1e28a37b98714edaee
parent657f9cb8b7f7c3a9687f3998319ce63346ef13a4 (diff)
downloademacs-dace60cfea488a9cc8a775109c56b66907aa6abb.tar.gz
emacs-dace60cfea488a9cc8a775109c56b66907aa6abb.zip
See ChangeLog
-rw-r--r--etc/ChangeLog4
-rw-r--r--etc/NEWS5
-rw-r--r--lisp/ChangeLog123
-rw-r--r--lisp/calendar/timeclock.el434
-rw-r--r--lisp/eshell/em-alias.el7
-rw-r--r--lisp/eshell/em-dirs.el6
-rw-r--r--lisp/eshell/em-glob.el5
-rw-r--r--lisp/eshell/em-ls.el74
-rw-r--r--lisp/eshell/em-script.el3
-rw-r--r--lisp/eshell/em-smart.el35
-rw-r--r--lisp/eshell/em-unix.el129
-rw-r--r--lisp/eshell/esh-cmd.el120
-rw-r--r--lisp/eshell/esh-groups.el1
-rw-r--r--lisp/eshell/esh-maint.el68
-rw-r--r--lisp/eshell/esh-mode.el11
-rw-r--r--lisp/eshell/esh-module.el6
-rw-r--r--lisp/eshell/esh-test.el8
-rw-r--r--lisp/eshell/esh-util.el14
-rw-r--r--lisp/textmodes/flyspell.el56
-rw-r--r--man/ChangeLog4
-rw-r--r--man/eshell.texi825
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 @@
12000-10-18 John Wiegley <johnw@gnu.org>
2
3 * NEWS: Added text for pcomplete.el.
4
12000-10-16 Gerd Moellmann <gerd@gnu.org> 52000-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.
diff --git a/etc/NEWS b/etc/NEWS
index 538010724f3..5d509f67ba6 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -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
1787Gnus facilities. 1787Gnus facilities.
1788 1788
1789*** pcomplete.el ?? 1789*** pcomplete.el is a library that provides programmable completion
1790facilities for Emacs, similar to what zsh and tcsh offer. The main
1791difference is that completion functions are written in Lisp, meaning
1792they 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 @@
12000-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
12000-10-29 Michael Kifer <kifer@cs.sunysb.edu> 1222000-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
8712000-10-13 John Wiegley <johnw@gnu.org> 9922000-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.
225The format of this list is (CODE TIME PROJECT). PROJECT will be 225The format of this list is (CODE TIME PROJECT).")
226non-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.
460The amount returned is relative to the value of `timeclock-workday'. 459The amount returned is relative to the value of `timeclock-workday'.
461If TODAY-ONLY is non-nil, the value returned will be relative only to 460If 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
463a difference if `timeclock-relative' is non-nil." 462a 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.
488If RELATIVE is non-nil, the amount returned will be relative to past 487If RELATIVE is non-nil, the amount returned will be relative to past
489time worked. The default is to return only the time that has elapsed 488time 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.
510If TODAY-ONLY is non-nil, the value returned will be relative only to 509If TODAY-ONLY is non-nil, the value returned will be relative only to
511the time worked today, and not to past time. This argument only makes 510the 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.
580If PROJECT is a string, it represents the project which the event is 579If PROJECT is a string, it represents the project which the event is
581being logged for. Normally only \"out\" events specify a project." 580being 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.
789A timelog contains data in the form of a single entry per line.
790Each entry has the form:
791
792 CODE YYYY/MM/DD HH:MM:SS [COMMENT]
793
794CODE is one of: b, h, i, o or O. COMMENT is optional when the code is
795i, 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
815When this function is called, it will return a data structure with the
816following format:
817
818 (DEBT ENTRIES-BY-DAY ENTRIES-BY-PROJECT)
819
820DEBT 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'
822entry), this is always zero.
823
824The two entries lists have similar formats. They are both alists,
825where the CAR is the index, and the CDR is a list of time entries.
826For ENTRIES-BY-DAY, the CAR is a textual date string, of the form
827YYYY/MM/DD. For ENTRIES-BY-PROJECT, it is the name of the project
828worked on, or t for the default project.
829
830The CDR for ENTRIES-BY-DAY is slightly different than for
831ENTRIES-BY-PROJECT. It has the following form:
832
833 (DAY-LENGTH TIME-ENTRIES...)
834
835For ENTRIES-BY-PROJECT, there is no DAY-LENGTH member. It is simply a
836list of TIME-ENTRIES. Note that if DAY-LENGTH is nil, it means
837whatever is the default should be used.
838
839A TIME-ENTRY is a recorded time interval. It has the following format
840\(although generally one does not have to manipulate these entries
841directly; see below):
842
843 (BEGIN-TIME END-TIME PROJECT [COMMENT] [FINAL-P])
844
845Anyway, suffice it to say there are a lot of structures. Typically
846the user is expected to manipulate to the day(s) or project(s) that he
847or she wants, at which point the following helper functions may be
848used:
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
881A 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
904There are a few more functions available, for locating day and entry
905lists:
906
907 timeclock-day-alist LOG-DATA
908 timeclock-project-alist LOG-DATA
909 timeclock-current-debt LOG-DATA
910
911See 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).
660If TODAY-ONLY is non-nil, the discrepancy will be not be relative, and 980If TODAY-ONLY is non-nil, the discrepancy will be not be relative, and
661will correspond only to the amount of time elapsed today. This is 981will correspond only to the amount of time elapsed today. This is
662identical to what would be return if `timeclock-relative' were nil." 982identical 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.
86This 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'.
62This 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.
93Using this boolean, instead of `eshell-ls-exclude-regexp', is both
94faster 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
196yet again." 209yet 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.
129Otherwise, Emacs will attempt to use rsh to invoke du on the remote machine." 134Otherwise, 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.")
462Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY. 477Rename 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.
494Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.") 510Copy 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
518more than one TARGET, the last argument must be a directory; create links 536more than one TARGET, the last argument must be a directory; create links
519in DIRECTORY to each TARGET. Create hard links by default, symbolic links 537in DIRECTORY to each TARGET. Create hard links by default, symbolic links
520with '--symbolic'. When creating hard links, each TARGET must exist.") 538with '--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.
539If in a pipeline, or the file is not a regular file, directory or 549If in a pipeline, or the file is not a regular file, directory or
540symlink, then revert to the system's definition of cat." 550symlink, 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.
208That is, if a command is defined by a function named eshell/NAME,
209and NAME is part of this list, it is invoked as a complex command.
210Complex commands are always correct, but run much slower. If a
211command works fine without being part of this list, then it doesn't
212need to be.
213
214If an entry is a function, it will be called with the name, and should
215return 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.
696If REVERSED is non-nil, the list of separated term groups will be 713If REVERSED is non-nil, the list of separated term groups will be
697returned in reverse order. If LAST-TERMS-SYM is a symbol, it's value 714returned 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
132naturally accessible within Emacs." 132naturally 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.
187This is used by `eshell-watch-for-password-prompt'." 185This 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'.
41If nil, t will be represented only in the exit code of the function,
42and not printed as a string. This causes Lisp functions to behave
43similarly 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
1994in POSS. Otherwise the change is undone. 1994in POSS. Otherwise the change is undone.
1995 1995
1996This function is meant to be added to 'flyspell-incorrect-hook'." 1996This 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.
2014This function is meant to be added to 'flyspell-incorrect-hook'." 2021This 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 @@
12000-10-28 John Wiegley <johnw@gnu.org>
2
3 * eshell.texi: Further editing, and finished the "bugs" section.
4
12000-10-28 Eli Zaretskii <eliz@is.elta.co.il> 52000-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
116This manual documents Eshell, a shell-like command interpretor 116This manual documents Eshell, a shell-like command interpretor
117implemented entirely in Emacs Lisp. It invokes no external processes 117implemented in Emacs Lisp. It invokes no external processes except for
118beyond those requested by the user. It is intended to be a functional 118those requested by the user. It is intended to be a functional
119replacement for command shells such as @command{bash}, @command{zsh}, 119replacement 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
121most of the tasks accomplished by such tools. 121handling 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
139Eshell is a @dfn{command shell} written using Emacs Lisp. All of what it does 140Eshell is a @dfn{command shell} written in Emacs Lisp. Everything it
140it uses Emacs' facilities to do. This means Eshell is as portable as 141does it uses Emacs' facilities to do. This means that Eshell is as
141Emacs itself. It also means that cooperation with other Lisp code is 142portable as Emacs itself. It also means that cooperation with Lisp code
142natural and seamless. 143is natural and seamless.
143 144
144So what is a command shell? To properly understand the role of a shell, 145What is a command shell? To properly understand the role of a shell,
145it's necessary to visualize what a computer does for you. Basically, a 146it's necessary to visualize what a computer does for you. Basically, a
146computer is a tool; in order to use that tool, you must tell it what to 147computer is a tool; in order to use that tool, you must tell it what to
147do---or give it ``commands''. These commands take many forms, such as 148do---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
149one form of command input. 150one form of command input.
150 151
151By far the most versatile way to express what you want the computer to 152By far the most versatile way to express what you want the computer to
152do is using an abbreviated language, called @dfn{a script}. In a 153do is by using an abbreviated language called @dfn{script}. In script,
153script, instead 154instead of telling the computer, ``list my files, please'', one writes
154of telling the computer, ``list my files, please'', we write just 155just ``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 156abbreviated to ``ls''. Typing @kbd{ls} in a command shell is a script
156it to ``ls''. Typing @kbd{ls} in a command shell is a script way of 157way of telling the computer to list your files.@footnote{This is
157telling the computer to list your files. This is comparable to viewing 158comparable to viewing the contents of a folder using a graphical
158the contents of a folder using a graphical display. 159display.}
159 160
160The real flexibility is apparent only when you realize that there are 161The real flexibility of this approach is apparent only when you realize
161many, many ways to list your files. Perhaps you want them sorted by 162that there are many, many different ways to list files. Perhaps you
162name, or sorted by date, or in reverse order, or grouped by type. Most 163want them sorted by name, sorted by date, in reverse order, or grouped
163graphical browsers have simple ways to express this. But what about 164by type. Most graphical browsers have simple ways to express this. But
164showing only a few files, or only files that meet a certain criteria? 165what about showing only a few files, or only files that meet a certain
165In very complex and specific situations, the request becomes too 166criteria? In very complex and specific situations, the request becomes
166difficult to express with a mouse. It is just these kinds of requests 167too difficult to express using a mouse or pointing device. It is just
167that are solvable using a command shell. 168these kinds of requests that are easily solved using a command shell.
168 169
169For example, what if you want to list every Word file on your hard 170For example, what if you want to list every Word file on your hard
170drive, larger than 100 kilobytes in size, and which hasn't been looked 171drive, 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
173computer for such a list? There is no way to do it! At least, not 174computer for such a list? There is no way to do it! At least, not
174without using a command shell. 175without using a command shell.
175 176
176So the role of a command shell is to give you more control over what 177The role of a command shell is to give you more control over what your
177your computer does for you. Not everyone needs this amount of control, 178computer does for you. Not everyone needs this amount of control, and
178and it does come at a cost: Learning the necessary script commands to 179it does come at a cost: Learning the necessary script commands to
179express what you want done. A complicated query, such as the example 180express what you want done. A complicated query, such as the example
180above, takes time to learn. But if you find yourself using your 181above, takes time to learn. But if you find yourself using your
181computer frequently enough, it is more than worthwhile in the long run. 182computer frequently enough, it is more than worthwhile in the long run.
182Any tool you use often deserves your time in learning to master it. 183Any 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
184looks like: But don't let it fool you; once you know what's going on, 185looks like: But don't let it fool you; once you know what's going on,
185it's easier than it looks: @code{ls -lt **/*.doc(Lk+50aM+5)}.} 186it'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)}.}
187As of Emacs 21, Eshell is part of the standard Emacs distribution. 188As 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,
230requests, bug reports and encouragement. Thanks a lot! Without you 231requests, bug reports and encouragement. Thanks a lot! Without you
231there would be no new releases of Eshell. 232there 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
237As mentioned above, Eshell comes preinstalled since Emacs 21. If you're 238As mentioned above, Eshell comes preinstalled as of Emacs 21. If you're
238using Emacs 20.4 or later, or XEmacs 21, you can download the most 239using Emacs 20.4 or later, or XEmacs 21, you can download the most
239recent version of Eshell from 240recent 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
242If you are using Emacs 21, please skip this section. 243However, 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,
420e.g., @code{dvilj4} for LaserJet-compatible printers. 421e.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. 427A command shell is a mechanism for entering verbally-formed commands.
428This is really all that it does, and every feature described in this
429manual is a means to that end. Therefore, it's important to get a firm
430grasp on exactly what a command is, and how it fits into the overall
431picture 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 441Commands are expressed using @dfn{script}, a special shorthand language
431@c language---that the computer can understand. 442that computers can understand without trouble.
432 443
433@c What does script look like? 444Script is an extremely simplified language. Oddly enough, this actually
445makes it look more complicated than it is. Whereas normal languages use
446a 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? 452The verb expresses what you want your computer to do. There are a fixed
453number of verbs, although this number is usually quite large. On the
454author's computer, it reaches almost 1400 in number. But of course,
455only 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 457Sometimes, 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 458word, 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 459a good example. Entering that will cause your computer to reboot,
445@c handful of these are necessary most of the time. 460assuming you have sufficient privileges.
446 461
447@c Sometimes, the verb is all that's necessary. A verb is always a 462Other verbs require more information. These are usually very capable of
448@c single word, usually related to the task it will perform. 463verbs, and must be told more specifically what to do. This extra
449@c @command{reboot} is a good example. Entering that will cause your 464information is given in the form of arguments. Arguments are also
450@c computer to reboot, assuming you have sufficient privileges. 465single words, that appear after the verb. For example, @command{echo}
466is a command verb that prints back whatever you say. @command{echo}
467requires 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 471echo 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 474This piece of script expresses a command that causes the computer to
461@c echo This is an example of using echo! 475print 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, 477Although 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
479forms. There are textual arguments, numerical arguments---even Lisp
480arguments. Distinguishing between these different types of arguments
481requires special typing, since the computer needs to know exactly what
482you 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
500Below is a partial list of currently known problems with Eshell version 514Below is a partial list of currently known problems with Eshell version
5012.3.2, which is the version distributed with Emacs 21.1. 5152.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
520Allow for a bash-compatible syntax, such as:
521
522@example
523alias arg=blah
524function 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
506In fact, piping to a process from a looping construct doesn't work in 529In fact, piping to a process from a looping construct doesn't work in
507general. If I change the call to @code{eshell-copy-handles} in 530general. If I change the call to @code{eshell-copy-handles} in
@@ -514,11 +537,6 @@ structured command thing is too complicated at present.
514On some XEmacs system, the subprocess interaction test fails 537On some XEmacs system, the subprocess interaction test fails
515inexplicably, although @command{bc} works fine at the command prompt. 538inexplicably, although @command{bc} works fine at the command prompt.
516 539
517@item @command{ls} in remote directories sometimes fails
518
519For XEmacs users, using @command{ls} in a remote directory sometimes
520fails. 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
524In XEmacs 21.1.8, the @file{*Help*} buffer has been renamed such that 542In XEmacs 21.1.8, the @file{*Help*} buffer has been renamed such that
@@ -563,266 +581,385 @@ since.
563 581
564Make it so that the Lisp command on the right of the pipe is repeatedly 582Make it so that the Lisp command on the right of the pipe is repeatedly
565called with the input strings as arguments. This will require changing 583called with the input strings as arguments. This will require changing
566eshell-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
570See the entry above. 588See 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 592The 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: 595Spawning child process: invalid argument
578@c 596@end example
579@c Spawning child process: invalid argument 597
580@c 598Also 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 601If @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 602expected output is written to the buffer.
585@c simply written to the buffer. 603
586@c 604Note 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 605package 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 606running 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 614This 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) 615be 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 619This would be so that if a Lisp function calls @code{print}, everything
602@c So that M-DEL acts in a predictable manner, etc. 620will 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 628So 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. 634If 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 635output 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 639Make 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 640Then 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 648Invalid 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. 651With @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 656Perhaps it should interpolate all permutations, and make that the
639@c glob match 657globbing 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 660In 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 665Make 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 667than 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 673This 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 678It 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 679pre-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 680And 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 684This 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 688It means that files beginning with a dot should be included in the
671@c post-command-hook. 689glob 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 693At 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 697An error should be generated only if @code{eshell-error-if-no-glob} is
680@c $=[REGEXP]. It also indexes into the directory ring 698non-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 704This is a list of commands for which, if the user presses @kbd{RET}, the
687@c interpolate.el --- interpolate $variable $(lisp)... references 705text 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 706current 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 716With 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 717can't keep up anymore and starts outputting blank lines. It only
700@c @item create a mode `eshell-browse' 718happens 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 720I think the problem is that @code{eshell-send-input} is resetting the
703@c first command run in each directory 721input target location, so that if the asynchronous process is not done
704@c @item look through the Korn Shell book for feature ideas 722by 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}" 723that the input is meant for the process; which, when smart display is
706@c This would be expanded by `eshell-expand-file-name' 724enabled, 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 725itself.
708@c @item implement M-| 726
709@c @item implement input redirection 727In holding down @kbd{RET} while an asynchronous process is running,
710@c If it's a lisp function, input redirection implies "xargs" (in a 728there 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 729running 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 731process 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'. 732there should be a way of killing pending input between the death of the
715@c @item in `eval-using-options', have a :complete tag 733process, 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 737Perhaps toggled by a command, that makes each output block a smart
720@c the current region) to be inserting in the symbol `blah'. 738display 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 744The 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. 745last 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 748A 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 758So 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. 762It would treat the Eshell buffer as a outline. Collapsing the outline
745@c This would allow it to be run from the command line. 763hides all of the output text. Collapsing again would show only the
746@c @item write a "help" command 764first 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' 768This 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]. 776If 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. 777way@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 782With 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 787It would be used to provide completion rules for that command. Then the
770@c Make (su, bash, telnet, rlogin, rsh, etc.) be part of 788macro 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" 792So 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 793input 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 796If 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 797input, 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' 799If a Lisp command, or an alias, is invoked, then if the line has no
782@c characters per line. 800newline characters, it is divided by whitespace and passed as arguments
783@c @item make dgrep load dired, mark everything, then execute the A binding 801to the Lisp function. Otherwise, it is divided at the newline
784@c @item write emsh.c 802characters. Thus, invoking @code{+} on a series of numbers will add
785@c It just runs Emacs with the appropriate arguments to invoke eshell. 803them; @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' 807It 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>". 812This means @samp{!n}, @samp{!#}, @samp{!:%}, and @samp{!:1-} as separate
795@c @item Write pushd/popd out to disk along with last-dir-ring 813from @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 823This would allow for an ``output translators'', that take a function to
806@c eshell-do-pipelines to perform this on-thy-fly rewriting. 824modify output with, and a target. Devise a syntax that works well with
807@c @item implement head and tail in Lisp 825pipes, 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 826regexp-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 830This would be optional, rather than always using the Eshell buffer.
813@c Allow for a bash-compatible syntax, such as: 831This 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 835It 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 836appropriate.
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
844Using @command{bg} on a process that is already in the background does
845nothing. Specifying redirection targets replaces (or adds) to the list
846current 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
854The syntax table for parsing these should be customizable, such that the
855user 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
861Return them as a list, so that @samp{$_[*]} is all the arguments of the
862last command.
863
864@item Copy ANSI code handling from @file{term.el} into @file{em-term.el}
865
866Make it possible for the user to send char-by-char to the underlying
867process. Ultimately, I should be able to move away from using term.el
868altogether, since everything but the ANSI code handling is already part
869of Eshell. Then, things would work correctly on Win32 as well (which
870doesn't have @file{/bin/sh}, although @file{term.el} tries to use it)
871
872@item Make the shell spawning commands be visual
873
874That 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
877being used to invoke a single command. Then, the behavior should be
878based on what that command is.
879
880@item Create an smart viewing command named @command{open}
881
882This would search for some way to open its argument (similar to opening
883a 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
889It would move point to the end of the buffer, and then turns on
890auto-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
898This would run Emacs with the appropriate arguments to invoke Eshell
899only. 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
909So that it automatically expands and corrects pathnames. Or make
910pathname 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
919Add 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
929This would call @code{ediff-patch-file}, or @code{ediff-patch-buffer},
930depending 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
936That is, @samp{find X | xargs Y} would be indicated using @samp{Y
937$@{find X@}}. Maybe @code{eshell-do-pipelines} could be changed to
938perform this on-thy-fly rewriting.
939
940@item Write an alias for @command{less} that brings up a @code{view-mode} buffer
941
942Such that the user can press @kbd{SPC} and @kbd{DEL}, and then @kbd{q}
943to 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
948Everywhere 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
955If 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
957eshell}, it doesn't display anything.
958
959@item @kbd{M-RET} during a long command (using smart display) doesn't work
960
961Since 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