diff options
| author | John Wiegley | 2000-10-29 05:18:48 +0000 |
|---|---|---|
| committer | John Wiegley | 2000-10-29 05:18:48 +0000 |
| commit | dace60cfea488a9cc8a775109c56b66907aa6abb (patch) | |
| tree | 364b9c0114540a5f51a42e1e28a37b98714edaee /lisp | |
| parent | 657f9cb8b7f7c3a9687f3998319ce63346ef13a4 (diff) | |
| download | emacs-dace60cfea488a9cc8a775109c56b66907aa6abb.tar.gz emacs-dace60cfea488a9cc8a775109c56b66907aa6abb.zip | |
See ChangeLog
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/ChangeLog | 123 | ||||
| -rw-r--r-- | lisp/calendar/timeclock.el | 434 | ||||
| -rw-r--r-- | lisp/eshell/em-alias.el | 7 | ||||
| -rw-r--r-- | lisp/eshell/em-dirs.el | 6 | ||||
| -rw-r--r-- | lisp/eshell/em-glob.el | 5 | ||||
| -rw-r--r-- | lisp/eshell/em-ls.el | 74 | ||||
| -rw-r--r-- | lisp/eshell/em-script.el | 3 | ||||
| -rw-r--r-- | lisp/eshell/em-smart.el | 35 | ||||
| -rw-r--r-- | lisp/eshell/em-unix.el | 129 | ||||
| -rw-r--r-- | lisp/eshell/esh-cmd.el | 120 | ||||
| -rw-r--r-- | lisp/eshell/esh-groups.el | 1 | ||||
| -rw-r--r-- | lisp/eshell/esh-maint.el | 68 | ||||
| -rw-r--r-- | lisp/eshell/esh-mode.el | 11 | ||||
| -rw-r--r-- | lisp/eshell/esh-module.el | 6 | ||||
| -rw-r--r-- | lisp/eshell/esh-test.el | 8 | ||||
| -rw-r--r-- | lisp/eshell/esh-util.el | 14 | ||||
| -rw-r--r-- | lisp/textmodes/flyspell.el | 56 |
17 files changed, 809 insertions, 291 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 903612bed0b..706751d315a 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,124 @@ | |||
| 1 | 2000-10-28 John Wiegley <johnw@gnu.org> | ||
| 2 | |||
| 3 | * textmodes/flyspell.el (flyspell-maybe-correct-transposition): | ||
| 4 | Changed this function to operate on a temporary buffer instead of | ||
| 5 | the main buffer. This not only keeps flyspell from marking a | ||
| 6 | buffer as changed that wasn't, but it solves the jumpy cursor | ||
| 7 | problem when attempts are made to edit incorrect words. | ||
| 8 | (flyspell-maybe-correct-doubling): Same change as for | ||
| 9 | `flyspell-maybe-correct-transposition'. | ||
| 10 | |||
| 11 | * calendar/timeclock.el (timeclock-log): Doc fix. | ||
| 12 | (timeclock-last-event): Doc fix. | ||
| 13 | (timeclock-log): Kill the timelog buffer after appending a new | ||
| 14 | event. | ||
| 15 | (timeclock-find-discrep): Use a temp buffer to read in the | ||
| 16 | timelog, instead of visiting the file. | ||
| 17 | (timeclock-log-data): A new function, along with a host of helper | ||
| 18 | functions, for the purpose of making timelog data accessible to | ||
| 19 | programmers. | ||
| 20 | |||
| 21 | * eshell/esh-mode.el (window-height test): Make certain that | ||
| 22 | `eshell-stringify-t' is non-nil. | ||
| 23 | (eshell-password-prompt-regexp): Changed to a much simpler | ||
| 24 | password regexp. | ||
| 25 | (eshell-send-input): If `eshell-invoke-directly' returns t, | ||
| 26 | directly invoke the parsed command using `eval'. This improves | ||
| 27 | turn-around time on simple commands by a factor of three or | ||
| 28 | greater, such as cd, ls, pwd, etc. -- which get used very often. | ||
| 29 | It also conserves thousands of cons cells per call (since | ||
| 30 | `eshell-do-eval' consumes memory like a Cookie Monster set loose | ||
| 31 | in the Pacific Cookie Company). | ||
| 32 | |||
| 33 | * eshell/esh-test.el (eshell-test): Whitespace fix. | ||
| 34 | |||
| 35 | * eshell/em-ls.el (eshell-ls-insert-directory): Make | ||
| 36 | `eshell-ls-initial-args' nil when inserting directory contents. | ||
| 37 | |||
| 38 | * eshell/em-script.el (eshell-script-initialize): Add names to | ||
| 39 | `eshell-complex-commands, since `source' and `.' are complex. | ||
| 40 | |||
| 41 | * eshell/esh-cmd.el (eshell-rewrite-for-command, | ||
| 42 | eshell-rewrite-while-command): Use `eshell-protect' instead of | ||
| 43 | `eshell-copy-handles'. | ||
| 44 | (eshell-rewrite-if-command): Use `eshell-protect' to wrap the call | ||
| 45 | bodies. | ||
| 46 | (eshell-separate-commands): Whitespace fix. | ||
| 47 | (eshell-complex-commands): Added a new list of names, for | ||
| 48 | determining whether a given command is as simple as it looks. | ||
| 49 | (eshell-invoke-directly): New function. Returns t if a command | ||
| 50 | should be invoked directly (using `eval'), rather than indirectly | ||
| 51 | using `eshell-do-eval'. | ||
| 52 | (eshell-do-eval): Whitespace fix. | ||
| 53 | |||
| 54 | * eshell/em-unix.el (eshell-default-target-is-dot): New variable, | ||
| 55 | which provides an emulation of the DOS shell behavior of assuming | ||
| 56 | that cp/mv/ln should copy/move/link to the current directory. | ||
| 57 | (eshell-remove-entries): Added a doc string. | ||
| 58 | (eshell-shuffle-files): Removed the check for `target' being null. | ||
| 59 | (eshell-mvcp-template, eshell-mvcpln-template): Renamed | ||
| 60 | `eshell-mvcp-template' to `eshell-mvcpln-template', and extended | ||
| 61 | it to do a smarter check of whether a destination was provided. | ||
| 62 | (eshell/mv, eshell/cp): Enable `:preserve-args'. | ||
| 63 | (eshell/ln): Enable `:preserve-args', and use | ||
| 64 | `eshell-mvcpln-template' to implement the body of the function. | ||
| 65 | (eshell/cat, eshell/make, eshell-poor-mans-grep, eshell-grep, | ||
| 66 | eshell/du, eshell/diff, eshell/locate): Stringify the argument | ||
| 67 | list after flattening it. This makes it possible to cat files | ||
| 68 | with numerical names. | ||
| 69 | (eshell-unix-initialize): Added several names to | ||
| 70 | `eshell-complex-commands. | ||
| 71 | (eshell-unix-command-complex-p): Return t if a given command name | ||
| 72 | may result in external processes being invoked. | ||
| 73 | |||
| 74 | * eshell/em-glob.el (eshell-glob-show-progress): Make this | ||
| 75 | variable nil by default, since it slows down glob processing by a | ||
| 76 | factor of two or more, and increases memory consumption. | ||
| 77 | |||
| 78 | * eshell/em-smart.el: Added a note about how memory consumptive | ||
| 79 | smart display mode can be (at least this is true in Emacs 21). | ||
| 80 | (eshell-smart-initialize): Whitespace fix. | ||
| 81 | (eshell-refresh-windows): Use `if' instead of `when'. | ||
| 82 | (eshell-smart-scroll-window): Calling `save-current-buffer' was | ||
| 83 | not necessary. | ||
| 84 | (eshell-currently-handling-window): Added a missing global | ||
| 85 | variable. | ||
| 86 | |||
| 87 | * eshell/em-ls.el (eshell-do-ls): Code simplification. | ||
| 88 | (eshell-ls-sort-entries, eshell-ls-entries, eshell-ls-dir): | ||
| 89 | Whitespace fix. | ||
| 90 | (eshell-ls-exclude-hidden): Added this variable in addition to | ||
| 91 | `eshell-ls-exclude-regexp'. This one prevents files beginning | ||
| 92 | with . from even being read, which can improve memory consumption | ||
| 93 | quite a bit. | ||
| 94 | (eshell-ls-dir): If `eshell-ls-exclude-hidden' is non-nil, do not | ||
| 95 | read file entries beginning with a dot. In home directories with | ||
| 96 | lots of hidden files, fully two-thirds of the time spent in ls is | ||
| 97 | used to read directory entries that are immediately thrown away. | ||
| 98 | (eshell-ls-initial-args): Added back this configuration variable, | ||
| 99 | for specifying default initial arguments to every call to ls. | ||
| 100 | Much faster than using an alias to do the same thing. | ||
| 101 | (eshell-do-ls): Use `eshell-ls-initial-args', if set. | ||
| 102 | (eshell-ls-dir): Whitespace change. | ||
| 103 | |||
| 104 | * eshell/em-dirs.el (eshell/pwd): Small code simplification. | ||
| 105 | |||
| 106 | * eshell/esh-util.el: Don't require `ange-ftp' if it's not | ||
| 107 | available. | ||
| 108 | (eshell-stringify-t): Added a customization variable, to indicate | ||
| 109 | whether `t' should be rendered as a string at all. If not, one | ||
| 110 | can still determine if the result of an expression is true using | ||
| 111 | "file-exists-p FILE && echo true". | ||
| 112 | (eshell-stringify): If `eshell-stringify-t' is nil, don't | ||
| 113 | stringify t! | ||
| 114 | |||
| 115 | * eshell/esh-module.el: Whitespace fix. | ||
| 116 | |||
| 117 | * eshell/em-alias.el (eshell-alias-initialize): Added | ||
| 118 | `eshell-command-aliased-p' to `eshell-complex-commands'. | ||
| 119 | (eshell-command-aliased-p): New function that returns t if a | ||
| 120 | command name names an aliased. | ||
| 121 | |||
| 1 | 2000-10-29 Michael Kifer <kifer@cs.sunysb.edu> | 122 | 2000-10-29 Michael Kifer <kifer@cs.sunysb.edu> |
| 2 | 123 | ||
| 3 | * viper-cmd.el (viper-preserve-cursor-color): new test that avoids | 124 | * viper-cmd.el (viper-preserve-cursor-color): new test that avoids |
| @@ -865,7 +986,7 @@ | |||
| 865 | * align.el, pcomplete.el, calendar/timeclock.el, | 986 | * align.el, pcomplete.el, calendar/timeclock.el, |
| 866 | eshell/esh-module.el, eshell/eshell.el: Removed URL reference. | 987 | eshell/esh-module.el, eshell/eshell.el: Removed URL reference. |
| 867 | 988 | ||
| 868 | * calendar/timeclock.el (timeclock-find-discrep): A fix to same | 989 | * calendar/timeclock.el (timeclock-find-discrep): A fix to some |
| 869 | faulty math, where holiday hours were being computing as seconds. | 990 | faulty math, where holiday hours were being computing as seconds. |
| 870 | 991 | ||
| 871 | 2000-10-13 John Wiegley <johnw@gnu.org> | 992 | 2000-10-13 John Wiegley <johnw@gnu.org> |
diff --git a/lisp/calendar/timeclock.el b/lisp/calendar/timeclock.el index 265406d2e5f..d96250dde1d 100644 --- a/lisp/calendar/timeclock.el +++ b/lisp/calendar/timeclock.el | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | ;; Author: John Wiegley <johnw@gnu.org> | 5 | ;; Author: John Wiegley <johnw@gnu.org> |
| 6 | ;; Created: 25 Mar 1999 | 6 | ;; Created: 25 Mar 1999 |
| 7 | ;; Version: 2.2 | 7 | ;; Version: 2.3 |
| 8 | ;; Keywords: calendar data | 8 | ;; Keywords: calendar data |
| 9 | 9 | ||
| 10 | ;; This file is part of GNU Emacs. | 10 | ;; This file is part of GNU Emacs. |
| @@ -222,8 +222,7 @@ in the modeline. See the variable `timeclock-modeline-display'." | |||
| 222 | 222 | ||
| 223 | (defvar timeclock-last-event nil | 223 | (defvar timeclock-last-event nil |
| 224 | "A list containing the last event that was recorded. | 224 | "A list containing the last event that was recorded. |
| 225 | The format of this list is (CODE TIME PROJECT). PROJECT will be | 225 | The format of this list is (CODE TIME PROJECT).") |
| 226 | non-nil only if CODE is \"o\" or \"O\".") | ||
| 227 | 226 | ||
| 228 | (defvar timeclock-last-event-workday nil | 227 | (defvar timeclock-last-event-workday nil |
| 229 | "The number of seconds in the workday of `timeclock-last-event'.") | 228 | "The number of seconds in the workday of `timeclock-last-event'.") |
| @@ -455,7 +454,7 @@ as with time remaining, where negative time really means overtime)." | |||
| 455 | (truncate (/ (abs seconds) 60 60)) | 454 | (truncate (/ (abs seconds) 60 60)) |
| 456 | (% (truncate (/ (abs seconds) 60)) 60)))) | 455 | (% (truncate (/ (abs seconds) 60)) 60)))) |
| 457 | 456 | ||
| 458 | (defun timeclock-workday-remaining (&optional today-only) | 457 | (defsubst timeclock-workday-remaining (&optional today-only) |
| 459 | "Return a the number of seconds until the workday is complete. | 458 | "Return a the number of seconds until the workday is complete. |
| 460 | The amount returned is relative to the value of `timeclock-workday'. | 459 | The amount returned is relative to the value of `timeclock-workday'. |
| 461 | If TODAY-ONLY is non-nil, the value returned will be relative only to | 460 | If TODAY-ONLY is non-nil, the value returned will be relative only to |
| @@ -463,7 +462,7 @@ the time worked today, and not to past time. This argument only makes | |||
| 463 | a difference if `timeclock-relative' is non-nil." | 462 | a difference if `timeclock-relative' is non-nil." |
| 464 | (- (timeclock-find-discrep today-only))) | 463 | (- (timeclock-find-discrep today-only))) |
| 465 | 464 | ||
| 466 | (defun timeclock-currently-in-p () | 465 | (defsubst timeclock-currently-in-p () |
| 467 | "Return non-nil if the user is currently clocked in." | 466 | "Return non-nil if the user is currently clocked in." |
| 468 | (equal (car timeclock-last-event) "i")) | 467 | (equal (car timeclock-last-event) "i")) |
| 469 | 468 | ||
| @@ -483,7 +482,7 @@ See `timeclock-relative' for more information about the meaning of | |||
| 483 | (message string) | 482 | (message string) |
| 484 | string))) | 483 | string))) |
| 485 | 484 | ||
| 486 | (defun timeclock-workday-elapsed (&optional relative) | 485 | (defsubst timeclock-workday-elapsed (&optional relative) |
| 487 | "Return a the number of seconds worked so far today. | 486 | "Return a the number of seconds worked so far today. |
| 488 | If RELATIVE is non-nil, the amount returned will be relative to past | 487 | If RELATIVE is non-nil, the amount returned will be relative to past |
| 489 | time worked. The default is to return only the time that has elapsed | 488 | time worked. The default is to return only the time that has elapsed |
| @@ -505,7 +504,7 @@ non-nil, the amount returned will be relative to past time worked." | |||
| 505 | (message string) | 504 | (message string) |
| 506 | string))) | 505 | string))) |
| 507 | 506 | ||
| 508 | (defun timeclock-when-to-leave (&optional today-only) | 507 | (defsubst timeclock-when-to-leave (&optional today-only) |
| 509 | "Return a time value representing at when the workday ends today. | 508 | "Return a time value representing at when the workday ends today. |
| 510 | If TODAY-ONLY is non-nil, the value returned will be relative only to | 509 | If TODAY-ONLY is non-nil, the value returned will be relative only to |
| 511 | the time worked today, and not to past time. This argument only makes | 510 | the time worked today, and not to past time. This argument only makes |
| @@ -578,9 +577,8 @@ non-nil." | |||
| 578 | (defun timeclock-log (code &optional project) | 577 | (defun timeclock-log (code &optional project) |
| 579 | "Log the event CODE to the timeclock log, at the time of call. | 578 | "Log the event CODE to the timeclock log, at the time of call. |
| 580 | If PROJECT is a string, it represents the project which the event is | 579 | If PROJECT is a string, it represents the project which the event is |
| 581 | being logged for. Normally only \"out\" events specify a project." | 580 | being logged for. Normally only \"in\" events specify a project." |
| 582 | (save-excursion | 581 | (with-current-buffer (find-file-noselect timeclock-file) |
| 583 | (set-buffer (find-file-noselect timeclock-file)) | ||
| 584 | (goto-char (point-max)) | 582 | (goto-char (point-max)) |
| 585 | (if (not (bolp)) | 583 | (if (not (bolp)) |
| 586 | (insert "\n")) | 584 | (insert "\n")) |
| @@ -603,42 +601,40 @@ being logged for. Normally only \"out\" events specify a project." | |||
| 603 | timeclock-last-period))) | 601 | timeclock-last-period))) |
| 604 | (setq timeclock-last-event (list code now project))) | 602 | (setq timeclock-last-event (list code now project))) |
| 605 | (save-buffer) | 603 | (save-buffer) |
| 606 | (run-hooks 'timeclock-event-hook))) | 604 | (run-hooks 'timeclock-event-hook) |
| 605 | (kill-buffer (current-buffer)))) | ||
| 607 | 606 | ||
| 608 | (defun timeclock-read-moment () | 607 | (defvar timeclock-moment-regexp |
| 608 | (concat "\\([bhioO]\\)\\s-+" | ||
| 609 | "\\([0-9]+\\)/\\([0-9]+\\)/\\([0-9]+\\)\\s-+" | ||
| 610 | "\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)[ \t]*" "\\([^\n]*\\)")) | ||
| 611 | |||
| 612 | (defsubst timeclock-read-moment () | ||
| 609 | "Read the moment under point from the timelog." | 613 | "Read the moment under point from the timelog." |
| 610 | (save-excursion | 614 | (if (looking-at timeclock-moment-regexp) |
| 611 | (beginning-of-line) | 615 | (let ((code (match-string 1)) |
| 612 | (let ((eol (save-excursion (end-of-line) (point)))) | 616 | (year (string-to-number (match-string 2))) |
| 613 | (if (re-search-forward | 617 | (mon (string-to-number (match-string 3))) |
| 614 | (concat "^\\(.\\)\\s-+" | 618 | (mday (string-to-number (match-string 4))) |
| 615 | "\\([0-9]+\\)/\\([0-9]+\\)/\\([0-9]+\\)\\s-+" | 619 | (hour (string-to-number (match-string 5))) |
| 616 | "\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)\\s-*" | 620 | (min (string-to-number (match-string 6))) |
| 617 | "\\(.*\\)") eol t) | 621 | (sec (string-to-number (match-string 7))) |
| 618 | (let ((code (match-string 1)) | 622 | (project (match-string 8))) |
| 619 | (year (string-to-number (match-string 2))) | 623 | (list code (encode-time sec min hour mday mon year) project)))) |
| 620 | (mon (string-to-number (match-string 3))) | 624 | |
| 621 | (mday (string-to-number (match-string 4))) | 625 | (defsubst timeclock-time-to-seconds (time) |
| 622 | (hour (string-to-number (match-string 5))) | ||
| 623 | (min (string-to-number (match-string 6))) | ||
| 624 | (sec (string-to-number (match-string 7))) | ||
| 625 | (project (match-string 8))) | ||
| 626 | (list code (encode-time sec min hour mday mon year) | ||
| 627 | project)))))) | ||
| 628 | |||
| 629 | (defun timeclock-time-to-seconds (time) | ||
| 630 | "Convert TIME to a floating point number." | 626 | "Convert TIME to a floating point number." |
| 631 | (+ (* (car time) 65536.0) | 627 | (+ (* (car time) 65536.0) |
| 632 | (cadr time) | 628 | (cadr time) |
| 633 | (/ (or (car (cdr (cdr time))) 0) 1000000.0))) | 629 | (/ (or (car (cdr (cdr time))) 0) 1000000.0))) |
| 634 | 630 | ||
| 635 | (defun timeclock-seconds-to-time (seconds) | 631 | (defsubst timeclock-seconds-to-time (seconds) |
| 636 | "Convert SECONDS (a floating point number) to an Emacs time structure." | 632 | "Convert SECONDS (a floating point number) to an Emacs time structure." |
| 637 | (list (floor seconds 65536) | 633 | (list (floor seconds 65536) |
| 638 | (floor (mod seconds 65536)) | 634 | (floor (mod seconds 65536)) |
| 639 | (floor (* (- seconds (ffloor seconds)) 1000000)))) | 635 | (floor (* (- seconds (ffloor seconds)) 1000000)))) |
| 640 | 636 | ||
| 641 | (defun timeclock-time-to-date (time) | 637 | (defsubst timeclock-time-to-date (time) |
| 642 | "Convert the TIME value to a textual date string." | 638 | "Convert the TIME value to a textual date string." |
| 643 | (format-time-string "%Y/%m/%d" time)) | 639 | (format-time-string "%Y/%m/%d" time)) |
| 644 | 640 | ||
| @@ -655,49 +651,376 @@ This is only provided for coherency when used by | |||
| 655 | (cadr timeclock-last-event))) | 651 | (cadr timeclock-last-event))) |
| 656 | timeclock-last-period)) | 652 | timeclock-last-period)) |
| 657 | 653 | ||
| 654 | (defsubst timeclock-entry-length (entry) | ||
| 655 | (- (timeclock-time-to-seconds (cadr entry)) | ||
| 656 | (timeclock-time-to-seconds (car entry)))) | ||
| 657 | |||
| 658 | (defsubst timeclock-entry-begin (entry) | ||
| 659 | (car entry)) | ||
| 660 | |||
| 661 | (defsubst timeclock-entry-end (entry) | ||
| 662 | (cadr entry)) | ||
| 663 | |||
| 664 | (defsubst timeclock-entry-project (entry) | ||
| 665 | (nth 2 entry)) | ||
| 666 | |||
| 667 | (defsubst timeclock-entry-comment (entry) | ||
| 668 | (nth 3 entry)) | ||
| 669 | |||
| 670 | |||
| 671 | (defsubst timeclock-entry-list-length (entry-list) | ||
| 672 | (let ((length 0)) | ||
| 673 | (while entry-list | ||
| 674 | (setq length (+ length (timeclock-entry-length (car entry-list)))) | ||
| 675 | (setq entry-list (cdr entry-list))) | ||
| 676 | length)) | ||
| 677 | |||
| 678 | (defsubst timeclock-entry-list-begin (entry-list) | ||
| 679 | (timeclock-entry-begin (car entry-list))) | ||
| 680 | |||
| 681 | (defsubst timeclock-entry-list-end (entry-list) | ||
| 682 | (timeclock-entry-end (car (last entry-list)))) | ||
| 683 | |||
| 684 | (defsubst timeclock-entry-list-span (entry-list) | ||
| 685 | (- (timeclock-time-to-seconds (timeclock-entry-list-end entry-list)) | ||
| 686 | (timeclock-time-to-seconds (timeclock-entry-list-begin entry-list)))) | ||
| 687 | |||
| 688 | (defsubst timeclock-entry-list-break (entry-list) | ||
| 689 | (- (timeclock-entry-list-span entry-list) | ||
| 690 | (timeclock-entry-list-length entry-list))) | ||
| 691 | |||
| 692 | (defsubst timeclock-entry-list-projects (entry-list) | ||
| 693 | (let (projects) | ||
| 694 | (while entry-list | ||
| 695 | (let ((project (timeclock-entry-project (car entry-list)))) | ||
| 696 | (if projects | ||
| 697 | (add-to-list 'projects project) | ||
| 698 | (setq projects (list project)))) | ||
| 699 | (setq entry-list (cdr entry-list))) | ||
| 700 | projects)) | ||
| 701 | |||
| 702 | |||
| 703 | (defsubst timeclock-day-required (day) | ||
| 704 | (car day)) | ||
| 705 | |||
| 706 | (defsubst timeclock-day-length (day) | ||
| 707 | (timeclock-entry-list-length (cdr day))) | ||
| 708 | |||
| 709 | (defsubst timeclock-day-debt (day) | ||
| 710 | (- (timeclock-day-required day) | ||
| 711 | (timeclock-day-length day))) | ||
| 712 | |||
| 713 | (defsubst timeclock-day-begin (day) | ||
| 714 | (timeclock-entry-list-begin (cdr day))) | ||
| 715 | |||
| 716 | (defsubst timeclock-day-end (day) | ||
| 717 | (timeclock-entry-list-end (cdr day))) | ||
| 718 | |||
| 719 | (defsubst timeclock-day-span (day) | ||
| 720 | (timeclock-entry-list-span (cdr day))) | ||
| 721 | |||
| 722 | (defsubst timeclock-day-break (day) | ||
| 723 | (timeclock-entry-list-break (cdr day))) | ||
| 724 | |||
| 725 | (defsubst timeclock-day-projects (day) | ||
| 726 | (timeclock-entry-list-projects (cdr day))) | ||
| 727 | |||
| 728 | (defmacro timeclock-day-list-template (func) | ||
| 729 | `(let ((length 0)) | ||
| 730 | (while day-list | ||
| 731 | (setq length (+ length (,(eval func) (car day-list)))) | ||
| 732 | (setq day-list (cdr day-list))) | ||
| 733 | length)) | ||
| 734 | |||
| 735 | (defun timeclock-day-list-required (day-list) | ||
| 736 | (timeclock-day-list-template 'timeclock-day-required)) | ||
| 737 | |||
| 738 | (defun timeclock-day-list-length (day-list) | ||
| 739 | (timeclock-day-list-template 'timeclock-day-length)) | ||
| 740 | |||
| 741 | (defun timeclock-day-list-debt (day-list) | ||
| 742 | (timeclock-day-list-template 'timeclock-day-debt)) | ||
| 743 | |||
| 744 | (defsubst timeclock-day-list-begin (day-list) | ||
| 745 | (timeclock-day-begin (car day-list))) | ||
| 746 | |||
| 747 | (defsubst timeclock-day-list-end (day-list) | ||
| 748 | (timeclock-day-end (car (last day-list)))) | ||
| 749 | |||
| 750 | (defun timeclock-day-list-span (day-list) | ||
| 751 | (timeclock-day-list-template 'timeclock-day-span)) | ||
| 752 | |||
| 753 | (defun timeclock-day-list-break (day-list) | ||
| 754 | (timeclock-day-list-template 'timeclock-day-break)) | ||
| 755 | |||
| 756 | (defun timeclock-day-list-projects (day-list) | ||
| 757 | (let (projects) | ||
| 758 | (while day-list | ||
| 759 | (let ((projs (timeclock-day-projects (car day-list)))) | ||
| 760 | (while projs | ||
| 761 | (if projects | ||
| 762 | (add-to-list 'projects (car projs)) | ||
| 763 | (setq projects (list (car projs)))) | ||
| 764 | (setq projs (cdr projs)))) | ||
| 765 | (setq day-list (cdr day-list))) | ||
| 766 | projects)) | ||
| 767 | |||
| 768 | |||
| 769 | (defsubst timeclock-current-debt (&optional log-data) | ||
| 770 | (nth 0 (or log-data (timeclock-log-data)))) | ||
| 771 | |||
| 772 | (defsubst timeclock-day-alist (&optional log-data) | ||
| 773 | (nth 1 (or log-data (timeclock-log-data)))) | ||
| 774 | |||
| 775 | (defun timeclock-day-list (&optional log-data) | ||
| 776 | (let ((alist (timeclock-day-alist log-data)) | ||
| 777 | day-list) | ||
| 778 | (while alist | ||
| 779 | (setq day-list (cons (cdar alist) day-list) | ||
| 780 | alist (cdr alist))) | ||
| 781 | day-list)) | ||
| 782 | |||
| 783 | (defsubst timeclock-project-alist (&optional log-data) | ||
| 784 | (nth 2 (or log-data (timeclock-log-data)))) | ||
| 785 | |||
| 786 | |||
| 787 | (defun timeclock-log-data (&optional recent-only filename) | ||
| 788 | "Return the contents of the timelog file, in a useful format. | ||
| 789 | A timelog contains data in the form of a single entry per line. | ||
| 790 | Each entry has the form: | ||
| 791 | |||
| 792 | CODE YYYY/MM/DD HH:MM:SS [COMMENT] | ||
| 793 | |||
| 794 | CODE is one of: b, h, i, o or O. COMMENT is optional when the code is | ||
| 795 | i, o or O. The meanings of the codes are: | ||
| 796 | |||
| 797 | b Set the current time balance, or \"time debt\". Useful when | ||
| 798 | archiving old log data, when a debt must be carried forward. | ||
| 799 | The COMMENT here is the number of seconds of debt. | ||
| 800 | |||
| 801 | h Set the required working time for the given day. This must | ||
| 802 | be the first entry for that day. The COMMENT in this case is | ||
| 803 | the number of hours that must be worked. Floating point | ||
| 804 | amounts are allowed. | ||
| 805 | |||
| 806 | i Clock in. The COMMENT in this case should be the name of the | ||
| 807 | project worked on. | ||
| 808 | |||
| 809 | o Clock out. COMMENT is unnecessary, but can be used to provide | ||
| 810 | a description of how the period went, for example. | ||
| 811 | |||
| 812 | O Final clock out. Whatever project was being worked on, it is | ||
| 813 | now finished. Useful for creating summary reports. | ||
| 814 | |||
| 815 | When this function is called, it will return a data structure with the | ||
| 816 | following format: | ||
| 817 | |||
| 818 | (DEBT ENTRIES-BY-DAY ENTRIES-BY-PROJECT) | ||
| 819 | |||
| 820 | DEBT is a floating point number representing the number of seconds | ||
| 821 | \"owed\" before any work was done. For a new file (one without a 'b' | ||
| 822 | entry), this is always zero. | ||
| 823 | |||
| 824 | The two entries lists have similar formats. They are both alists, | ||
| 825 | where the CAR is the index, and the CDR is a list of time entries. | ||
| 826 | For ENTRIES-BY-DAY, the CAR is a textual date string, of the form | ||
| 827 | YYYY/MM/DD. For ENTRIES-BY-PROJECT, it is the name of the project | ||
| 828 | worked on, or t for the default project. | ||
| 829 | |||
| 830 | The CDR for ENTRIES-BY-DAY is slightly different than for | ||
| 831 | ENTRIES-BY-PROJECT. It has the following form: | ||
| 832 | |||
| 833 | (DAY-LENGTH TIME-ENTRIES...) | ||
| 834 | |||
| 835 | For ENTRIES-BY-PROJECT, there is no DAY-LENGTH member. It is simply a | ||
| 836 | list of TIME-ENTRIES. Note that if DAY-LENGTH is nil, it means | ||
| 837 | whatever is the default should be used. | ||
| 838 | |||
| 839 | A TIME-ENTRY is a recorded time interval. It has the following format | ||
| 840 | \(although generally one does not have to manipulate these entries | ||
| 841 | directly; see below): | ||
| 842 | |||
| 843 | (BEGIN-TIME END-TIME PROJECT [COMMENT] [FINAL-P]) | ||
| 844 | |||
| 845 | Anyway, suffice it to say there are a lot of structures. Typically | ||
| 846 | the user is expected to manipulate to the day(s) or project(s) that he | ||
| 847 | or she wants, at which point the following helper functions may be | ||
| 848 | used: | ||
| 849 | |||
| 850 | timeclock-day-required | ||
| 851 | timeclock-day-length | ||
| 852 | timeclock-day-debt | ||
| 853 | timeclock-day-begin | ||
| 854 | timeclock-day-end | ||
| 855 | timeclock-day-span | ||
| 856 | timeclock-day-break | ||
| 857 | timeclock-day-projects | ||
| 858 | |||
| 859 | timeclock-day-list-required | ||
| 860 | timeclock-day-list-length | ||
| 861 | timeclock-day-list-debt | ||
| 862 | timeclock-day-list-begin | ||
| 863 | timeclock-day-list-end | ||
| 864 | timeclock-day-list-span | ||
| 865 | timeclock-day-list-break | ||
| 866 | timeclock-day-list-projects | ||
| 867 | |||
| 868 | timeclock-entry-length | ||
| 869 | timeclock-entry-begin | ||
| 870 | timeclock-entry-end | ||
| 871 | timeclock-entry-project | ||
| 872 | timeclock-entry-comment | ||
| 873 | |||
| 874 | timeclock-entry-list-length | ||
| 875 | timeclock-entry-list-begin | ||
| 876 | timeclock-entry-list-end | ||
| 877 | timeclock-entry-list-span | ||
| 878 | timeclock-entry-list-break | ||
| 879 | timeclock-entry-list-projects | ||
| 880 | |||
| 881 | A few comments should make the use of the above functions obvious: | ||
| 882 | |||
| 883 | `required' is the amount of time that must be spent during a day, or | ||
| 884 | sequence of days, in order to have no debt. | ||
| 885 | |||
| 886 | `length' is the actual amount of time that was spent. | ||
| 887 | |||
| 888 | `debt' is the difference between required time and length. A | ||
| 889 | negative debt signifies overtime. | ||
| 890 | |||
| 891 | `begin' is the earliest moment at which work began. | ||
| 892 | |||
| 893 | `end' is the final moment work was done. | ||
| 894 | |||
| 895 | `span' is the difference between begin and end. | ||
| 896 | |||
| 897 | `break' is the difference between span and length. | ||
| 898 | |||
| 899 | `project' is the project that was worked on, and `projects' is a | ||
| 900 | list of all the projects that were worked on during a given period. | ||
| 901 | |||
| 902 | `comment', where it applies, could mean anything. | ||
| 903 | |||
| 904 | There are a few more functions available, for locating day and entry | ||
| 905 | lists: | ||
| 906 | |||
| 907 | timeclock-day-alist LOG-DATA | ||
| 908 | timeclock-project-alist LOG-DATA | ||
| 909 | timeclock-current-debt LOG-DATA | ||
| 910 | |||
| 911 | See the documentation for the given function if more info is needed." | ||
| 912 | (let* ((log-data (list 0.0 nil nil)) | ||
| 913 | (now (current-time)) | ||
| 914 | (todays-date (timeclock-time-to-date now)) | ||
| 915 | last-date-limited last-date-seconds last-date | ||
| 916 | (line 0) last beg day entry) | ||
| 917 | (with-temp-buffer | ||
| 918 | (insert-file-contents (or filename timeclock-file)) | ||
| 919 | (when recent-only | ||
| 920 | (goto-char (point-max)) | ||
| 921 | (unless (re-search-backward "^b\\s-+" nil t) | ||
| 922 | (goto-char (point-min)))) | ||
| 923 | (while (or (setq event (timeclock-read-moment)) | ||
| 924 | (and beg (not last) | ||
| 925 | (setq last t event (list "o" now)))) | ||
| 926 | (setq line (1+ line)) | ||
| 927 | (cond ((equal (car event) "b") | ||
| 928 | (setcar log-data (string-to-number (nth 2 event)))) | ||
| 929 | ((equal (car event) "h") | ||
| 930 | (setq last-date-limited (timeclock-time-to-date (cadr event)) | ||
| 931 | last-date-seconds (* (string-to-number (nth 2 event)) | ||
| 932 | 3600.0))) | ||
| 933 | ((equal (car event) "i") | ||
| 934 | (if beg | ||
| 935 | (error "Error in format of timelog file, line %d" line) | ||
| 936 | (setq beg t)) | ||
| 937 | (setq entry (list (cadr event) nil | ||
| 938 | (and (> (length (nth 2 event)) 0) | ||
| 939 | (nth 2 event)))) | ||
| 940 | (let ((date (timeclock-time-to-date (cadr event)))) | ||
| 941 | (if (and last-date | ||
| 942 | (not (equal date last-date))) | ||
| 943 | (setcar (cdr log-data) | ||
| 944 | (cons (cons last-date day) | ||
| 945 | (cadr log-data))) | ||
| 946 | (setq day (list (and last-date-limited | ||
| 947 | last-date-seconds)))) | ||
| 948 | (setq last-date date | ||
| 949 | last-date-limited nil))) | ||
| 950 | ((equal (downcase (car event)) "o") | ||
| 951 | (if (not beg) | ||
| 952 | (error "Error in format of timelog file, line %d" line) | ||
| 953 | (setq beg nil)) | ||
| 954 | (setcar (cdr entry) (cadr event)) | ||
| 955 | (let ((desc (and (> (length (nth 2 event)) 0) | ||
| 956 | (nth 2 event)))) | ||
| 957 | (if desc | ||
| 958 | (nconc entry (list (nth 2 event)))) | ||
| 959 | (if (equal (car event) "O") | ||
| 960 | (nconc entry (if desc | ||
| 961 | (list t) | ||
| 962 | (list nil t)))) | ||
| 963 | (nconc day (list entry)) | ||
| 964 | (setq desc (nth 2 entry)) | ||
| 965 | (let ((proj (assoc desc (nth 2 log-data)))) | ||
| 966 | (if (not proj) | ||
| 967 | (setcar (cddr log-data) | ||
| 968 | (cons (cons desc (list entry)) | ||
| 969 | (car (cddr log-data)))) | ||
| 970 | (nconc (cdr proj) (list entry))))))) | ||
| 971 | (forward-line)) | ||
| 972 | (if day | ||
| 973 | (setcar (cdr log-data) | ||
| 974 | (cons (cons last-date day) | ||
| 975 | (cadr log-data)))) | ||
| 976 | log-data))) | ||
| 977 | |||
| 658 | (defun timeclock-find-discrep (&optional today-only) | 978 | (defun timeclock-find-discrep (&optional today-only) |
| 659 | "Find overall discrepancy from `timeclock-workday' (in seconds). | 979 | "Find overall discrepancy from `timeclock-workday' (in seconds). |
| 660 | If TODAY-ONLY is non-nil, the discrepancy will be not be relative, and | 980 | If TODAY-ONLY is non-nil, the discrepancy will be not be relative, and |
| 661 | will correspond only to the amount of time elapsed today. This is | 981 | will correspond only to the amount of time elapsed today. This is |
| 662 | identical to what would be return if `timeclock-relative' were nil." | 982 | identical to what would be return if `timeclock-relative' were nil." |
| 663 | (let* ((now (current-time)) (first t) | 983 | ;; This is not implemented in terms of the functions above, because |
| 984 | ;; it's a bit wasteful to read all of that data in, just to throw | ||
| 985 | ;; away more than 90% of the information afterwards. | ||
| 986 | (let* ((now (current-time)) | ||
| 664 | (todays-date (timeclock-time-to-date now)) | 987 | (todays-date (timeclock-time-to-date now)) |
| 665 | accum event beg last-date | 988 | (first t) (accum 0) |
| 666 | last-date-limited last-date-seconds avg) | 989 | event beg last-date avg |
| 990 | last-date-limited last-date-seconds) | ||
| 667 | (unless timeclock-discrepancy | 991 | (unless timeclock-discrepancy |
| 668 | (setq timeclock-project-list nil | 992 | (setq timeclock-project-list nil |
| 669 | timeclock-last-project nil | 993 | timeclock-last-project nil |
| 670 | timeclock-reason-list nil) | 994 | timeclock-reason-list nil |
| 671 | (save-excursion | 995 | timeclock-elapsed 0) |
| 672 | (set-buffer (find-file-noselect timeclock-file)) | 996 | (with-temp-buffer |
| 673 | (goto-char (point-min)) | 997 | (insert-file-contents timeclock-file) |
| 674 | (setq accum 0) | 998 | (goto-char (point-max)) |
| 675 | (setq timeclock-elapsed 0) | 999 | (unless (re-search-backward "^b\\s-+" nil t) |
| 1000 | (goto-char (point-min))) | ||
| 676 | (while (setq event (timeclock-read-moment)) | 1001 | (while (setq event (timeclock-read-moment)) |
| 677 | (cond ((equal (car event) "h") | 1002 | (cond ((equal (car event) "b") |
| 1003 | (setq accum (string-to-number (nth 2 event)))) | ||
| 1004 | ((equal (car event) "h") | ||
| 678 | (setq last-date-limited | 1005 | (setq last-date-limited |
| 679 | (timeclock-time-to-date (cadr event)) | 1006 | (timeclock-time-to-date (cadr event)) |
| 680 | last-date-seconds | 1007 | last-date-seconds |
| 681 | (* (string-to-number (nth 2 event)) 3600))) | 1008 | (* (string-to-number (nth 2 event)) 3600.0))) |
| 682 | ((equal (car event) "i") | 1009 | ((equal (car event) "i") |
| 683 | (when (and (nth 2 event) | 1010 | (when (and (nth 2 event) |
| 684 | (> (length (nth 2 event)) 0)) | 1011 | (> (length (nth 2 event)) 0)) |
| 685 | (add-to-list 'timeclock-project-list (nth 2 event)) | 1012 | (add-to-list 'timeclock-project-list (nth 2 event)) |
| 686 | (setq timeclock-last-project (nth 2 event))) | 1013 | (setq timeclock-last-project (nth 2 event))) |
| 687 | (let ((date (timeclock-time-to-date (cadr event)))) | 1014 | (let ((date (timeclock-time-to-date (cadr event)))) |
| 688 | (if (and last-date | 1015 | (if (and timeclock-relative |
| 689 | timeclock-relative | 1016 | (if last-date |
| 690 | (not (equal date last-date))) | 1017 | (not (equal date last-date)) |
| 691 | (setq accum (- accum | 1018 | first)) |
| 692 | (if last-date-limited | ||
| 693 | last-date-seconds | ||
| 694 | timeclock-workday))) | ||
| 695 | (unless (or last-date (not first)) | ||
| 696 | (setq first nil | 1019 | (setq first nil |
| 697 | accum (- accum | 1020 | accum (- accum |
| 698 | (if last-date-limited | 1021 | (if last-date-limited |
| 699 | last-date-seconds | 1022 | last-date-seconds |
| 700 | timeclock-workday))))) | 1023 | timeclock-workday)))) |
| 701 | (setq last-date date | 1024 | (setq last-date date |
| 702 | last-date-limited nil) | 1025 | last-date-limited nil) |
| 703 | (if beg | 1026 | (if beg |
| @@ -712,8 +1035,7 @@ identical to what would be return if `timeclock-relative' were nil." | |||
| 712 | (if (not beg) | 1035 | (if (not beg) |
| 713 | (error "Error in format of timelog file!") | 1036 | (error "Error in format of timelog file!") |
| 714 | (setq timeclock-last-period | 1037 | (setq timeclock-last-period |
| 715 | (- (timeclock-time-to-seconds (cadr event)) | 1038 | (- (timeclock-time-to-seconds (cadr event)) beg) |
| 716 | beg) | ||
| 717 | accum (+ timeclock-last-period accum) | 1039 | accum (+ timeclock-last-period accum) |
| 718 | beg nil))) | 1040 | beg nil))) |
| 719 | (if (equal last-date todays-date) | 1041 | (if (equal last-date todays-date) |
diff --git a/lisp/eshell/em-alias.el b/lisp/eshell/em-alias.el index 85e4e97e692..a407bf5deb8 100644 --- a/lisp/eshell/em-alias.el +++ b/lisp/eshell/em-alias.el | |||
| @@ -151,7 +151,12 @@ command, which will automatically write them to the file named by | |||
| 151 | (add-hook 'eshell-alternate-command-hook 'eshell-fix-bad-commands t t) | 151 | (add-hook 'eshell-alternate-command-hook 'eshell-fix-bad-commands t t) |
| 152 | (eshell-read-aliases-list) | 152 | (eshell-read-aliases-list) |
| 153 | (make-local-hook 'eshell-named-command-hook) | 153 | (make-local-hook 'eshell-named-command-hook) |
| 154 | (add-hook 'eshell-named-command-hook 'eshell-maybe-replace-by-alias t t)) | 154 | (add-hook 'eshell-named-command-hook 'eshell-maybe-replace-by-alias t t) |
| 155 | (make-local-variable 'eshell-complex-commands) | ||
| 156 | (add-to-list 'eshell-complex-commands 'eshell-command-aliased-p)) | ||
| 157 | |||
| 158 | (defun eshell-command-aliased-p (name) | ||
| 159 | (member name eshell-command-aliases-list)) | ||
| 155 | 160 | ||
| 156 | (defun eshell/alias (&optional alias &rest definition) | 161 | (defun eshell/alias (&optional alias &rest definition) |
| 157 | "Define an ALIAS in the user's alias list using DEFINITION." | 162 | "Define an ALIAS in the user's alias list using DEFINITION." |
diff --git a/lisp/eshell/em-dirs.el b/lisp/eshell/em-dirs.el index 02d1eb3076b..0c147f14be6 100644 --- a/lisp/eshell/em-dirs.el +++ b/lisp/eshell/em-dirs.el | |||
| @@ -297,7 +297,7 @@ Thus, this does not include the current directory.") | |||
| 297 | (file-name-as-directory (cdr user)))) | 297 | (file-name-as-directory (cdr user)))) |
| 298 | eshell-user-names))))))) | 298 | eshell-user-names))))))) |
| 299 | 299 | ||
| 300 | (defun eshell/pwd (&rest args) ; ignored | 300 | (defun eshell/pwd (&rest args) |
| 301 | "Change output from `pwd` to be cleaner." | 301 | "Change output from `pwd` to be cleaner." |
| 302 | (let* ((path default-directory) | 302 | (let* ((path default-directory) |
| 303 | (len (length path))) | 303 | (len (length path))) |
| @@ -307,8 +307,8 @@ Thus, this does not include the current directory.") | |||
| 307 | (string-match "\\`[A-Za-z]:[\\\\/]\\'" path)))) | 307 | (string-match "\\`[A-Za-z]:[\\\\/]\\'" path)))) |
| 308 | (setq path (substring path 0 (1- (length path))))) | 308 | (setq path (substring path 0 (1- (length path))))) |
| 309 | (if eshell-pwd-convert-function | 309 | (if eshell-pwd-convert-function |
| 310 | (setq path (funcall eshell-pwd-convert-function path))) | 310 | (funcall eshell-pwd-convert-function path) |
| 311 | path)) | 311 | path))) |
| 312 | 312 | ||
| 313 | (defun eshell-expand-multiple-dots (path) | 313 | (defun eshell-expand-multiple-dots (path) |
| 314 | "Convert '...' to '../..', '....' to '../../..', etc.. | 314 | "Convert '...' to '../..', '....' to '../../..', etc.. |
diff --git a/lisp/eshell/em-glob.el b/lisp/eshell/em-glob.el index b281cee4fd7..f4f9ebbe5b6 100644 --- a/lisp/eshell/em-glob.el +++ b/lisp/eshell/em-glob.el | |||
| @@ -81,8 +81,9 @@ by zsh for filename generation." | |||
| 81 | :type 'boolean | 81 | :type 'boolean |
| 82 | :group 'eshell-glob) | 82 | :group 'eshell-glob) |
| 83 | 83 | ||
| 84 | (defcustom eshell-glob-show-progress t | 84 | (defcustom eshell-glob-show-progress nil |
| 85 | "*If non-nil, display progress messages during a recursive glob." | 85 | "*If non-nil, display progress messages during a recursive glob. |
| 86 | This option slows down recursive glob processing by quite a bit." | ||
| 86 | :type 'boolean | 87 | :type 'boolean |
| 87 | :group 'eshell-glob) | 88 | :group 'eshell-glob) |
| 88 | 89 | ||
diff --git a/lisp/eshell/em-ls.el b/lisp/eshell/em-ls.el index 2afef625f55..534ea932c3c 100644 --- a/lisp/eshell/em-ls.el +++ b/lisp/eshell/em-ls.el | |||
| @@ -57,6 +57,12 @@ properties to colorize its output based on the setting of | |||
| 57 | :type 'hook | 57 | :type 'hook |
| 58 | :group 'eshell-ls) | 58 | :group 'eshell-ls) |
| 59 | 59 | ||
| 60 | (defcustom eshell-ls-initial-args nil | ||
| 61 | "*If non-nil, this list of args is included before any call to `ls'. | ||
| 62 | This is useful for enabling human-readable format (-h), for example." | ||
| 63 | :type '(repeat :tag "Arguments" string) | ||
| 64 | :group 'eshell-ls) | ||
| 65 | |||
| 60 | (defcustom eshell-ls-use-in-dired nil | 66 | (defcustom eshell-ls-use-in-dired nil |
| 61 | "*If non-nil, use `eshell-ls' to read directories in dired." | 67 | "*If non-nil, use `eshell-ls' to read directories in dired." |
| 62 | :set (lambda (symbol value) | 68 | :set (lambda (symbol value) |
| @@ -77,11 +83,18 @@ properties to colorize its output based on the setting of | |||
| 77 | :type 'integer | 83 | :type 'integer |
| 78 | :group 'eshell-ls) | 84 | :group 'eshell-ls) |
| 79 | 85 | ||
| 80 | (defcustom eshell-ls-exclude-regexp "\\`\\." | 86 | (defcustom eshell-ls-exclude-regexp nil |
| 81 | "*Unless -a is specified, files matching this regexp will not be shown." | 87 | "*Unless -a is specified, files matching this regexp will not be shown." |
| 82 | :type 'regexp | 88 | :type 'regexp |
| 83 | :group 'eshell-ls) | 89 | :group 'eshell-ls) |
| 84 | 90 | ||
| 91 | (defcustom eshell-ls-exclude-hidden t | ||
| 92 | "*Unless -a is specified, files beginning with . will not be shown. | ||
| 93 | Using this boolean, instead of `eshell-ls-exclude-regexp', is both | ||
| 94 | faster and conserves more memory." | ||
| 95 | :type 'boolean | ||
| 96 | :group 'eshell-ls) | ||
| 97 | |||
| 85 | (defcustom eshell-ls-use-colors t | 98 | (defcustom eshell-ls-use-colors t |
| 86 | "*If non-nil, use colors in file listings." | 99 | "*If non-nil, use colors in file listings." |
| 87 | :type 'boolean | 100 | :type 'boolean |
| @@ -196,13 +209,13 @@ This is really just for efficiency, to avoid having to stat the file | |||
| 196 | yet again." | 209 | yet again." |
| 197 | `(if (numberp (nth 2 ,attrs)) | 210 | `(if (numberp (nth 2 ,attrs)) |
| 198 | (if (= (user-uid) (nth 2 ,attrs)) | 211 | (if (= (user-uid) (nth 2 ,attrs)) |
| 199 | (not (eq (aref (nth 8 ,attrs) ,index) ?-)) | 212 | (not (eq (aref (nth 8 ,attrs) ,index) ?-)) |
| 200 | (,(eval func) ,file)) | 213 | (,(eval func) ,file)) |
| 201 | (not (eq (aref (nth 8 ,attrs) | 214 | (not (eq (aref (nth 8 ,attrs) |
| 202 | (+ ,index (if (member (nth 2 ,attrs) | 215 | (+ ,index (if (member (nth 2 ,attrs) |
| 203 | (eshell-current-ange-uids)) | 216 | (eshell-current-ange-uids)) |
| 204 | 0 6))) | 217 | 0 6))) |
| 205 | ?-)))) | 218 | ?-)))) |
| 206 | 219 | ||
| 207 | (defcustom eshell-ls-highlight-alist nil | 220 | (defcustom eshell-ls-highlight-alist nil |
| 208 | "*This alist correlates test functions to color. | 221 | "*This alist correlates test functions to color. |
| @@ -248,7 +261,8 @@ instead." | |||
| 248 | (symbol-value 'font-lock-buffers))))) | 261 | (symbol-value 'font-lock-buffers))))) |
| 249 | (let ((insert-func 'insert) | 262 | (let ((insert-func 'insert) |
| 250 | (error-func 'insert) | 263 | (error-func 'insert) |
| 251 | (flush-func 'ignore)) | 264 | (flush-func 'ignore) |
| 265 | eshell-ls-initial-args) | ||
| 252 | (eshell-do-ls (append switches (list file)))))))) | 266 | (eshell-do-ls (append switches (list file)))))))) |
| 253 | 267 | ||
| 254 | (defsubst eshell/ls (&rest args) | 268 | (defsubst eshell/ls (&rest args) |
| @@ -281,7 +295,9 @@ instead." | |||
| 281 | (funcall flush-func -1) | 295 | (funcall flush-func -1) |
| 282 | ;; process the command arguments, and begin listing files | 296 | ;; process the command arguments, and begin listing files |
| 283 | (eshell-eval-using-options | 297 | (eshell-eval-using-options |
| 284 | "ls" args | 298 | "ls" (if eshell-ls-initial-args |
| 299 | (list eshell-ls-initial-args args) | ||
| 300 | args) | ||
| 285 | `((?a "all" nil show-all | 301 | `((?a "all" nil show-all |
| 286 | "show all files in directory") | 302 | "show all files in directory") |
| 287 | (?c nil by-ctime sort-method | 303 | (?c nil by-ctime sort-method |
| @@ -343,11 +359,11 @@ Sort entries alphabetically across.") | |||
| 343 | (error (concat "-I option requires that `eshell-glob'" | 359 | (error (concat "-I option requires that `eshell-glob'" |
| 344 | " be a member of `eshell-modules-list'"))) | 360 | " be a member of `eshell-modules-list'"))) |
| 345 | (set-text-properties 0 (length ignore-pattern) nil ignore-pattern) | 361 | (set-text-properties 0 (length ignore-pattern) nil ignore-pattern) |
| 346 | (if eshell-ls-exclude-regexp | 362 | (setq eshell-ls-exclude-regexp |
| 347 | (setq eshell-ls-exclude-regexp | 363 | (if eshell-ls-exclude-regexp |
| 348 | (concat "\\(" eshell-ls-exclude-regexp "\\|" | 364 | (concat "\\(" eshell-ls-exclude-regexp "\\|" |
| 349 | (eshell-glob-regexp ignore-pattern) "\\)")) | 365 | (eshell-glob-regexp ignore-pattern) "\\)") |
| 350 | (setq eshell-ls-exclude-regexp (eshell-glob-regexp ignore-pattern)))) | 366 | (eshell-glob-regexp ignore-pattern)))) |
| 351 | ;; list the files! | 367 | ;; list the files! |
| 352 | (eshell-ls-entries | 368 | (eshell-ls-entries |
| 353 | (mapcar (function | 369 | (mapcar (function |
| @@ -356,7 +372,8 @@ Sort entries alphabetically across.") | |||
| 356 | (file-name-absolute-p arg)) | 372 | (file-name-absolute-p arg)) |
| 357 | (expand-file-name arg) | 373 | (expand-file-name arg) |
| 358 | arg) | 374 | arg) |
| 359 | (eshell-file-attributes arg)))) args) | 375 | (eshell-file-attributes arg)))) |
| 376 | args) | ||
| 360 | t (expand-file-name default-directory))) | 377 | t (expand-file-name default-directory))) |
| 361 | (funcall flush-func))) | 378 | (funcall flush-func))) |
| 362 | 379 | ||
| @@ -491,12 +508,13 @@ relative to that directory." | |||
| 491 | (file-relative-name dir root-dir) | 508 | (file-relative-name dir root-dir) |
| 492 | (expand-file-name dir))) | 509 | (expand-file-name dir))) |
| 493 | (cdr dirinfo))) ":\n")) | 510 | (cdr dirinfo))) ":\n")) |
| 494 | (let ((entries | 511 | (let ((entries (eshell-directory-files-and-attributes |
| 495 | (eshell-directory-files-and-attributes dir nil nil t))) | 512 | dir nil (and (not show-all) |
| 496 | (unless show-all | 513 | eshell-ls-exclude-hidden |
| 497 | (while (and entries | 514 | "\\`[^.]") t))) |
| 498 | (string-match eshell-ls-exclude-regexp | 515 | (when (and (not show-all) eshell-ls-exclude-regexp) |
| 499 | (caar entries))) | 516 | (while (and entries (string-match eshell-ls-exclude-regexp |
| 517 | (caar entries))) | ||
| 500 | (setq entries (cdr entries))) | 518 | (setq entries (cdr entries))) |
| 501 | (let ((e entries)) | 519 | (let ((e entries)) |
| 502 | (while (cdr e) | 520 | (while (cdr e) |
| @@ -552,17 +570,13 @@ In Eshell's implementation of ls, ENTRIES is always reversed." | |||
| 552 | (let ((result | 570 | (let ((result |
| 553 | (cond | 571 | (cond |
| 554 | ((eq sort-method 'by-atime) | 572 | ((eq sort-method 'by-atime) |
| 555 | (eshell-ls-compare-entries | 573 | (eshell-ls-compare-entries l r 4 'eshell-time-less-p)) |
| 556 | l r 4 'eshell-time-less-p)) | ||
| 557 | ((eq sort-method 'by-mtime) | 574 | ((eq sort-method 'by-mtime) |
| 558 | (eshell-ls-compare-entries | 575 | (eshell-ls-compare-entries l r 5 'eshell-time-less-p)) |
| 559 | l r 5 'eshell-time-less-p)) | ||
| 560 | ((eq sort-method 'by-ctime) | 576 | ((eq sort-method 'by-ctime) |
| 561 | (eshell-ls-compare-entries | 577 | (eshell-ls-compare-entries l r 6 'eshell-time-less-p)) |
| 562 | l r 6 'eshell-time-less-p)) | ||
| 563 | ((eq sort-method 'by-size) | 578 | ((eq sort-method 'by-size) |
| 564 | (eshell-ls-compare-entries | 579 | (eshell-ls-compare-entries l r 7 '<)) |
| 565 | l r 7 '<)) | ||
| 566 | ((eq sort-method 'by-extension) | 580 | ((eq sort-method 'by-extension) |
| 567 | (let ((lx (file-name-extension | 581 | (let ((lx (file-name-extension |
| 568 | (directory-file-name (car l)))) | 582 | (directory-file-name (car l)))) |
| @@ -699,8 +713,8 @@ need to be printed." | |||
| 699 | (if (and need-return (not dir-literal)) | 713 | (if (and need-return (not dir-literal)) |
| 700 | (funcall insert-func "\n")) | 714 | (funcall insert-func "\n")) |
| 701 | (eshell-ls-dir dir show-names | 715 | (eshell-ls-dir dir show-names |
| 702 | (unless (file-name-absolute-p (car dir)) | 716 | (unless (file-name-absolute-p (car dir)) root-dir) |
| 703 | root-dir) size-width) | 717 | size-width) |
| 704 | (setq need-return t)))) | 718 | (setq need-return t)))) |
| 705 | 719 | ||
| 706 | (defun eshell-ls-find-column-widths (files) | 720 | (defun eshell-ls-find-column-widths (files) |
diff --git a/lisp/eshell/em-script.el b/lisp/eshell/em-script.el index d6a8ea54e2f..8967426cadf 100644 --- a/lisp/eshell/em-script.el +++ b/lisp/eshell/em-script.el | |||
| @@ -63,6 +63,9 @@ This includes when running `eshell-command'." | |||
| 63 | (string= (file-name-nondirectory file) | 63 | (string= (file-name-nondirectory file) |
| 64 | "eshell")) . eshell/source) | 64 | "eshell")) . eshell/source) |
| 65 | eshell-interpreter-alist)) | 65 | eshell-interpreter-alist)) |
| 66 | (make-local-variable 'eshell-complex-commands) | ||
| 67 | (setq eshell-complex-commands | ||
| 68 | (append '("source" ".") eshell-complex-commands)) | ||
| 66 | ;; these two variables are changed through usage, but we don't want | 69 | ;; these two variables are changed through usage, but we don't want |
| 67 | ;; to ruin it for other modules | 70 | ;; to ruin it for other modules |
| 68 | (let (eshell-inside-quote-regexp | 71 | (let (eshell-inside-quote-regexp |
diff --git a/lisp/eshell/em-smart.el b/lisp/eshell/em-smart.el index cc02f2fedc3..9bef8b10d20 100644 --- a/lisp/eshell/em-smart.el +++ b/lisp/eshell/em-smart.el | |||
| @@ -77,6 +77,11 @@ it to get a real sense of how it works." | |||
| 77 | ;; scroll, etc. | 77 | ;; scroll, etc. |
| 78 | ;; | 78 | ;; |
| 79 | ;; @ Like I said, it's not really comprehensible until you try it! ;) | 79 | ;; @ Like I said, it's not really comprehensible until you try it! ;) |
| 80 | ;; | ||
| 81 | ;; One disadvantage of this module is that it increases Eshell's | ||
| 82 | ;; memory consumption by a factor of two or more. With small commands | ||
| 83 | ;; (such as pwd), where the screen is mostly full, consumption can | ||
| 84 | ;; increase by orders of magnitude. | ||
| 80 | 85 | ||
| 81 | ;;; User Variables: | 86 | ;;; User Variables: |
| 82 | 87 | ||
| @@ -154,6 +159,7 @@ The options are `begin', `after' or `end'." | |||
| 154 | 159 | ||
| 155 | (defvar eshell-smart-displayed nil) | 160 | (defvar eshell-smart-displayed nil) |
| 156 | (defvar eshell-smart-command-done nil) | 161 | (defvar eshell-smart-command-done nil) |
| 162 | (defvar eshell-currently-handling-window nil) | ||
| 157 | 163 | ||
| 158 | ;;; Functions: | 164 | ;;; Functions: |
| 159 | 165 | ||
| @@ -175,19 +181,17 @@ The options are `begin', `after' or `end'." | |||
| 175 | 181 | ||
| 176 | (make-local-hook 'pre-command-hook) | 182 | (make-local-hook 'pre-command-hook) |
| 177 | (make-local-hook 'after-change-functions) | 183 | (make-local-hook 'after-change-functions) |
| 178 | (add-hook 'after-change-functions | 184 | (add-hook 'after-change-functions 'eshell-disable-after-change nil t) |
| 179 | 'eshell-disable-after-change nil t) | ||
| 180 | 185 | ||
| 181 | (make-local-hook 'eshell-input-filter-functions) | 186 | (make-local-hook 'eshell-input-filter-functions) |
| 182 | (add-hook 'eshell-input-filter-functions | 187 | (add-hook 'eshell-input-filter-functions 'eshell-smart-display-setup nil t) |
| 183 | 'eshell-smart-display-setup nil t) | ||
| 184 | 188 | ||
| 185 | (make-local-variable 'eshell-smart-command-done) | 189 | (make-local-variable 'eshell-smart-command-done) |
| 186 | (make-local-hook 'eshell-post-command-hook) | 190 | (make-local-hook 'eshell-post-command-hook) |
| 187 | (add-hook 'eshell-post-command-hook | 191 | (add-hook 'eshell-post-command-hook |
| 188 | (function | 192 | (function |
| 189 | (lambda () | 193 | (lambda () |
| 190 | (setq eshell-smart-command-done t))) t t) | 194 | (setq eshell-smart-command-done t))) t t) |
| 191 | 195 | ||
| 192 | (unless (eq eshell-review-quick-commands t) | 196 | (unless (eq eshell-review-quick-commands t) |
| 193 | (add-hook 'eshell-post-command-hook | 197 | (add-hook 'eshell-post-command-hook |
| @@ -198,10 +202,9 @@ The options are `begin', `after' or `end'." | |||
| 198 | (unless eshell-currently-handling-window | 202 | (unless eshell-currently-handling-window |
| 199 | (let ((inhibit-point-motion-hooks t) | 203 | (let ((inhibit-point-motion-hooks t) |
| 200 | (eshell-currently-handling-window t)) | 204 | (eshell-currently-handling-window t)) |
| 201 | (save-current-buffer | 205 | (save-selected-window |
| 202 | (save-selected-window | 206 | (select-window wind) |
| 203 | (select-window wind) | 207 | (eshell-smart-redisplay))))) |
| 204 | (eshell-smart-redisplay)))))) | ||
| 205 | 208 | ||
| 206 | (defun eshell-refresh-windows (&optional frame) | 209 | (defun eshell-refresh-windows (&optional frame) |
| 207 | "Refresh all visible Eshell buffers." | 210 | "Refresh all visible Eshell buffers." |
| @@ -210,10 +213,10 @@ The options are `begin', `after' or `end'." | |||
| 210 | (function | 213 | (function |
| 211 | (lambda (wind) | 214 | (lambda (wind) |
| 212 | (with-current-buffer (window-buffer wind) | 215 | (with-current-buffer (window-buffer wind) |
| 213 | (when eshell-mode | 216 | (if eshell-mode |
| 214 | (let (window-scroll-functions) | 217 | (let (window-scroll-functions) |
| 215 | (eshell-smart-scroll-window wind (window-start)) | 218 | (eshell-smart-scroll-window wind (window-start)) |
| 216 | (setq affected t)))))) | 219 | (setq affected t)))))) |
| 217 | 0 frame) | 220 | 0 frame) |
| 218 | (if affected | 221 | (if affected |
| 219 | (let (window-scroll-functions) | 222 | (let (window-scroll-functions) |
diff --git a/lisp/eshell/em-unix.el b/lisp/eshell/em-unix.el index 7f0414ef056..c9b3d418b83 100644 --- a/lisp/eshell/em-unix.el +++ b/lisp/eshell/em-unix.el | |||
| @@ -124,6 +124,11 @@ Otherwise, `rmdir' is required." | |||
| 124 | :type 'boolean | 124 | :type 'boolean |
| 125 | :group 'eshell-unix) | 125 | :group 'eshell-unix) |
| 126 | 126 | ||
| 127 | (defcustom eshell-default-target-is-dot nil | ||
| 128 | "*If non-nil, the default destination for cp, mv or ln is `.'." | ||
| 129 | :type 'boolean | ||
| 130 | :group 'eshell-unix) | ||
| 131 | |||
| 127 | (defcustom eshell-du-prefer-over-ange nil | 132 | (defcustom eshell-du-prefer-over-ange nil |
| 128 | "*Use Eshell's du in ange-ftp remote directories. | 133 | "*Use Eshell's du in ange-ftp remote directories. |
| 129 | Otherwise, Emacs will attempt to use rsh to invoke du on the remote machine." | 134 | Otherwise, Emacs will attempt to use rsh to invoke du on the remote machine." |
| @@ -140,7 +145,12 @@ Otherwise, Emacs will attempt to use rsh to invoke du on the remote machine." | |||
| 140 | (when (eshell-using-module 'eshell-cmpl) | 145 | (when (eshell-using-module 'eshell-cmpl) |
| 141 | (make-local-hook 'pcomplete-try-first-hook) | 146 | (make-local-hook 'pcomplete-try-first-hook) |
| 142 | (add-hook 'pcomplete-try-first-hook | 147 | (add-hook 'pcomplete-try-first-hook |
| 143 | 'eshell-complete-host-reference nil t))) | 148 | 'eshell-complete-host-reference nil t)) |
| 149 | (make-local-variable 'eshell-complex-commands) | ||
| 150 | (setq eshell-complex-commands | ||
| 151 | (append '("grep" "egrep" "fgrep" "agrep" "glimpse" "locate" | ||
| 152 | "cat" "time" "cp" "mv" "make" "du" "diff") | ||
| 153 | eshell-complex-commands))) | ||
| 144 | 154 | ||
| 145 | (defalias 'eshell/date 'current-time-string) | 155 | (defalias 'eshell/date 'current-time-string) |
| 146 | (defalias 'eshell/basename 'file-name-nondirectory) | 156 | (defalias 'eshell/basename 'file-name-nondirectory) |
| @@ -157,6 +167,7 @@ Otherwise, Emacs will attempt to use rsh to invoke du on the remote machine." | |||
| 157 | (funcall 'man (apply 'eshell-flatten-and-stringify args))) | 167 | (funcall 'man (apply 'eshell-flatten-and-stringify args))) |
| 158 | 168 | ||
| 159 | (defun eshell-remove-entries (path files &optional top-level) | 169 | (defun eshell-remove-entries (path files &optional top-level) |
| 170 | "From PATH, remove all of the given FILES, perhaps interactively." | ||
| 160 | (while files | 171 | (while files |
| 161 | (if (string-match "\\`\\.\\.?\\'" | 172 | (if (string-match "\\`\\.\\.?\\'" |
| 162 | (file-name-nondirectory (car files))) | 173 | (file-name-nondirectory (car files))) |
| @@ -302,8 +313,6 @@ Remove the DIRECTORY(ies), if they are empty.") | |||
| 302 | 313 | ||
| 303 | (defun eshell-shuffle-files (command action files target func deep &rest args) | 314 | (defun eshell-shuffle-files (command action files target func deep &rest args) |
| 304 | "Shuffle around some filesystem entries, using FUNC to do the work." | 315 | "Shuffle around some filesystem entries, using FUNC to do the work." |
| 305 | (if (null target) | ||
| 306 | (error "%s: missing destination file" command)) | ||
| 307 | (let ((attr-target (eshell-file-attributes target)) | 316 | (let ((attr-target (eshell-file-attributes target)) |
| 308 | (is-dir (or (file-directory-p target) | 317 | (is-dir (or (file-directory-p target) |
| 309 | (and preview (not eshell-warn-dot-directories)))) | 318 | (and preview (not eshell-warn-dot-directories)))) |
| @@ -417,30 +426,35 @@ Remove the DIRECTORY(ies), if they are empty.") | |||
| 417 | (format "tar %s %s" tar-args archive) args)))) | 426 | (format "tar %s %s" tar-args archive) args)))) |
| 418 | 427 | ||
| 419 | ;; this is to avoid duplicating code... | 428 | ;; this is to avoid duplicating code... |
| 420 | (defmacro eshell-mvcp-template | 429 | (defmacro eshell-mvcpln-template (command action func query-var |
| 421 | (command action func query-var force-var &optional preserve) | 430 | force-var &optional preserve) |
| 422 | `(if (and (string-match eshell-tar-regexp (car (last args))) | 431 | `(let ((len (length args))) |
| 423 | (or (> (length args) 2) | 432 | (if (or (= len 0) |
| 424 | (and (file-directory-p (car args)) | 433 | (and (= len 1) (null eshell-default-target-is-dot))) |
| 425 | (or (not no-dereference) | 434 | (error "%s: missing destination file or directory" ,command)) |
| 426 | (not (file-symlink-p (car args))))))) | 435 | (if (= len 1) |
| 427 | (eshell-shorthand-tar-command ,command args) | 436 | (nconc args '("."))) |
| 428 | (let (target ange-cache) | 437 | (setq args (eshell-stringify-list (eshell-flatten-list args))) |
| 429 | (if (> (length args) 1) | 438 | (if (and ,(not (equal command "ln")) |
| 430 | (progn | 439 | (string-match eshell-tar-regexp (car (last args))) |
| 431 | (setq target (car (last args))) | 440 | (or (> (length args) 2) |
| 432 | (setcdr (last args 2) nil)) | 441 | (and (file-directory-p (car args)) |
| 433 | (setq args nil)) | 442 | (or (not no-dereference) |
| 434 | (eshell-shuffle-files | 443 | (not (file-symlink-p (car args))))))) |
| 435 | ,command ,action args target ,func nil | 444 | (eshell-shorthand-tar-command ,command args) |
| 436 | ,@(append | 445 | (let ((target (car (last args))) |
| 437 | `((if (and (or interactive | 446 | ange-cache) |
| 438 | ,query-var) | 447 | (setcdr (last args 2) nil) |
| 439 | (not force)) | 448 | (eshell-shuffle-files |
| 440 | 1 (or force ,force-var))) | 449 | ,command ,action args target ,func nil |
| 441 | (if preserve | 450 | ,@(append |
| 442 | (list preserve))))) | 451 | `((if (and (or interactive |
| 443 | nil)) | 452 | ,query-var) |
| 453 | (not force)) | ||
| 454 | 1 (or force ,force-var))) | ||
| 455 | (if preserve | ||
| 456 | (list preserve))))) | ||
| 457 | nil))) | ||
| 444 | 458 | ||
| 445 | (defun eshell/mv (&rest args) | 459 | (defun eshell/mv (&rest args) |
| 446 | "Implementation of mv in Lisp." | 460 | "Implementation of mv in Lisp." |
| @@ -455,6 +469,7 @@ Remove the DIRECTORY(ies), if they are empty.") | |||
| 455 | (?v "verbose" nil verbose | 469 | (?v "verbose" nil verbose |
| 456 | "explain what is being done") | 470 | "explain what is being done") |
| 457 | (nil "help" nil nil "show this usage screen") | 471 | (nil "help" nil nil "show this usage screen") |
| 472 | :preserve-args | ||
| 458 | :external "mv" | 473 | :external "mv" |
| 459 | :show-usage | 474 | :show-usage |
| 460 | :usage "[OPTION]... SOURCE DEST | 475 | :usage "[OPTION]... SOURCE DEST |
| @@ -462,9 +477,9 @@ Remove the DIRECTORY(ies), if they are empty.") | |||
| 462 | Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY. | 477 | Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY. |
| 463 | \[OPTION] DIRECTORY...") | 478 | \[OPTION] DIRECTORY...") |
| 464 | (let ((no-dereference t)) | 479 | (let ((no-dereference t)) |
| 465 | (eshell-mvcp-template "mv" "moving" 'rename-file | 480 | (eshell-mvcpln-template "mv" "moving" 'rename-file |
| 466 | eshell-mv-interactive-query | 481 | eshell-mv-interactive-query |
| 467 | eshell-mv-overwrite-files)))) | 482 | eshell-mv-overwrite-files)))) |
| 468 | 483 | ||
| 469 | (defun eshell/cp (&rest args) | 484 | (defun eshell/cp (&rest args) |
| 470 | "Implementation of cp in Lisp." | 485 | "Implementation of cp in Lisp." |
| @@ -487,6 +502,7 @@ Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY. | |||
| 487 | (?v "verbose" nil verbose | 502 | (?v "verbose" nil verbose |
| 488 | "explain what is being done") | 503 | "explain what is being done") |
| 489 | (nil "help" nil nil "show this usage screen") | 504 | (nil "help" nil nil "show this usage screen") |
| 505 | :preserve-args | ||
| 490 | :external "cp" | 506 | :external "cp" |
| 491 | :show-usage | 507 | :show-usage |
| 492 | :usage "[OPTION]... SOURCE DEST | 508 | :usage "[OPTION]... SOURCE DEST |
| @@ -494,9 +510,9 @@ Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY. | |||
| 494 | Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.") | 510 | Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.") |
| 495 | (if archive | 511 | (if archive |
| 496 | (setq preserve t no-dereference t recursive t)) | 512 | (setq preserve t no-dereference t recursive t)) |
| 497 | (eshell-mvcp-template "cp" "copying" 'copy-file | 513 | (eshell-mvcpln-template "cp" "copying" 'copy-file |
| 498 | eshell-cp-interactive-query | 514 | eshell-cp-interactive-query |
| 499 | eshell-cp-overwrite-files preserve))) | 515 | eshell-cp-overwrite-files preserve))) |
| 500 | 516 | ||
| 501 | (defun eshell/ln (&rest args) | 517 | (defun eshell/ln (&rest args) |
| 502 | "Implementation of ln in Lisp." | 518 | "Implementation of ln in Lisp." |
| @@ -505,11 +521,13 @@ Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.") | |||
| 505 | '((?h "help" nil nil "show this usage screen") | 521 | '((?h "help" nil nil "show this usage screen") |
| 506 | (?s "symbolic" nil symbolic | 522 | (?s "symbolic" nil symbolic |
| 507 | "make symbolic links instead of hard links") | 523 | "make symbolic links instead of hard links") |
| 508 | (?i "interactive" nil interactive "request confirmation if target already exists") | 524 | (?i "interactive" nil interactive |
| 525 | "request confirmation if target already exists") | ||
| 509 | (?f "force" nil force "remove existing destinations, never prompt") | 526 | (?f "force" nil force "remove existing destinations, never prompt") |
| 510 | (?n "preview" nil preview | 527 | (?n "preview" nil preview |
| 511 | "don't change anything on disk") | 528 | "don't change anything on disk") |
| 512 | (?v "verbose" nil verbose "explain what is being done") | 529 | (?v "verbose" nil verbose "explain what is being done") |
| 530 | :preserve-args | ||
| 513 | :external "ln" | 531 | :external "ln" |
| 514 | :show-usage | 532 | :show-usage |
| 515 | :usage "[OPTION]... TARGET [LINK_NAME] | 533 | :usage "[OPTION]... TARGET [LINK_NAME] |
| @@ -518,27 +536,19 @@ Create a link to the specified TARGET with optional LINK_NAME. If there is | |||
| 518 | more than one TARGET, the last argument must be a directory; create links | 536 | more than one TARGET, the last argument must be a directory; create links |
| 519 | in DIRECTORY to each TARGET. Create hard links by default, symbolic links | 537 | in DIRECTORY to each TARGET. Create hard links by default, symbolic links |
| 520 | with '--symbolic'. When creating hard links, each TARGET must exist.") | 538 | with '--symbolic'. When creating hard links, each TARGET must exist.") |
| 521 | (let (target no-dereference ange-cache) | 539 | (let ((no-dereference t)) |
| 522 | (if (> (length args) 1) | 540 | (eshell-mvcpln-template "ln" "linking" |
| 523 | (progn | 541 | (if symbolic |
| 524 | (setq target (car (last args))) | 542 | 'make-symbolic-link |
| 525 | (setcdr (last args 2) nil)) | 543 | 'add-name-to-file) |
| 526 | (setq args nil)) | 544 | eshell-ln-interactive-query |
| 527 | (eshell-shuffle-files "ln" "linking" args target | 545 | eshell-ln-overwrite-files)))) |
| 528 | (if symbolic | ||
| 529 | 'make-symbolic-link | ||
| 530 | 'add-name-to-file) nil | ||
| 531 | (if (and (or interactive | ||
| 532 | eshell-ln-interactive-query) | ||
| 533 | (not force)) | ||
| 534 | 1 (or force eshell-ln-overwrite-files)))) | ||
| 535 | nil)) | ||
| 536 | 546 | ||
| 537 | (defun eshell/cat (&rest args) | 547 | (defun eshell/cat (&rest args) |
| 538 | "Implementation of cat in Lisp. | 548 | "Implementation of cat in Lisp. |
| 539 | If in a pipeline, or the file is not a regular file, directory or | 549 | If in a pipeline, or the file is not a regular file, directory or |
| 540 | symlink, then revert to the system's definition of cat." | 550 | symlink, then revert to the system's definition of cat." |
| 541 | (setq args (eshell-flatten-list args)) | 551 | (setq args (eshell-stringify-list (eshell-flatten-list args))) |
| 542 | (if (or eshell-in-pipeline-p | 552 | (if (or eshell-in-pipeline-p |
| 543 | (catch 'special | 553 | (catch 'special |
| 544 | (eshell-for arg args | 554 | (eshell-for arg args |
| @@ -593,7 +603,8 @@ Concatenate FILE(s), or standard input, to standard output.") | |||
| 593 | (list 'quote (eshell-copy-environment)))))) | 603 | (list 'quote (eshell-copy-environment)))))) |
| 594 | (compile (concat "make " (eshell-flatten-and-stringify args)))) | 604 | (compile (concat "make " (eshell-flatten-and-stringify args)))) |
| 595 | (throw 'eshell-replace-command | 605 | (throw 'eshell-replace-command |
| 596 | (eshell-parse-command "*make" (eshell-flatten-list args))))) | 606 | (eshell-parse-command "*make" (eshell-stringify-list |
| 607 | (eshell-flatten-list args)))))) | ||
| 597 | 608 | ||
| 598 | (defun eshell-occur-mode-goto-occurrence () | 609 | (defun eshell-occur-mode-goto-occurrence () |
| 599 | "Go to the occurrence the current line describes." | 610 | "Go to the occurrence the current line describes." |
| @@ -627,7 +638,8 @@ available..." | |||
| 627 | (default-directory default-dir)) | 638 | (default-directory default-dir)) |
| 628 | (erase-buffer) | 639 | (erase-buffer) |
| 629 | (occur-mode) | 640 | (occur-mode) |
| 630 | (let ((files (eshell-flatten-list (cdr args))) | 641 | (let ((files (eshell-stringify-list |
| 642 | (eshell-flatten-list (cdr args)))) | ||
| 631 | (inhibit-redisplay t) | 643 | (inhibit-redisplay t) |
| 632 | string) | 644 | string) |
| 633 | (when (car args) | 645 | (when (car args) |
| @@ -670,14 +682,16 @@ external command." | |||
| 670 | (not eshell-in-subcommand-p)))) | 682 | (not eshell-in-subcommand-p)))) |
| 671 | (throw 'eshell-replace-command | 683 | (throw 'eshell-replace-command |
| 672 | (eshell-parse-command (concat "*" command) | 684 | (eshell-parse-command (concat "*" command) |
| 673 | (eshell-flatten-list args))) | 685 | (eshell-stringify-list |
| 686 | (eshell-flatten-list args)))) | ||
| 674 | (let* ((compilation-process-setup-function | 687 | (let* ((compilation-process-setup-function |
| 675 | (list 'lambda nil | 688 | (list 'lambda nil |
| 676 | (list 'setq 'process-environment | 689 | (list 'setq 'process-environment |
| 677 | (list 'quote (eshell-copy-environment))))) | 690 | (list 'quote (eshell-copy-environment))))) |
| 678 | (args (mapconcat 'identity | 691 | (args (mapconcat 'identity |
| 679 | (mapcar 'shell-quote-argument | 692 | (mapcar 'shell-quote-argument |
| 680 | (eshell-flatten-list args)) | 693 | (eshell-stringify-list |
| 694 | (eshell-flatten-list args))) | ||
| 681 | " ")) | 695 | " ")) |
| 682 | (cmd (progn | 696 | (cmd (progn |
| 683 | (set-text-properties 0 (length args) | 697 | (set-text-properties 0 (length args) |
| @@ -797,7 +811,7 @@ external command." | |||
| 797 | (defun eshell/du (&rest args) | 811 | (defun eshell/du (&rest args) |
| 798 | "Implementation of \"du\" in Lisp, passing ARGS." | 812 | "Implementation of \"du\" in Lisp, passing ARGS." |
| 799 | (setq args (if args | 813 | (setq args (if args |
| 800 | (eshell-flatten-list args) | 814 | (eshell-stringify-list (eshell-flatten-list args)) |
| 801 | '("."))) | 815 | '("."))) |
| 802 | (let ((ext-du (eshell-search-path "du"))) | 816 | (let ((ext-du (eshell-search-path "du"))) |
| 803 | (if (and ext-du | 817 | (if (and ext-du |
| @@ -909,7 +923,7 @@ Show wall-clock time elapsed during execution of COMMAND.") | |||
| 909 | 923 | ||
| 910 | (defun eshell/diff (&rest args) | 924 | (defun eshell/diff (&rest args) |
| 911 | "Alias \"diff\" to call Emacs `diff' function." | 925 | "Alias \"diff\" to call Emacs `diff' function." |
| 912 | (let ((orig-args (eshell-flatten-list args))) | 926 | (let ((orig-args (eshell-stringify-list (eshell-flatten-list args)))) |
| 913 | (if (or eshell-plain-diff-behavior | 927 | (if (or eshell-plain-diff-behavior |
| 914 | (not (and (eshell-interactive-output-p) | 928 | (not (and (eshell-interactive-output-p) |
| 915 | (not eshell-in-pipeline-p) | 929 | (not eshell-in-pipeline-p) |
| @@ -951,7 +965,8 @@ Show wall-clock time elapsed during execution of COMMAND.") | |||
| 951 | (and (stringp (car args)) | 965 | (and (stringp (car args)) |
| 952 | (string-match "^-" (car args)))) | 966 | (string-match "^-" (car args)))) |
| 953 | (throw 'eshell-replace-command | 967 | (throw 'eshell-replace-command |
| 954 | (eshell-parse-command "*locate" (eshell-flatten-list args))) | 968 | (eshell-parse-command "*locate" (eshell-stringify-list |
| 969 | (eshell-flatten-list args)))) | ||
| 955 | (save-selected-window | 970 | (save-selected-window |
| 956 | (let ((locate-history-list (list (car args)))) | 971 | (let ((locate-history-list (list (car args)))) |
| 957 | (locate-with-filter (car args) (cadr args)))))) | 972 | (locate-with-filter (car args) (cadr args)))))) |
diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el index 6d2ede0a72c..7d5a53625f5 100644 --- a/lisp/eshell/esh-cmd.el +++ b/lisp/eshell/esh-cmd.el | |||
| @@ -203,6 +203,21 @@ which may be modified directly. Any return value is ignored." | |||
| 203 | :type 'hook | 203 | :type 'hook |
| 204 | :group 'eshell-cmd) | 204 | :group 'eshell-cmd) |
| 205 | 205 | ||
| 206 | (defcustom eshell-complex-commands nil | ||
| 207 | "*A list of commands names or functions, that determine complexity. | ||
| 208 | That is, if a command is defined by a function named eshell/NAME, | ||
| 209 | and NAME is part of this list, it is invoked as a complex command. | ||
| 210 | Complex commands are always correct, but run much slower. If a | ||
| 211 | command works fine without being part of this list, then it doesn't | ||
| 212 | need to be. | ||
| 213 | |||
| 214 | If an entry is a function, it will be called with the name, and should | ||
| 215 | return non-nil if the command is complex." | ||
| 216 | :type '(repeat :tag "Commands" | ||
| 217 | (choice (string :tag "Name") | ||
| 218 | (function :tag "Predicate"))) | ||
| 219 | :group 'eshell-cmd) | ||
| 220 | |||
| 206 | ;;; Code: | 221 | ;;; Code: |
| 207 | 222 | ||
| 208 | (require 'esh-util) | 223 | (require 'esh-util) |
| @@ -518,8 +533,8 @@ implemented via rewriting, rather than as a function." | |||
| 518 | (list 'car | 533 | (list 'car |
| 519 | (list 'symbol-value | 534 | (list 'symbol-value |
| 520 | (list 'quote 'for-items))))) | 535 | (list 'quote 'for-items))))) |
| 521 | (list 'eshell-copy-handles | 536 | (list 'eshell-protect |
| 522 | (eshell-invokify-arg body t))) | 537 | (eshell-invokify-arg body t))) |
| 523 | (list 'setcar 'for-items | 538 | (list 'setcar 'for-items |
| 524 | (list 'cadr | 539 | (list 'cadr |
| 525 | (list 'symbol-value | 540 | (list 'symbol-value |
| @@ -583,7 +598,7 @@ must be implemented via rewriting, rather than as a function." | |||
| 583 | (eshell-structure-basic-command | 598 | (eshell-structure-basic-command |
| 584 | 'while '("while" "until") (car terms) | 599 | 'while '("while" "until") (car terms) |
| 585 | (eshell-invokify-arg (cadr terms) nil t) | 600 | (eshell-invokify-arg (cadr terms) nil t) |
| 586 | (list 'eshell-copy-handles | 601 | (list 'eshell-protect |
| 587 | (eshell-invokify-arg (car (last terms)) t))))) | 602 | (eshell-invokify-arg (car (last terms)) t))))) |
| 588 | 603 | ||
| 589 | (defun eshell-rewrite-if-command (terms) | 604 | (defun eshell-rewrite-if-command (terms) |
| @@ -596,13 +611,15 @@ must be implemented via rewriting, rather than as a function." | |||
| 596 | (eshell-structure-basic-command | 611 | (eshell-structure-basic-command |
| 597 | 'if '("if" "unless") (car terms) | 612 | 'if '("if" "unless") (car terms) |
| 598 | (eshell-invokify-arg (cadr terms) nil t) | 613 | (eshell-invokify-arg (cadr terms) nil t) |
| 599 | (eshell-invokify-arg | 614 | (list 'eshell-protect |
| 600 | (if (= (length terms) 5) | 615 | (eshell-invokify-arg |
| 601 | (car (last terms 3)) | 616 | (if (= (length terms) 5) |
| 602 | (car (last terms))) t) | 617 | (car (last terms 3)) |
| 603 | (eshell-invokify-arg | 618 | (car (last terms))) t)) |
| 604 | (if (= (length terms) 5) | 619 | (if (= (length terms) 5) |
| 605 | (car (last terms))) t)))) | 620 | (list 'eshell-protect |
| 621 | (eshell-invokify-arg | ||
| 622 | (car (last terms)))) t)))) | ||
| 606 | 623 | ||
| 607 | (defun eshell-exit-success-p () | 624 | (defun eshell-exit-success-p () |
| 608 | "Return non-nil if the last command was \"successful\". | 625 | "Return non-nil if the last command was \"successful\". |
| @@ -651,8 +668,8 @@ For an external command, it means an exit code of 0." | |||
| 651 | (assert (car sep-terms)) | 668 | (assert (car sep-terms)) |
| 652 | (setq final (eshell-structure-basic-command | 669 | (setq final (eshell-structure-basic-command |
| 653 | 'if (string= (car sep-terms) "&&") "if" | 670 | 'if (string= (car sep-terms) "&&") "if" |
| 654 | (list 'eshell-commands (car results)) | 671 | (list 'eshell-protect (car results)) |
| 655 | final | 672 | (list 'eshell-protect final) |
| 656 | nil t) | 673 | nil t) |
| 657 | results (cdr results) | 674 | results (cdr results) |
| 658 | sep-terms (cdr sep-terms))) | 675 | sep-terms (cdr sep-terms))) |
| @@ -690,8 +707,8 @@ For an external command, it means an exit code of 0." | |||
| 690 | (list 'eshell-lisp-command (list 'quote obj))) | 707 | (list 'eshell-lisp-command (list 'quote obj))) |
| 691 | (ignore (goto-char here)))))) | 708 | (ignore (goto-char here)))))) |
| 692 | 709 | ||
| 693 | (defun eshell-separate-commands | 710 | (defun eshell-separate-commands (terms separator &optional |
| 694 | (terms separator &optional reversed last-terms-sym) | 711 | reversed last-terms-sym) |
| 695 | "Separate TERMS using SEPARATOR. | 712 | "Separate TERMS using SEPARATOR. |
| 696 | If REVERSED is non-nil, the list of separated term groups will be | 713 | If REVERSED is non-nil, the list of separated term groups will be |
| 697 | returned in reverse order. If LAST-TERMS-SYM is a symbol, it's value | 714 | returned in reverse order. If LAST-TERMS-SYM is a symbol, it's value |
| @@ -772,21 +789,6 @@ this grossness will be made to disappear by using `call/cc'..." | |||
| 772 | (eshell-errorn (error-message-string err)) | 789 | (eshell-errorn (error-message-string err)) |
| 773 | (eshell-close-handles 1))))) | 790 | (eshell-close-handles 1))))) |
| 774 | 791 | ||
| 775 | ;; (defun eshell-copy-or-protect-handles () | ||
| 776 | ;; (if (eshell-processp (car (aref eshell-current-handles | ||
| 777 | ;; eshell-output-handle))) | ||
| 778 | ;; (eshell-protect-handles eshell-current-handles) | ||
| 779 | ;; (eshell-create-handles | ||
| 780 | ;; (car (aref eshell-current-handles | ||
| 781 | ;; eshell-output-handle)) nil | ||
| 782 | ;; (car (aref eshell-current-handles | ||
| 783 | ;; eshell-error-handle)) nil))) | ||
| 784 | |||
| 785 | ;; (defmacro eshell-copy-handles (object) | ||
| 786 | ;; "Duplicate current I/O handles, so OBJECT works with its own copy." | ||
| 787 | ;; `(let ((eshell-current-handles (eshell-copy-or-protect-handles))) | ||
| 788 | ;; ,object)) | ||
| 789 | |||
| 790 | (defmacro eshell-copy-handles (object) | 792 | (defmacro eshell-copy-handles (object) |
| 791 | "Duplicate current I/O handles, so OBJECT works with its own copy." | 793 | "Duplicate current I/O handles, so OBJECT works with its own copy." |
| 792 | `(let ((eshell-current-handles | 794 | `(let ((eshell-current-handles |
| @@ -965,6 +967,22 @@ at the moment are: | |||
| 965 | (if subform | 967 | (if subform |
| 966 | (concat "\n\n" (eshell-stringify subform)) "")))))) | 968 | (concat "\n\n" (eshell-stringify subform)) "")))))) |
| 967 | 969 | ||
| 970 | (defun eshell-invoke-directly (command input) | ||
| 971 | (let ((base (cadr (nth 2 (nth 2 (cadr command))))) name) | ||
| 972 | (if (and (eq (car base) 'eshell-trap-errors) | ||
| 973 | (eq (car (cadr base)) 'eshell-named-command)) | ||
| 974 | (setq name (cadr (cadr base)))) | ||
| 975 | (and name (stringp name) | ||
| 976 | (not (member name eshell-complex-commands)) | ||
| 977 | (catch 'simple | ||
| 978 | (progn | ||
| 979 | (eshell-for pred eshell-complex-commands | ||
| 980 | (if (and (functionp pred) | ||
| 981 | (funcall pred name)) | ||
| 982 | (throw 'simple nil))) | ||
| 983 | t)) | ||
| 984 | (fboundp (intern-soft (concat "eshell/" name)))))) | ||
| 985 | |||
| 968 | (defun eshell-eval-command (command &optional input) | 986 | (defun eshell-eval-command (command &optional input) |
| 969 | "Evaluate the given COMMAND iteratively." | 987 | "Evaluate the given COMMAND iteratively." |
| 970 | (if eshell-current-command | 988 | (if eshell-current-command |
| @@ -1163,29 +1181,29 @@ be finished later after the completion of an asynchronous subprocess." | |||
| 1163 | ((eq (car form) 'prog1) | 1181 | ((eq (car form) 'prog1) |
| 1164 | (cadr form)) | 1182 | (cadr form)) |
| 1165 | (t | 1183 | (t |
| 1184 | ;; If a command desire to replace its execution form with | ||
| 1185 | ;; another command form, all it needs to do is throw the new | ||
| 1186 | ;; form using the exception tag `eshell-replace-command'. | ||
| 1187 | ;; For example, let's say that the form currently being | ||
| 1188 | ;; eval'd is: | ||
| 1189 | ;; | ||
| 1190 | ;; (eshell-named-command "hello") | ||
| 1191 | ;; | ||
| 1192 | ;; Now, let's assume the 'hello' command is an Eshell alias, | ||
| 1193 | ;; the definition of which yields the command: | ||
| 1194 | ;; | ||
| 1195 | ;; (eshell-named-command "echo" (list "Hello" "world")) | ||
| 1196 | ;; | ||
| 1197 | ;; What the alias code would like to do is simply substitute | ||
| 1198 | ;; the alias form for the original form. To accomplish | ||
| 1199 | ;; this, all it needs to do is to throw the substitution | ||
| 1200 | ;; form with the `eshell-replace-command' tag, and the form | ||
| 1201 | ;; will be replaced within the current command, and | ||
| 1202 | ;; execution will then resume (iteratively) as before. | ||
| 1203 | ;; Thus, aliases can even contain references to asynchronous | ||
| 1204 | ;; sub-commands, and things will still work out as they | ||
| 1205 | ;; should. | ||
| 1166 | (let (result new-form) | 1206 | (let (result new-form) |
| 1167 | ;; If a command desire to replace its execution form with | ||
| 1168 | ;; another command form, all it needs to do is throw the | ||
| 1169 | ;; new form using the exception tag | ||
| 1170 | ;; `eshell-replace-command'. For example, let's say that | ||
| 1171 | ;; the form currently being eval'd is: | ||
| 1172 | ;; | ||
| 1173 | ;; (eshell-named-command \"hello\") | ||
| 1174 | ;; | ||
| 1175 | ;; Now, let's assume the 'hello' command is an Eshell | ||
| 1176 | ;; alias, the definition of which yields the command: | ||
| 1177 | ;; | ||
| 1178 | ;; (eshell-named-command \"echo\" (list \"Hello\" \"world\")) | ||
| 1179 | ;; | ||
| 1180 | ;; What the alias code would like to do is simply | ||
| 1181 | ;; substitute the alias form for the original form. To | ||
| 1182 | ;; accomplish this, all it needs to do is to throw the | ||
| 1183 | ;; substitution form with the `eshell-replace-command' | ||
| 1184 | ;; tag, and the form will be replaced within the current | ||
| 1185 | ;; command, and execution will then resume (iteratively) | ||
| 1186 | ;; as before. Thus, aliases can even contain references | ||
| 1187 | ;; to asynchronous sub-commands, and things will still | ||
| 1188 | ;; work out as they should. | ||
| 1189 | (if (setq new-form | 1207 | (if (setq new-form |
| 1190 | (catch 'eshell-replace-command | 1208 | (catch 'eshell-replace-command |
| 1191 | (ignore | 1209 | (ignore |
diff --git a/lisp/eshell/esh-groups.el b/lisp/eshell/esh-groups.el index 218bd2a2e52..d82cdff4ffd 100644 --- a/lisp/eshell/esh-groups.el +++ b/lisp/eshell/esh-groups.el | |||
| @@ -132,4 +132,3 @@ functions, or as aliases which make some of Emacs' behavior more | |||
| 132 | naturally accessible within Emacs." | 132 | naturally accessible within Emacs." |
| 133 | :tag "Extra alias functions" | 133 | :tag "Extra alias functions" |
| 134 | :group 'eshell-module) | 134 | :group 'eshell-module) |
| 135 | |||
diff --git a/lisp/eshell/esh-maint.el b/lisp/eshell/esh-maint.el index 13b3597b4ce..89e50401c67 100644 --- a/lisp/eshell/esh-maint.el +++ b/lisp/eshell/esh-maint.el | |||
| @@ -48,7 +48,7 @@ | |||
| 48 | ;; (interactive) | 48 | ;; (interactive) |
| 49 | ;; (require 'autoload) | 49 | ;; (require 'autoload) |
| 50 | ;; (setq generated-autoload-file | 50 | ;; (setq generated-autoload-file |
| 51 | ;; (expand-file-name (car command-line-args-left))) | 51 | ;; (expand-file-name (car command-line-args-left))) |
| 52 | ;; (setq command-line-args-left (cdr command-line-args-left)) | 52 | ;; (setq command-line-args-left (cdr command-line-args-left)) |
| 53 | ;; (batch-update-autoloads)) | 53 | ;; (batch-update-autoloads)) |
| 54 | 54 | ||
| @@ -65,23 +65,23 @@ | |||
| 65 | ;; Core Functionality\n") | 65 | ;; Core Functionality\n") |
| 66 | ;; (eshell-for module | 66 | ;; (eshell-for module |
| 67 | ;; (sort (eshell-subgroups 'eshell) | 67 | ;; (sort (eshell-subgroups 'eshell) |
| 68 | ;; (function | 68 | ;; (function |
| 69 | ;; (lambda (a b) | 69 | ;; (lambda (a b) |
| 70 | ;; (string-lessp (symbol-name a) | 70 | ;; (string-lessp (symbol-name a) |
| 71 | ;; (symbol-name b))))) | 71 | ;; (symbol-name b))))) |
| 72 | ;; (insert (format "* %-34s" | 72 | ;; (insert (format "* %-34s" |
| 73 | ;; (concat (get module 'custom-tag) "::")) | 73 | ;; (concat (get module 'custom-tag) "::")) |
| 74 | ;; (symbol-name module) ".\n")) | 74 | ;; (symbol-name module) ".\n")) |
| 75 | ;; (insert "\nOptional Functionality\n") | 75 | ;; (insert "\nOptional Functionality\n") |
| 76 | ;; (eshell-for module | 76 | ;; (eshell-for module |
| 77 | ;; (sort (eshell-subgroups 'eshell-module) | 77 | ;; (sort (eshell-subgroups 'eshell-module) |
| 78 | ;; (function | 78 | ;; (function |
| 79 | ;; (lambda (a b) | 79 | ;; (lambda (a b) |
| 80 | ;; (string-lessp (symbol-name a) | 80 | ;; (string-lessp (symbol-name a) |
| 81 | ;; (symbol-name b))))) | 81 | ;; (symbol-name b))))) |
| 82 | ;; (insert (format "* %-34s" | 82 | ;; (insert (format "* %-34s" |
| 83 | ;; (concat (get module 'custom-tag) "::")) | 83 | ;; (concat (get module 'custom-tag) "::")) |
| 84 | ;; (symbol-name module) ".\n")) | 84 | ;; (symbol-name module) ".\n")) |
| 85 | ;; (insert "@end menu\n")) | 85 | ;; (insert "@end menu\n")) |
| 86 | 86 | ||
| 87 | ;; (defun eshell-make-texi () | 87 | ;; (defun eshell-make-texi () |
| @@ -91,27 +91,27 @@ | |||
| 91 | ;; (require 'texidoc) | 91 | ;; (require 'texidoc) |
| 92 | ;; (require 'pcomplete) | 92 | ;; (require 'pcomplete) |
| 93 | ;; (apply 'texidoc-files 'eshell-generate-main-menu "eshell.doci" | 93 | ;; (apply 'texidoc-files 'eshell-generate-main-menu "eshell.doci" |
| 94 | ;; (append | 94 | ;; (append |
| 95 | ;; (list "eshell.el") | 95 | ;; (list "eshell.el") |
| 96 | ;; (sort (mapcar | 96 | ;; (sort (mapcar |
| 97 | ;; (function | 97 | ;; (function |
| 98 | ;; (lambda (sym) | 98 | ;; (lambda (sym) |
| 99 | ;; (let ((name (symbol-name sym))) | 99 | ;; (let ((name (symbol-name sym))) |
| 100 | ;; (if (string-match "\\`eshell-\\(.*\\)" name) | 100 | ;; (if (string-match "\\`eshell-\\(.*\\)" name) |
| 101 | ;; (setq name (concat "esh-" (match-string 1 name)))) | 101 | ;; (setq name (concat "esh-" (match-string 1 name)))) |
| 102 | ;; (concat name ".el")))) | 102 | ;; (concat name ".el")))) |
| 103 | ;; (eshell-subgroups 'eshell)) | 103 | ;; (eshell-subgroups 'eshell)) |
| 104 | ;; 'string-lessp) | 104 | ;; 'string-lessp) |
| 105 | ;; (sort (mapcar | 105 | ;; (sort (mapcar |
| 106 | ;; (function | 106 | ;; (function |
| 107 | ;; (lambda (sym) | 107 | ;; (lambda (sym) |
| 108 | ;; (let ((name (symbol-name sym))) | 108 | ;; (let ((name (symbol-name sym))) |
| 109 | ;; (if (string-match "\\`eshell-\\(.*\\)" name) | 109 | ;; (if (string-match "\\`eshell-\\(.*\\)" name) |
| 110 | ;; (setq name (concat "em-" (match-string 1 name)))) | 110 | ;; (setq name (concat "em-" (match-string 1 name)))) |
| 111 | ;; (concat name ".el")))) | 111 | ;; (concat name ".el")))) |
| 112 | ;; (eshell-subgroups 'eshell-module)) | 112 | ;; (eshell-subgroups 'eshell-module)) |
| 113 | ;; 'string-lessp) | 113 | ;; 'string-lessp) |
| 114 | ;; (list "eshell.texi")))) | 114 | ;; (list "eshell.texi")))) |
| 115 | 115 | ||
| 116 | ;; (defun eshell-make-readme () | 116 | ;; (defun eshell-make-readme () |
| 117 | ;; "Make the README file from eshell.el." | 117 | ;; "Make the README file from eshell.el." |
diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el index ad513c47a0b..5da511626c5 100644 --- a/lisp/eshell/esh-mode.el +++ b/lisp/eshell/esh-mode.el | |||
| @@ -180,9 +180,7 @@ inserted. They return the string as it should be inserted." | |||
| 180 | :group 'eshell-mode) | 180 | :group 'eshell-mode) |
| 181 | 181 | ||
| 182 | (defcustom eshell-password-prompt-regexp | 182 | (defcustom eshell-password-prompt-regexp |
| 183 | "\\(\\([Oo]ld \\|[Nn]ew \\|Kerberos \\|CVS \\|'s \\|login \\|^\\)\ | 183 | "[Pp]ass\\(word\\|phrase\\).*:\\s *\\'" |
| 184 | [Pp]assword\\|pass phrase\\|\\(Enter\\|Repeat\\) passphrase\\)\ | ||
| 185 | \\( for [^@ \t\n]+@[^@ \t\n]+\\)?:\\s *\\'" | ||
| 186 | "*Regexp matching prompts for passwords in the inferior process. | 184 | "*Regexp matching prompts for passwords in the inferior process. |
| 187 | This is used by `eshell-watch-for-password-prompt'." | 185 | This is used by `eshell-watch-for-password-prompt'." |
| 188 | :type 'regexp | 186 | :type 'regexp |
| @@ -462,7 +460,8 @@ sessions, such as when using `eshell-command'.") | |||
| 462 | 460 | ||
| 463 | (eshell-deftest var window-height | 461 | (eshell-deftest var window-height |
| 464 | "LINES equals window height" | 462 | "LINES equals window height" |
| 465 | (eshell-command-result-p "= $LINES (window-height)" "t\n")) | 463 | (let ((eshell-stringify-t t)) |
| 464 | (eshell-command-result-p "= $LINES (window-height)" "t\n"))) | ||
| 466 | 465 | ||
| 467 | (defun eshell-command-started () | 466 | (defun eshell-command-started () |
| 468 | "Indicate in the modeline that a command has started." | 467 | "Indicate in the modeline that a command has started." |
| @@ -736,7 +735,9 @@ newline." | |||
| 736 | (run-hooks 'eshell-input-filter-functions) | 735 | (run-hooks 'eshell-input-filter-functions) |
| 737 | (and (catch 'eshell-terminal | 736 | (and (catch 'eshell-terminal |
| 738 | (ignore | 737 | (ignore |
| 739 | (eshell-eval-command cmd input))) | 738 | (if (eshell-invoke-directly cmd input) |
| 739 | (eval cmd) | ||
| 740 | (eshell-eval-command cmd input)))) | ||
| 740 | (eshell-life-is-too-much))))) | 741 | (eshell-life-is-too-much))))) |
| 741 | (quit | 742 | (quit |
| 742 | (eshell-reset t) | 743 | (eshell-reset t) |
diff --git a/lisp/eshell/esh-module.el b/lisp/eshell/esh-module.el index 3eab199201e..f09f1ac7b24 100644 --- a/lisp/eshell/esh-module.el +++ b/lisp/eshell/esh-module.el | |||
| @@ -24,7 +24,9 @@ | |||
| 24 | 24 | ||
| 25 | (provide 'esh-module) | 25 | (provide 'esh-module) |
| 26 | 26 | ||
| 27 | (eval-when-compile (require 'esh-maint) (require 'cl)) | 27 | (eval-when-compile |
| 28 | (require 'esh-maint) | ||
| 29 | (require 'cl)) | ||
| 28 | 30 | ||
| 29 | (defgroup eshell-module nil | 31 | (defgroup eshell-module nil |
| 30 | "The `eshell-module' group is for Eshell extension modules, which | 32 | "The `eshell-module' group is for Eshell extension modules, which |
| @@ -85,7 +87,7 @@ customizing the variable `eshell-modules-list'." | |||
| 85 | (equal (file-name-nondirectory byte-compile-current-file) | 87 | (equal (file-name-nondirectory byte-compile-current-file) |
| 86 | "esh-modu.el")))) | 88 | "esh-modu.el")))) |
| 87 | (let* ((directory (file-name-directory byte-compile-current-file)) | 89 | (let* ((directory (file-name-directory byte-compile-current-file)) |
| 88 | (elc-file (expand-file-name "esh-groups.elc" directory))) | 90 | (elc-file (expand-file-name "esh-groups.elc" directory))) |
| 89 | (eshell-load-defgroups directory) | 91 | (eshell-load-defgroups directory) |
| 90 | (if (file-exists-p elc-file) (delete-file elc-file))))) | 92 | (if (file-exists-p elc-file) (delete-file elc-file))))) |
| 91 | 93 | ||
diff --git a/lisp/eshell/esh-test.el b/lisp/eshell/esh-test.el index 6a14541ab39..acfb409da57 100644 --- a/lisp/eshell/esh-test.el +++ b/lisp/eshell/esh-test.el | |||
| @@ -173,12 +173,12 @@ | |||
| 173 | system-configuration | 173 | system-configuration |
| 174 | (cond ((featurep 'motif) ", Motif") | 174 | (cond ((featurep 'motif) ", Motif") |
| 175 | ((featurep 'x-toolkit) ", X toolkit") | 175 | ((featurep 'x-toolkit) ", X toolkit") |
| 176 | (t ""))) "\n") | 176 | (t "")))) |
| 177 | (switch-to-buffer test-buffer) | 177 | (switch-to-buffer test-buffer) |
| 178 | (delete-other-windows)) | 178 | (delete-other-windows)) |
| 179 | (eshell-for funcname | 179 | (eshell-for funcname (sort (all-completions "eshell-test--" |
| 180 | (sort (all-completions "eshell-test--" obarray 'functionp) | 180 | obarray 'functionp) |
| 181 | 'string-lessp) | 181 | 'string-lessp) |
| 182 | (with-current-buffer test-buffer | 182 | (with-current-buffer test-buffer |
| 183 | (insert "\n")) | 183 | (insert "\n")) |
| 184 | (funcall (intern-soft funcname))) | 184 | (funcall (intern-soft funcname))) |
diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el index 01c0ff2c76e..3d8dedc6bae 100644 --- a/lisp/eshell/esh-util.el +++ b/lisp/eshell/esh-util.el | |||
| @@ -36,6 +36,14 @@ | |||
| 36 | 36 | ||
| 37 | ;;; User Variables: | 37 | ;;; User Variables: |
| 38 | 38 | ||
| 39 | (defcustom eshell-stringify-t t | ||
| 40 | "*If non-nil, the string representation of t is 't'. | ||
| 41 | If nil, t will be represented only in the exit code of the function, | ||
| 42 | and not printed as a string. This causes Lisp functions to behave | ||
| 43 | similarly to external commands, as far as successful result output." | ||
| 44 | :type 'boolean | ||
| 45 | :group 'eshell-util) | ||
| 46 | |||
| 39 | (defcustom eshell-group-file "/etc/group" | 47 | (defcustom eshell-group-file "/etc/group" |
| 40 | "*If non-nil, the name of the group file on your system." | 48 | "*If non-nil, the name of the group file on your system." |
| 41 | :type '(choice (const :tag "No group file" nil) file) | 49 | :type '(choice (const :tag "No group file" nil) file) |
| @@ -305,7 +313,9 @@ If N or M is nil, it means the end of the list." | |||
| 305 | ((numberp object) | 313 | ((numberp object) |
| 306 | (number-to-string object)) | 314 | (number-to-string object)) |
| 307 | (t | 315 | (t |
| 308 | (pp-to-string object)))) | 316 | (unless (and (eq object t) |
| 317 | (not eshell-stringify-t)) | ||
| 318 | (pp-to-string object))))) | ||
| 309 | 319 | ||
| 310 | (defsubst eshell-stringify-list (args) | 320 | (defsubst eshell-stringify-list (args) |
| 311 | "Convert each element of ARGS into a string value." | 321 | "Convert each element of ARGS into a string value." |
| @@ -611,7 +621,7 @@ Unless optional argument INPLACE is non-nil, return a new string." | |||
| 611 | (autoload 'parse-time-string "parse-time")) | 621 | (autoload 'parse-time-string "parse-time")) |
| 612 | 622 | ||
| 613 | (eval-when-compile | 623 | (eval-when-compile |
| 614 | (require 'ange-ftp)) | 624 | (load "ange-ftp" t)) |
| 615 | 625 | ||
| 616 | (defun eshell-parse-ange-ls (dir) | 626 | (defun eshell-parse-ange-ls (dir) |
| 617 | (let (entry) | 627 | (let (entry) |
diff --git a/lisp/textmodes/flyspell.el b/lisp/textmodes/flyspell.el index fe95b3faa59..74c07f19602 100644 --- a/lisp/textmodes/flyspell.el +++ b/lisp/textmodes/flyspell.el | |||
| @@ -1986,7 +1986,7 @@ The word checked is the word at the mouse position." | |||
| 1986 | menu)))) | 1986 | menu)))) |
| 1987 | 1987 | ||
| 1988 | ;*---------------------------------------------------------------------*/ | 1988 | ;*---------------------------------------------------------------------*/ |
| 1989 | ;* Some example functions for real autocrrecting */ | 1989 | ;* Some example functions for real autocrrecting xb */ |
| 1990 | ;*---------------------------------------------------------------------*/ | 1990 | ;*---------------------------------------------------------------------*/ |
| 1991 | (defun flyspell-maybe-correct-transposition (beg end poss) | 1991 | (defun flyspell-maybe-correct-transposition (beg end poss) |
| 1992 | "Apply 'transpose-chars' to all points in the region BEG to END and | 1992 | "Apply 'transpose-chars' to all points in the region BEG to END and |
| @@ -1994,17 +1994,24 @@ return t if any those result in a possible replacement suggested by ispell | |||
| 1994 | in POSS. Otherwise the change is undone. | 1994 | in POSS. Otherwise the change is undone. |
| 1995 | 1995 | ||
| 1996 | This function is meant to be added to 'flyspell-incorrect-hook'." | 1996 | This function is meant to be added to 'flyspell-incorrect-hook'." |
| 1997 | (when (consp poss) | 1997 | (when (consp poss) |
| 1998 | (catch 'done | 1998 | (catch 'done |
| 1999 | (save-excursion | 1999 | (let ((str (buffer-substring beg end)) |
| 2000 | (goto-char (1+ beg)) | 2000 | (i 0) (len (- end beg)) tmp) |
| 2001 | (while (< (point) end) | 2001 | (while (< (1+ i) len) |
| 2002 | (transpose-chars 1) | 2002 | (setq tmp (aref str i)) |
| 2003 | (when (member (buffer-substring beg end) (nth 2 poss)) | 2003 | (aset str i (aref str (1+ i))) |
| 2004 | (throw 'done t)) | 2004 | (aset str (1+ i) tmp) |
| 2005 | (transpose-chars -1) | 2005 | (when (member str (nth 2 poss)) |
| 2006 | (forward-char)) | 2006 | (save-excursion |
| 2007 | nil)))) | 2007 | (goto-char (+ beg i 1)) |
| 2008 | (transpose-chars 1)) | ||
| 2009 | (throw 'done t)) | ||
| 2010 | (setq tmp (aref str i)) | ||
| 2011 | (aset str i (aref str (1+ i))) | ||
| 2012 | (aset str (1+ i) tmp) | ||
| 2013 | (setq i (1+ i)))) | ||
| 2014 | nil))) | ||
| 2008 | 2015 | ||
| 2009 | (defun flyspell-maybe-correct-doubling (beg end poss) | 2016 | (defun flyspell-maybe-correct-doubling (beg end poss) |
| 2010 | "For each doubled charachter in the region BEG to END, remove one and | 2017 | "For each doubled charachter in the region BEG to END, remove one and |
| @@ -2014,21 +2021,18 @@ in POSS. Otherwise the change is undone. | |||
| 2014 | This function is meant to be added to 'flyspell-incorrect-hook'." | 2021 | This function is meant to be added to 'flyspell-incorrect-hook'." |
| 2015 | (when (consp poss) | 2022 | (when (consp poss) |
| 2016 | (catch 'done | 2023 | (catch 'done |
| 2017 | (save-excursion | 2024 | (let ((str (buffer-substring beg end)) |
| 2018 | (let ((last (char-after beg)) | 2025 | (i 0) (len (- end beg))) |
| 2019 | this) | 2026 | (while (< (1+ i) len) |
| 2020 | (goto-char (1+ beg)) | 2027 | (when (and (= (aref str i) (aref str (1+ i))) |
| 2021 | (while (< (point) end) | 2028 | (member (concat (substring str 0 (1+ i)) |
| 2022 | (setq this (char-after)) | 2029 | (substring str (+ i 2))) |
| 2023 | (if (not (char-equal this last)) | 2030 | (nth 2 poss))) |
| 2024 | (forward-char) | 2031 | (goto-char (+ beg i)) |
| 2025 | (delete-char 1) | 2032 | (delete-char 1) |
| 2026 | (when (member (buffer-substring beg (1- end)) (nth 2 poss)) | 2033 | (throw 'done t)) |
| 2027 | (throw 'done t)) | 2034 | (setq i (1+ i)))) |
| 2028 | ;; undo | 2035 | nil))) |
| 2029 | (insert-char this 1)) | ||
| 2030 | (setq last this)) | ||
| 2031 | nil))))) | ||
| 2032 | 2036 | ||
| 2033 | ;*---------------------------------------------------------------------*/ | 2037 | ;*---------------------------------------------------------------------*/ |
| 2034 | ;* flyspell-already-abbrevp ... */ | 2038 | ;* flyspell-already-abbrevp ... */ |