See ChangeLog
This commit is contained in:
parent
657f9cb8b7
commit
dace60cfea
21 changed files with 1299 additions and 633 deletions
|
@ -1,3 +1,7 @@
|
|||
2000-10-18 John Wiegley <johnw@gnu.org>
|
||||
|
||||
* NEWS: Added text for pcomplete.el.
|
||||
|
||||
2000-10-16 Gerd Moellmann <gerd@gnu.org>
|
||||
|
||||
* 3B-MAXMEM, AIX.DUMP, SUN-SUPPORT: Removed.
|
||||
|
|
5
etc/NEWS
5
etc/NEWS
|
@ -1786,7 +1786,10 @@ Fill mode.
|
|||
*** gnus-mule.el is now just a compatibility layer over the built-in
|
||||
Gnus facilities.
|
||||
|
||||
*** pcomplete.el ??
|
||||
*** pcomplete.el is a library that provides programmable completion
|
||||
facilities for Emacs, similar to what zsh and tcsh offer. The main
|
||||
difference is that completion functions are written in Lisp, meaning
|
||||
they can be profiled, debugged, etc.
|
||||
|
||||
** Withdrawn packages
|
||||
|
||||
|
|
123
lisp/ChangeLog
123
lisp/ChangeLog
|
@ -1,3 +1,124 @@
|
|||
2000-10-28 John Wiegley <johnw@gnu.org>
|
||||
|
||||
* textmodes/flyspell.el (flyspell-maybe-correct-transposition):
|
||||
Changed this function to operate on a temporary buffer instead of
|
||||
the main buffer. This not only keeps flyspell from marking a
|
||||
buffer as changed that wasn't, but it solves the jumpy cursor
|
||||
problem when attempts are made to edit incorrect words.
|
||||
(flyspell-maybe-correct-doubling): Same change as for
|
||||
`flyspell-maybe-correct-transposition'.
|
||||
|
||||
* calendar/timeclock.el (timeclock-log): Doc fix.
|
||||
(timeclock-last-event): Doc fix.
|
||||
(timeclock-log): Kill the timelog buffer after appending a new
|
||||
event.
|
||||
(timeclock-find-discrep): Use a temp buffer to read in the
|
||||
timelog, instead of visiting the file.
|
||||
(timeclock-log-data): A new function, along with a host of helper
|
||||
functions, for the purpose of making timelog data accessible to
|
||||
programmers.
|
||||
|
||||
* eshell/esh-mode.el (window-height test): Make certain that
|
||||
`eshell-stringify-t' is non-nil.
|
||||
(eshell-password-prompt-regexp): Changed to a much simpler
|
||||
password regexp.
|
||||
(eshell-send-input): If `eshell-invoke-directly' returns t,
|
||||
directly invoke the parsed command using `eval'. This improves
|
||||
turn-around time on simple commands by a factor of three or
|
||||
greater, such as cd, ls, pwd, etc. -- which get used very often.
|
||||
It also conserves thousands of cons cells per call (since
|
||||
`eshell-do-eval' consumes memory like a Cookie Monster set loose
|
||||
in the Pacific Cookie Company).
|
||||
|
||||
* eshell/esh-test.el (eshell-test): Whitespace fix.
|
||||
|
||||
* eshell/em-ls.el (eshell-ls-insert-directory): Make
|
||||
`eshell-ls-initial-args' nil when inserting directory contents.
|
||||
|
||||
* eshell/em-script.el (eshell-script-initialize): Add names to
|
||||
`eshell-complex-commands, since `source' and `.' are complex.
|
||||
|
||||
* eshell/esh-cmd.el (eshell-rewrite-for-command,
|
||||
eshell-rewrite-while-command): Use `eshell-protect' instead of
|
||||
`eshell-copy-handles'.
|
||||
(eshell-rewrite-if-command): Use `eshell-protect' to wrap the call
|
||||
bodies.
|
||||
(eshell-separate-commands): Whitespace fix.
|
||||
(eshell-complex-commands): Added a new list of names, for
|
||||
determining whether a given command is as simple as it looks.
|
||||
(eshell-invoke-directly): New function. Returns t if a command
|
||||
should be invoked directly (using `eval'), rather than indirectly
|
||||
using `eshell-do-eval'.
|
||||
(eshell-do-eval): Whitespace fix.
|
||||
|
||||
* eshell/em-unix.el (eshell-default-target-is-dot): New variable,
|
||||
which provides an emulation of the DOS shell behavior of assuming
|
||||
that cp/mv/ln should copy/move/link to the current directory.
|
||||
(eshell-remove-entries): Added a doc string.
|
||||
(eshell-shuffle-files): Removed the check for `target' being null.
|
||||
(eshell-mvcp-template, eshell-mvcpln-template): Renamed
|
||||
`eshell-mvcp-template' to `eshell-mvcpln-template', and extended
|
||||
it to do a smarter check of whether a destination was provided.
|
||||
(eshell/mv, eshell/cp): Enable `:preserve-args'.
|
||||
(eshell/ln): Enable `:preserve-args', and use
|
||||
`eshell-mvcpln-template' to implement the body of the function.
|
||||
(eshell/cat, eshell/make, eshell-poor-mans-grep, eshell-grep,
|
||||
eshell/du, eshell/diff, eshell/locate): Stringify the argument
|
||||
list after flattening it. This makes it possible to cat files
|
||||
with numerical names.
|
||||
(eshell-unix-initialize): Added several names to
|
||||
`eshell-complex-commands.
|
||||
(eshell-unix-command-complex-p): Return t if a given command name
|
||||
may result in external processes being invoked.
|
||||
|
||||
* eshell/em-glob.el (eshell-glob-show-progress): Make this
|
||||
variable nil by default, since it slows down glob processing by a
|
||||
factor of two or more, and increases memory consumption.
|
||||
|
||||
* eshell/em-smart.el: Added a note about how memory consumptive
|
||||
smart display mode can be (at least this is true in Emacs 21).
|
||||
(eshell-smart-initialize): Whitespace fix.
|
||||
(eshell-refresh-windows): Use `if' instead of `when'.
|
||||
(eshell-smart-scroll-window): Calling `save-current-buffer' was
|
||||
not necessary.
|
||||
(eshell-currently-handling-window): Added a missing global
|
||||
variable.
|
||||
|
||||
* eshell/em-ls.el (eshell-do-ls): Code simplification.
|
||||
(eshell-ls-sort-entries, eshell-ls-entries, eshell-ls-dir):
|
||||
Whitespace fix.
|
||||
(eshell-ls-exclude-hidden): Added this variable in addition to
|
||||
`eshell-ls-exclude-regexp'. This one prevents files beginning
|
||||
with . from even being read, which can improve memory consumption
|
||||
quite a bit.
|
||||
(eshell-ls-dir): If `eshell-ls-exclude-hidden' is non-nil, do not
|
||||
read file entries beginning with a dot. In home directories with
|
||||
lots of hidden files, fully two-thirds of the time spent in ls is
|
||||
used to read directory entries that are immediately thrown away.
|
||||
(eshell-ls-initial-args): Added back this configuration variable,
|
||||
for specifying default initial arguments to every call to ls.
|
||||
Much faster than using an alias to do the same thing.
|
||||
(eshell-do-ls): Use `eshell-ls-initial-args', if set.
|
||||
(eshell-ls-dir): Whitespace change.
|
||||
|
||||
* eshell/em-dirs.el (eshell/pwd): Small code simplification.
|
||||
|
||||
* eshell/esh-util.el: Don't require `ange-ftp' if it's not
|
||||
available.
|
||||
(eshell-stringify-t): Added a customization variable, to indicate
|
||||
whether `t' should be rendered as a string at all. If not, one
|
||||
can still determine if the result of an expression is true using
|
||||
"file-exists-p FILE && echo true".
|
||||
(eshell-stringify): If `eshell-stringify-t' is nil, don't
|
||||
stringify t!
|
||||
|
||||
* eshell/esh-module.el: Whitespace fix.
|
||||
|
||||
* eshell/em-alias.el (eshell-alias-initialize): Added
|
||||
`eshell-command-aliased-p' to `eshell-complex-commands'.
|
||||
(eshell-command-aliased-p): New function that returns t if a
|
||||
command name names an aliased.
|
||||
|
||||
2000-10-29 Michael Kifer <kifer@cs.sunysb.edu>
|
||||
|
||||
* viper-cmd.el (viper-preserve-cursor-color): new test that avoids
|
||||
|
@ -865,7 +986,7 @@
|
|||
* align.el, pcomplete.el, calendar/timeclock.el,
|
||||
eshell/esh-module.el, eshell/eshell.el: Removed URL reference.
|
||||
|
||||
* calendar/timeclock.el (timeclock-find-discrep): A fix to same
|
||||
* calendar/timeclock.el (timeclock-find-discrep): A fix to some
|
||||
faulty math, where holiday hours were being computing as seconds.
|
||||
|
||||
2000-10-13 John Wiegley <johnw@gnu.org>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
;; Author: John Wiegley <johnw@gnu.org>
|
||||
;; Created: 25 Mar 1999
|
||||
;; Version: 2.2
|
||||
;; Version: 2.3
|
||||
;; Keywords: calendar data
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
@ -222,8 +222,7 @@ in the modeline. See the variable `timeclock-modeline-display'."
|
|||
|
||||
(defvar timeclock-last-event nil
|
||||
"A list containing the last event that was recorded.
|
||||
The format of this list is (CODE TIME PROJECT). PROJECT will be
|
||||
non-nil only if CODE is \"o\" or \"O\".")
|
||||
The format of this list is (CODE TIME PROJECT).")
|
||||
|
||||
(defvar timeclock-last-event-workday nil
|
||||
"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)."
|
|||
(truncate (/ (abs seconds) 60 60))
|
||||
(% (truncate (/ (abs seconds) 60)) 60))))
|
||||
|
||||
(defun timeclock-workday-remaining (&optional today-only)
|
||||
(defsubst timeclock-workday-remaining (&optional today-only)
|
||||
"Return a the number of seconds until the workday is complete.
|
||||
The amount returned is relative to the value of `timeclock-workday'.
|
||||
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
|
|||
a difference if `timeclock-relative' is non-nil."
|
||||
(- (timeclock-find-discrep today-only)))
|
||||
|
||||
(defun timeclock-currently-in-p ()
|
||||
(defsubst timeclock-currently-in-p ()
|
||||
"Return non-nil if the user is currently clocked in."
|
||||
(equal (car timeclock-last-event) "i"))
|
||||
|
||||
|
@ -483,7 +482,7 @@ See `timeclock-relative' for more information about the meaning of
|
|||
(message string)
|
||||
string)))
|
||||
|
||||
(defun timeclock-workday-elapsed (&optional relative)
|
||||
(defsubst timeclock-workday-elapsed (&optional relative)
|
||||
"Return a the number of seconds worked so far today.
|
||||
If RELATIVE is non-nil, the amount returned will be relative to past
|
||||
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."
|
|||
(message string)
|
||||
string)))
|
||||
|
||||
(defun timeclock-when-to-leave (&optional today-only)
|
||||
(defsubst timeclock-when-to-leave (&optional today-only)
|
||||
"Return a time value representing at when the workday ends today.
|
||||
If TODAY-ONLY is non-nil, the value returned will be relative only to
|
||||
the time worked today, and not to past time. This argument only makes
|
||||
|
@ -578,9 +577,8 @@ non-nil."
|
|||
(defun timeclock-log (code &optional project)
|
||||
"Log the event CODE to the timeclock log, at the time of call.
|
||||
If PROJECT is a string, it represents the project which the event is
|
||||
being logged for. Normally only \"out\" events specify a project."
|
||||
(save-excursion
|
||||
(set-buffer (find-file-noselect timeclock-file))
|
||||
being logged for. Normally only \"in\" events specify a project."
|
||||
(with-current-buffer (find-file-noselect timeclock-file)
|
||||
(goto-char (point-max))
|
||||
(if (not (bolp))
|
||||
(insert "\n"))
|
||||
|
@ -603,42 +601,40 @@ being logged for. Normally only \"out\" events specify a project."
|
|||
timeclock-last-period)))
|
||||
(setq timeclock-last-event (list code now project)))
|
||||
(save-buffer)
|
||||
(run-hooks 'timeclock-event-hook)))
|
||||
(run-hooks 'timeclock-event-hook)
|
||||
(kill-buffer (current-buffer))))
|
||||
|
||||
(defun timeclock-read-moment ()
|
||||
(defvar timeclock-moment-regexp
|
||||
(concat "\\([bhioO]\\)\\s-+"
|
||||
"\\([0-9]+\\)/\\([0-9]+\\)/\\([0-9]+\\)\\s-+"
|
||||
"\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)[ \t]*" "\\([^\n]*\\)"))
|
||||
|
||||
(defsubst timeclock-read-moment ()
|
||||
"Read the moment under point from the timelog."
|
||||
(save-excursion
|
||||
(beginning-of-line)
|
||||
(let ((eol (save-excursion (end-of-line) (point))))
|
||||
(if (re-search-forward
|
||||
(concat "^\\(.\\)\\s-+"
|
||||
"\\([0-9]+\\)/\\([0-9]+\\)/\\([0-9]+\\)\\s-+"
|
||||
"\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)\\s-*"
|
||||
"\\(.*\\)") eol t)
|
||||
(let ((code (match-string 1))
|
||||
(year (string-to-number (match-string 2)))
|
||||
(mon (string-to-number (match-string 3)))
|
||||
(mday (string-to-number (match-string 4)))
|
||||
(hour (string-to-number (match-string 5)))
|
||||
(min (string-to-number (match-string 6)))
|
||||
(sec (string-to-number (match-string 7)))
|
||||
(project (match-string 8)))
|
||||
(list code (encode-time sec min hour mday mon year)
|
||||
project))))))
|
||||
(if (looking-at timeclock-moment-regexp)
|
||||
(let ((code (match-string 1))
|
||||
(year (string-to-number (match-string 2)))
|
||||
(mon (string-to-number (match-string 3)))
|
||||
(mday (string-to-number (match-string 4)))
|
||||
(hour (string-to-number (match-string 5)))
|
||||
(min (string-to-number (match-string 6)))
|
||||
(sec (string-to-number (match-string 7)))
|
||||
(project (match-string 8)))
|
||||
(list code (encode-time sec min hour mday mon year) project))))
|
||||
|
||||
(defun timeclock-time-to-seconds (time)
|
||||
(defsubst timeclock-time-to-seconds (time)
|
||||
"Convert TIME to a floating point number."
|
||||
(+ (* (car time) 65536.0)
|
||||
(cadr time)
|
||||
(/ (or (car (cdr (cdr time))) 0) 1000000.0)))
|
||||
|
||||
(defun timeclock-seconds-to-time (seconds)
|
||||
(defsubst timeclock-seconds-to-time (seconds)
|
||||
"Convert SECONDS (a floating point number) to an Emacs time structure."
|
||||
(list (floor seconds 65536)
|
||||
(floor (mod seconds 65536))
|
||||
(floor (* (- seconds (ffloor seconds)) 1000000))))
|
||||
|
||||
(defun timeclock-time-to-date (time)
|
||||
(defsubst timeclock-time-to-date (time)
|
||||
"Convert the TIME value to a textual date string."
|
||||
(format-time-string "%Y/%m/%d" time))
|
||||
|
||||
|
@ -655,49 +651,376 @@ This is only provided for coherency when used by
|
|||
(cadr timeclock-last-event)))
|
||||
timeclock-last-period))
|
||||
|
||||
(defsubst timeclock-entry-length (entry)
|
||||
(- (timeclock-time-to-seconds (cadr entry))
|
||||
(timeclock-time-to-seconds (car entry))))
|
||||
|
||||
(defsubst timeclock-entry-begin (entry)
|
||||
(car entry))
|
||||
|
||||
(defsubst timeclock-entry-end (entry)
|
||||
(cadr entry))
|
||||
|
||||
(defsubst timeclock-entry-project (entry)
|
||||
(nth 2 entry))
|
||||
|
||||
(defsubst timeclock-entry-comment (entry)
|
||||
(nth 3 entry))
|
||||
|
||||
|
||||
(defsubst timeclock-entry-list-length (entry-list)
|
||||
(let ((length 0))
|
||||
(while entry-list
|
||||
(setq length (+ length (timeclock-entry-length (car entry-list))))
|
||||
(setq entry-list (cdr entry-list)))
|
||||
length))
|
||||
|
||||
(defsubst timeclock-entry-list-begin (entry-list)
|
||||
(timeclock-entry-begin (car entry-list)))
|
||||
|
||||
(defsubst timeclock-entry-list-end (entry-list)
|
||||
(timeclock-entry-end (car (last entry-list))))
|
||||
|
||||
(defsubst timeclock-entry-list-span (entry-list)
|
||||
(- (timeclock-time-to-seconds (timeclock-entry-list-end entry-list))
|
||||
(timeclock-time-to-seconds (timeclock-entry-list-begin entry-list))))
|
||||
|
||||
(defsubst timeclock-entry-list-break (entry-list)
|
||||
(- (timeclock-entry-list-span entry-list)
|
||||
(timeclock-entry-list-length entry-list)))
|
||||
|
||||
(defsubst timeclock-entry-list-projects (entry-list)
|
||||
(let (projects)
|
||||
(while entry-list
|
||||
(let ((project (timeclock-entry-project (car entry-list))))
|
||||
(if projects
|
||||
(add-to-list 'projects project)
|
||||
(setq projects (list project))))
|
||||
(setq entry-list (cdr entry-list)))
|
||||
projects))
|
||||
|
||||
|
||||
(defsubst timeclock-day-required (day)
|
||||
(car day))
|
||||
|
||||
(defsubst timeclock-day-length (day)
|
||||
(timeclock-entry-list-length (cdr day)))
|
||||
|
||||
(defsubst timeclock-day-debt (day)
|
||||
(- (timeclock-day-required day)
|
||||
(timeclock-day-length day)))
|
||||
|
||||
(defsubst timeclock-day-begin (day)
|
||||
(timeclock-entry-list-begin (cdr day)))
|
||||
|
||||
(defsubst timeclock-day-end (day)
|
||||
(timeclock-entry-list-end (cdr day)))
|
||||
|
||||
(defsubst timeclock-day-span (day)
|
||||
(timeclock-entry-list-span (cdr day)))
|
||||
|
||||
(defsubst timeclock-day-break (day)
|
||||
(timeclock-entry-list-break (cdr day)))
|
||||
|
||||
(defsubst timeclock-day-projects (day)
|
||||
(timeclock-entry-list-projects (cdr day)))
|
||||
|
||||
(defmacro timeclock-day-list-template (func)
|
||||
`(let ((length 0))
|
||||
(while day-list
|
||||
(setq length (+ length (,(eval func) (car day-list))))
|
||||
(setq day-list (cdr day-list)))
|
||||
length))
|
||||
|
||||
(defun timeclock-day-list-required (day-list)
|
||||
(timeclock-day-list-template 'timeclock-day-required))
|
||||
|
||||
(defun timeclock-day-list-length (day-list)
|
||||
(timeclock-day-list-template 'timeclock-day-length))
|
||||
|
||||
(defun timeclock-day-list-debt (day-list)
|
||||
(timeclock-day-list-template 'timeclock-day-debt))
|
||||
|
||||
(defsubst timeclock-day-list-begin (day-list)
|
||||
(timeclock-day-begin (car day-list)))
|
||||
|
||||
(defsubst timeclock-day-list-end (day-list)
|
||||
(timeclock-day-end (car (last day-list))))
|
||||
|
||||
(defun timeclock-day-list-span (day-list)
|
||||
(timeclock-day-list-template 'timeclock-day-span))
|
||||
|
||||
(defun timeclock-day-list-break (day-list)
|
||||
(timeclock-day-list-template 'timeclock-day-break))
|
||||
|
||||
(defun timeclock-day-list-projects (day-list)
|
||||
(let (projects)
|
||||
(while day-list
|
||||
(let ((projs (timeclock-day-projects (car day-list))))
|
||||
(while projs
|
||||
(if projects
|
||||
(add-to-list 'projects (car projs))
|
||||
(setq projects (list (car projs))))
|
||||
(setq projs (cdr projs))))
|
||||
(setq day-list (cdr day-list)))
|
||||
projects))
|
||||
|
||||
|
||||
(defsubst timeclock-current-debt (&optional log-data)
|
||||
(nth 0 (or log-data (timeclock-log-data))))
|
||||
|
||||
(defsubst timeclock-day-alist (&optional log-data)
|
||||
(nth 1 (or log-data (timeclock-log-data))))
|
||||
|
||||
(defun timeclock-day-list (&optional log-data)
|
||||
(let ((alist (timeclock-day-alist log-data))
|
||||
day-list)
|
||||
(while alist
|
||||
(setq day-list (cons (cdar alist) day-list)
|
||||
alist (cdr alist)))
|
||||
day-list))
|
||||
|
||||
(defsubst timeclock-project-alist (&optional log-data)
|
||||
(nth 2 (or log-data (timeclock-log-data))))
|
||||
|
||||
|
||||
(defun timeclock-log-data (&optional recent-only filename)
|
||||
"Return the contents of the timelog file, in a useful format.
|
||||
A timelog contains data in the form of a single entry per line.
|
||||
Each entry has the form:
|
||||
|
||||
CODE YYYY/MM/DD HH:MM:SS [COMMENT]
|
||||
|
||||
CODE is one of: b, h, i, o or O. COMMENT is optional when the code is
|
||||
i, o or O. The meanings of the codes are:
|
||||
|
||||
b Set the current time balance, or \"time debt\". Useful when
|
||||
archiving old log data, when a debt must be carried forward.
|
||||
The COMMENT here is the number of seconds of debt.
|
||||
|
||||
h Set the required working time for the given day. This must
|
||||
be the first entry for that day. The COMMENT in this case is
|
||||
the number of hours that must be worked. Floating point
|
||||
amounts are allowed.
|
||||
|
||||
i Clock in. The COMMENT in this case should be the name of the
|
||||
project worked on.
|
||||
|
||||
o Clock out. COMMENT is unnecessary, but can be used to provide
|
||||
a description of how the period went, for example.
|
||||
|
||||
O Final clock out. Whatever project was being worked on, it is
|
||||
now finished. Useful for creating summary reports.
|
||||
|
||||
When this function is called, it will return a data structure with the
|
||||
following format:
|
||||
|
||||
(DEBT ENTRIES-BY-DAY ENTRIES-BY-PROJECT)
|
||||
|
||||
DEBT is a floating point number representing the number of seconds
|
||||
\"owed\" before any work was done. For a new file (one without a 'b'
|
||||
entry), this is always zero.
|
||||
|
||||
The two entries lists have similar formats. They are both alists,
|
||||
where the CAR is the index, and the CDR is a list of time entries.
|
||||
For ENTRIES-BY-DAY, the CAR is a textual date string, of the form
|
||||
YYYY/MM/DD. For ENTRIES-BY-PROJECT, it is the name of the project
|
||||
worked on, or t for the default project.
|
||||
|
||||
The CDR for ENTRIES-BY-DAY is slightly different than for
|
||||
ENTRIES-BY-PROJECT. It has the following form:
|
||||
|
||||
(DAY-LENGTH TIME-ENTRIES...)
|
||||
|
||||
For ENTRIES-BY-PROJECT, there is no DAY-LENGTH member. It is simply a
|
||||
list of TIME-ENTRIES. Note that if DAY-LENGTH is nil, it means
|
||||
whatever is the default should be used.
|
||||
|
||||
A TIME-ENTRY is a recorded time interval. It has the following format
|
||||
\(although generally one does not have to manipulate these entries
|
||||
directly; see below):
|
||||
|
||||
(BEGIN-TIME END-TIME PROJECT [COMMENT] [FINAL-P])
|
||||
|
||||
Anyway, suffice it to say there are a lot of structures. Typically
|
||||
the user is expected to manipulate to the day(s) or project(s) that he
|
||||
or she wants, at which point the following helper functions may be
|
||||
used:
|
||||
|
||||
timeclock-day-required
|
||||
timeclock-day-length
|
||||
timeclock-day-debt
|
||||
timeclock-day-begin
|
||||
timeclock-day-end
|
||||
timeclock-day-span
|
||||
timeclock-day-break
|
||||
timeclock-day-projects
|
||||
|
||||
timeclock-day-list-required
|
||||
timeclock-day-list-length
|
||||
timeclock-day-list-debt
|
||||
timeclock-day-list-begin
|
||||
timeclock-day-list-end
|
||||
timeclock-day-list-span
|
||||
timeclock-day-list-break
|
||||
timeclock-day-list-projects
|
||||
|
||||
timeclock-entry-length
|
||||
timeclock-entry-begin
|
||||
timeclock-entry-end
|
||||
timeclock-entry-project
|
||||
timeclock-entry-comment
|
||||
|
||||
timeclock-entry-list-length
|
||||
timeclock-entry-list-begin
|
||||
timeclock-entry-list-end
|
||||
timeclock-entry-list-span
|
||||
timeclock-entry-list-break
|
||||
timeclock-entry-list-projects
|
||||
|
||||
A few comments should make the use of the above functions obvious:
|
||||
|
||||
`required' is the amount of time that must be spent during a day, or
|
||||
sequence of days, in order to have no debt.
|
||||
|
||||
`length' is the actual amount of time that was spent.
|
||||
|
||||
`debt' is the difference between required time and length. A
|
||||
negative debt signifies overtime.
|
||||
|
||||
`begin' is the earliest moment at which work began.
|
||||
|
||||
`end' is the final moment work was done.
|
||||
|
||||
`span' is the difference between begin and end.
|
||||
|
||||
`break' is the difference between span and length.
|
||||
|
||||
`project' is the project that was worked on, and `projects' is a
|
||||
list of all the projects that were worked on during a given period.
|
||||
|
||||
`comment', where it applies, could mean anything.
|
||||
|
||||
There are a few more functions available, for locating day and entry
|
||||
lists:
|
||||
|
||||
timeclock-day-alist LOG-DATA
|
||||
timeclock-project-alist LOG-DATA
|
||||
timeclock-current-debt LOG-DATA
|
||||
|
||||
See the documentation for the given function if more info is needed."
|
||||
(let* ((log-data (list 0.0 nil nil))
|
||||
(now (current-time))
|
||||
(todays-date (timeclock-time-to-date now))
|
||||
last-date-limited last-date-seconds last-date
|
||||
(line 0) last beg day entry)
|
||||
(with-temp-buffer
|
||||
(insert-file-contents (or filename timeclock-file))
|
||||
(when recent-only
|
||||
(goto-char (point-max))
|
||||
(unless (re-search-backward "^b\\s-+" nil t)
|
||||
(goto-char (point-min))))
|
||||
(while (or (setq event (timeclock-read-moment))
|
||||
(and beg (not last)
|
||||
(setq last t event (list "o" now))))
|
||||
(setq line (1+ line))
|
||||
(cond ((equal (car event) "b")
|
||||
(setcar log-data (string-to-number (nth 2 event))))
|
||||
((equal (car event) "h")
|
||||
(setq last-date-limited (timeclock-time-to-date (cadr event))
|
||||
last-date-seconds (* (string-to-number (nth 2 event))
|
||||
3600.0)))
|
||||
((equal (car event) "i")
|
||||
(if beg
|
||||
(error "Error in format of timelog file, line %d" line)
|
||||
(setq beg t))
|
||||
(setq entry (list (cadr event) nil
|
||||
(and (> (length (nth 2 event)) 0)
|
||||
(nth 2 event))))
|
||||
(let ((date (timeclock-time-to-date (cadr event))))
|
||||
(if (and last-date
|
||||
(not (equal date last-date)))
|
||||
(setcar (cdr log-data)
|
||||
(cons (cons last-date day)
|
||||
(cadr log-data)))
|
||||
(setq day (list (and last-date-limited
|
||||
last-date-seconds))))
|
||||
(setq last-date date
|
||||
last-date-limited nil)))
|
||||
((equal (downcase (car event)) "o")
|
||||
(if (not beg)
|
||||
(error "Error in format of timelog file, line %d" line)
|
||||
(setq beg nil))
|
||||
(setcar (cdr entry) (cadr event))
|
||||
(let ((desc (and (> (length (nth 2 event)) 0)
|
||||
(nth 2 event))))
|
||||
(if desc
|
||||
(nconc entry (list (nth 2 event))))
|
||||
(if (equal (car event) "O")
|
||||
(nconc entry (if desc
|
||||
(list t)
|
||||
(list nil t))))
|
||||
(nconc day (list entry))
|
||||
(setq desc (nth 2 entry))
|
||||
(let ((proj (assoc desc (nth 2 log-data))))
|
||||
(if (not proj)
|
||||
(setcar (cddr log-data)
|
||||
(cons (cons desc (list entry))
|
||||
(car (cddr log-data))))
|
||||
(nconc (cdr proj) (list entry)))))))
|
||||
(forward-line))
|
||||
(if day
|
||||
(setcar (cdr log-data)
|
||||
(cons (cons last-date day)
|
||||
(cadr log-data))))
|
||||
log-data)))
|
||||
|
||||
(defun timeclock-find-discrep (&optional today-only)
|
||||
"Find overall discrepancy from `timeclock-workday' (in seconds).
|
||||
If TODAY-ONLY is non-nil, the discrepancy will be not be relative, and
|
||||
will correspond only to the amount of time elapsed today. This is
|
||||
identical to what would be return if `timeclock-relative' were nil."
|
||||
(let* ((now (current-time)) (first t)
|
||||
;; This is not implemented in terms of the functions above, because
|
||||
;; it's a bit wasteful to read all of that data in, just to throw
|
||||
;; away more than 90% of the information afterwards.
|
||||
(let* ((now (current-time))
|
||||
(todays-date (timeclock-time-to-date now))
|
||||
accum event beg last-date
|
||||
last-date-limited last-date-seconds avg)
|
||||
(first t) (accum 0)
|
||||
event beg last-date avg
|
||||
last-date-limited last-date-seconds)
|
||||
(unless timeclock-discrepancy
|
||||
(setq timeclock-project-list nil
|
||||
timeclock-last-project nil
|
||||
timeclock-reason-list nil)
|
||||
(save-excursion
|
||||
(set-buffer (find-file-noselect timeclock-file))
|
||||
(goto-char (point-min))
|
||||
(setq accum 0)
|
||||
(setq timeclock-elapsed 0)
|
||||
timeclock-reason-list nil
|
||||
timeclock-elapsed 0)
|
||||
(with-temp-buffer
|
||||
(insert-file-contents timeclock-file)
|
||||
(goto-char (point-max))
|
||||
(unless (re-search-backward "^b\\s-+" nil t)
|
||||
(goto-char (point-min)))
|
||||
(while (setq event (timeclock-read-moment))
|
||||
(cond ((equal (car event) "h")
|
||||
(cond ((equal (car event) "b")
|
||||
(setq accum (string-to-number (nth 2 event))))
|
||||
((equal (car event) "h")
|
||||
(setq last-date-limited
|
||||
(timeclock-time-to-date (cadr event))
|
||||
last-date-seconds
|
||||
(* (string-to-number (nth 2 event)) 3600)))
|
||||
(* (string-to-number (nth 2 event)) 3600.0)))
|
||||
((equal (car event) "i")
|
||||
(when (and (nth 2 event)
|
||||
(> (length (nth 2 event)) 0))
|
||||
(add-to-list 'timeclock-project-list (nth 2 event))
|
||||
(setq timeclock-last-project (nth 2 event)))
|
||||
(let ((date (timeclock-time-to-date (cadr event))))
|
||||
(if (and last-date
|
||||
timeclock-relative
|
||||
(not (equal date last-date)))
|
||||
(setq accum (- accum
|
||||
(if last-date-limited
|
||||
last-date-seconds
|
||||
timeclock-workday)))
|
||||
(unless (or last-date (not first))
|
||||
(if (and timeclock-relative
|
||||
(if last-date
|
||||
(not (equal date last-date))
|
||||
first))
|
||||
(setq first nil
|
||||
accum (- accum
|
||||
(if last-date-limited
|
||||
last-date-seconds
|
||||
timeclock-workday)))))
|
||||
timeclock-workday))))
|
||||
(setq last-date date
|
||||
last-date-limited nil)
|
||||
(if beg
|
||||
|
@ -712,8 +1035,7 @@ identical to what would be return if `timeclock-relative' were nil."
|
|||
(if (not beg)
|
||||
(error "Error in format of timelog file!")
|
||||
(setq timeclock-last-period
|
||||
(- (timeclock-time-to-seconds (cadr event))
|
||||
beg)
|
||||
(- (timeclock-time-to-seconds (cadr event)) beg)
|
||||
accum (+ timeclock-last-period accum)
|
||||
beg nil)))
|
||||
(if (equal last-date todays-date)
|
||||
|
|
|
@ -151,7 +151,12 @@ command, which will automatically write them to the file named by
|
|||
(add-hook 'eshell-alternate-command-hook 'eshell-fix-bad-commands t t)
|
||||
(eshell-read-aliases-list)
|
||||
(make-local-hook 'eshell-named-command-hook)
|
||||
(add-hook 'eshell-named-command-hook 'eshell-maybe-replace-by-alias t t))
|
||||
(add-hook 'eshell-named-command-hook 'eshell-maybe-replace-by-alias t t)
|
||||
(make-local-variable 'eshell-complex-commands)
|
||||
(add-to-list 'eshell-complex-commands 'eshell-command-aliased-p))
|
||||
|
||||
(defun eshell-command-aliased-p (name)
|
||||
(member name eshell-command-aliases-list))
|
||||
|
||||
(defun eshell/alias (&optional alias &rest definition)
|
||||
"Define an ALIAS in the user's alias list using DEFINITION."
|
||||
|
|
|
@ -297,7 +297,7 @@ Thus, this does not include the current directory.")
|
|||
(file-name-as-directory (cdr user))))
|
||||
eshell-user-names)))))))
|
||||
|
||||
(defun eshell/pwd (&rest args) ; ignored
|
||||
(defun eshell/pwd (&rest args)
|
||||
"Change output from `pwd` to be cleaner."
|
||||
(let* ((path default-directory)
|
||||
(len (length path)))
|
||||
|
@ -307,8 +307,8 @@ Thus, this does not include the current directory.")
|
|||
(string-match "\\`[A-Za-z]:[\\\\/]\\'" path))))
|
||||
(setq path (substring path 0 (1- (length path)))))
|
||||
(if eshell-pwd-convert-function
|
||||
(setq path (funcall eshell-pwd-convert-function path)))
|
||||
path))
|
||||
(funcall eshell-pwd-convert-function path)
|
||||
path)))
|
||||
|
||||
(defun eshell-expand-multiple-dots (path)
|
||||
"Convert '...' to '../..', '....' to '../../..', etc..
|
||||
|
|
|
@ -81,8 +81,9 @@ by zsh for filename generation."
|
|||
:type 'boolean
|
||||
:group 'eshell-glob)
|
||||
|
||||
(defcustom eshell-glob-show-progress t
|
||||
"*If non-nil, display progress messages during a recursive glob."
|
||||
(defcustom eshell-glob-show-progress nil
|
||||
"*If non-nil, display progress messages during a recursive glob.
|
||||
This option slows down recursive glob processing by quite a bit."
|
||||
:type 'boolean
|
||||
:group 'eshell-glob)
|
||||
|
||||
|
|
|
@ -57,6 +57,12 @@ properties to colorize its output based on the setting of
|
|||
:type 'hook
|
||||
:group 'eshell-ls)
|
||||
|
||||
(defcustom eshell-ls-initial-args nil
|
||||
"*If non-nil, this list of args is included before any call to `ls'.
|
||||
This is useful for enabling human-readable format (-h), for example."
|
||||
:type '(repeat :tag "Arguments" string)
|
||||
:group 'eshell-ls)
|
||||
|
||||
(defcustom eshell-ls-use-in-dired nil
|
||||
"*If non-nil, use `eshell-ls' to read directories in dired."
|
||||
:set (lambda (symbol value)
|
||||
|
@ -77,11 +83,18 @@ properties to colorize its output based on the setting of
|
|||
:type 'integer
|
||||
:group 'eshell-ls)
|
||||
|
||||
(defcustom eshell-ls-exclude-regexp "\\`\\."
|
||||
(defcustom eshell-ls-exclude-regexp nil
|
||||
"*Unless -a is specified, files matching this regexp will not be shown."
|
||||
:type 'regexp
|
||||
:group 'eshell-ls)
|
||||
|
||||
(defcustom eshell-ls-exclude-hidden t
|
||||
"*Unless -a is specified, files beginning with . will not be shown.
|
||||
Using this boolean, instead of `eshell-ls-exclude-regexp', is both
|
||||
faster and conserves more memory."
|
||||
:type 'boolean
|
||||
:group 'eshell-ls)
|
||||
|
||||
(defcustom eshell-ls-use-colors t
|
||||
"*If non-nil, use colors in file listings."
|
||||
:type 'boolean
|
||||
|
@ -196,13 +209,13 @@ This is really just for efficiency, to avoid having to stat the file
|
|||
yet again."
|
||||
`(if (numberp (nth 2 ,attrs))
|
||||
(if (= (user-uid) (nth 2 ,attrs))
|
||||
(not (eq (aref (nth 8 ,attrs) ,index) ?-))
|
||||
(,(eval func) ,file))
|
||||
(not (eq (aref (nth 8 ,attrs) ,index) ?-))
|
||||
(,(eval func) ,file))
|
||||
(not (eq (aref (nth 8 ,attrs)
|
||||
(+ ,index (if (member (nth 2 ,attrs)
|
||||
(eshell-current-ange-uids))
|
||||
0 6)))
|
||||
?-))))
|
||||
(+ ,index (if (member (nth 2 ,attrs)
|
||||
(eshell-current-ange-uids))
|
||||
0 6)))
|
||||
?-))))
|
||||
|
||||
(defcustom eshell-ls-highlight-alist nil
|
||||
"*This alist correlates test functions to color.
|
||||
|
@ -248,7 +261,8 @@ instead."
|
|||
(symbol-value 'font-lock-buffers)))))
|
||||
(let ((insert-func 'insert)
|
||||
(error-func 'insert)
|
||||
(flush-func 'ignore))
|
||||
(flush-func 'ignore)
|
||||
eshell-ls-initial-args)
|
||||
(eshell-do-ls (append switches (list file))))))))
|
||||
|
||||
(defsubst eshell/ls (&rest args)
|
||||
|
@ -281,7 +295,9 @@ instead."
|
|||
(funcall flush-func -1)
|
||||
;; process the command arguments, and begin listing files
|
||||
(eshell-eval-using-options
|
||||
"ls" args
|
||||
"ls" (if eshell-ls-initial-args
|
||||
(list eshell-ls-initial-args args)
|
||||
args)
|
||||
`((?a "all" nil show-all
|
||||
"show all files in directory")
|
||||
(?c nil by-ctime sort-method
|
||||
|
@ -343,11 +359,11 @@ Sort entries alphabetically across.")
|
|||
(error (concat "-I option requires that `eshell-glob'"
|
||||
" be a member of `eshell-modules-list'")))
|
||||
(set-text-properties 0 (length ignore-pattern) nil ignore-pattern)
|
||||
(if eshell-ls-exclude-regexp
|
||||
(setq eshell-ls-exclude-regexp
|
||||
(setq eshell-ls-exclude-regexp
|
||||
(if eshell-ls-exclude-regexp
|
||||
(concat "\\(" eshell-ls-exclude-regexp "\\|"
|
||||
(eshell-glob-regexp ignore-pattern) "\\)"))
|
||||
(setq eshell-ls-exclude-regexp (eshell-glob-regexp ignore-pattern))))
|
||||
(eshell-glob-regexp ignore-pattern) "\\)")
|
||||
(eshell-glob-regexp ignore-pattern))))
|
||||
;; list the files!
|
||||
(eshell-ls-entries
|
||||
(mapcar (function
|
||||
|
@ -356,7 +372,8 @@ Sort entries alphabetically across.")
|
|||
(file-name-absolute-p arg))
|
||||
(expand-file-name arg)
|
||||
arg)
|
||||
(eshell-file-attributes arg)))) args)
|
||||
(eshell-file-attributes arg))))
|
||||
args)
|
||||
t (expand-file-name default-directory)))
|
||||
(funcall flush-func)))
|
||||
|
||||
|
@ -491,12 +508,13 @@ relative to that directory."
|
|||
(file-relative-name dir root-dir)
|
||||
(expand-file-name dir)))
|
||||
(cdr dirinfo))) ":\n"))
|
||||
(let ((entries
|
||||
(eshell-directory-files-and-attributes dir nil nil t)))
|
||||
(unless show-all
|
||||
(while (and entries
|
||||
(string-match eshell-ls-exclude-regexp
|
||||
(caar entries)))
|
||||
(let ((entries (eshell-directory-files-and-attributes
|
||||
dir nil (and (not show-all)
|
||||
eshell-ls-exclude-hidden
|
||||
"\\`[^.]") t)))
|
||||
(when (and (not show-all) eshell-ls-exclude-regexp)
|
||||
(while (and entries (string-match eshell-ls-exclude-regexp
|
||||
(caar entries)))
|
||||
(setq entries (cdr entries)))
|
||||
(let ((e entries))
|
||||
(while (cdr e)
|
||||
|
@ -552,17 +570,13 @@ In Eshell's implementation of ls, ENTRIES is always reversed."
|
|||
(let ((result
|
||||
(cond
|
||||
((eq sort-method 'by-atime)
|
||||
(eshell-ls-compare-entries
|
||||
l r 4 'eshell-time-less-p))
|
||||
(eshell-ls-compare-entries l r 4 'eshell-time-less-p))
|
||||
((eq sort-method 'by-mtime)
|
||||
(eshell-ls-compare-entries
|
||||
l r 5 'eshell-time-less-p))
|
||||
(eshell-ls-compare-entries l r 5 'eshell-time-less-p))
|
||||
((eq sort-method 'by-ctime)
|
||||
(eshell-ls-compare-entries
|
||||
l r 6 'eshell-time-less-p))
|
||||
(eshell-ls-compare-entries l r 6 'eshell-time-less-p))
|
||||
((eq sort-method 'by-size)
|
||||
(eshell-ls-compare-entries
|
||||
l r 7 '<))
|
||||
(eshell-ls-compare-entries l r 7 '<))
|
||||
((eq sort-method 'by-extension)
|
||||
(let ((lx (file-name-extension
|
||||
(directory-file-name (car l))))
|
||||
|
@ -699,8 +713,8 @@ need to be printed."
|
|||
(if (and need-return (not dir-literal))
|
||||
(funcall insert-func "\n"))
|
||||
(eshell-ls-dir dir show-names
|
||||
(unless (file-name-absolute-p (car dir))
|
||||
root-dir) size-width)
|
||||
(unless (file-name-absolute-p (car dir)) root-dir)
|
||||
size-width)
|
||||
(setq need-return t))))
|
||||
|
||||
(defun eshell-ls-find-column-widths (files)
|
||||
|
|
|
@ -63,6 +63,9 @@ This includes when running `eshell-command'."
|
|||
(string= (file-name-nondirectory file)
|
||||
"eshell")) . eshell/source)
|
||||
eshell-interpreter-alist))
|
||||
(make-local-variable 'eshell-complex-commands)
|
||||
(setq eshell-complex-commands
|
||||
(append '("source" ".") eshell-complex-commands))
|
||||
;; these two variables are changed through usage, but we don't want
|
||||
;; to ruin it for other modules
|
||||
(let (eshell-inside-quote-regexp
|
||||
|
|
|
@ -77,6 +77,11 @@ it to get a real sense of how it works."
|
|||
;; scroll, etc.
|
||||
;;
|
||||
;; @ Like I said, it's not really comprehensible until you try it! ;)
|
||||
;;
|
||||
;; One disadvantage of this module is that it increases Eshell's
|
||||
;; memory consumption by a factor of two or more. With small commands
|
||||
;; (such as pwd), where the screen is mostly full, consumption can
|
||||
;; increase by orders of magnitude.
|
||||
|
||||
;;; User Variables:
|
||||
|
||||
|
@ -154,6 +159,7 @@ The options are `begin', `after' or `end'."
|
|||
|
||||
(defvar eshell-smart-displayed nil)
|
||||
(defvar eshell-smart-command-done nil)
|
||||
(defvar eshell-currently-handling-window nil)
|
||||
|
||||
;;; Functions:
|
||||
|
||||
|
@ -175,19 +181,17 @@ The options are `begin', `after' or `end'."
|
|||
|
||||
(make-local-hook 'pre-command-hook)
|
||||
(make-local-hook 'after-change-functions)
|
||||
(add-hook 'after-change-functions
|
||||
'eshell-disable-after-change nil t)
|
||||
(add-hook 'after-change-functions 'eshell-disable-after-change nil t)
|
||||
|
||||
(make-local-hook 'eshell-input-filter-functions)
|
||||
(add-hook 'eshell-input-filter-functions
|
||||
'eshell-smart-display-setup nil t)
|
||||
(add-hook 'eshell-input-filter-functions 'eshell-smart-display-setup nil t)
|
||||
|
||||
(make-local-variable 'eshell-smart-command-done)
|
||||
(make-local-hook 'eshell-post-command-hook)
|
||||
(add-hook 'eshell-post-command-hook
|
||||
(function
|
||||
(lambda ()
|
||||
(setq eshell-smart-command-done t))) t t)
|
||||
(add-hook 'eshell-post-command-hook
|
||||
(function
|
||||
(lambda ()
|
||||
(setq eshell-smart-command-done t))) t t)
|
||||
|
||||
(unless (eq eshell-review-quick-commands t)
|
||||
(add-hook 'eshell-post-command-hook
|
||||
|
@ -198,10 +202,9 @@ The options are `begin', `after' or `end'."
|
|||
(unless eshell-currently-handling-window
|
||||
(let ((inhibit-point-motion-hooks t)
|
||||
(eshell-currently-handling-window t))
|
||||
(save-current-buffer
|
||||
(save-selected-window
|
||||
(select-window wind)
|
||||
(eshell-smart-redisplay))))))
|
||||
(save-selected-window
|
||||
(select-window wind)
|
||||
(eshell-smart-redisplay)))))
|
||||
|
||||
(defun eshell-refresh-windows (&optional frame)
|
||||
"Refresh all visible Eshell buffers."
|
||||
|
@ -210,10 +213,10 @@ The options are `begin', `after' or `end'."
|
|||
(function
|
||||
(lambda (wind)
|
||||
(with-current-buffer (window-buffer wind)
|
||||
(when eshell-mode
|
||||
(let (window-scroll-functions)
|
||||
(eshell-smart-scroll-window wind (window-start))
|
||||
(setq affected t))))))
|
||||
(if eshell-mode
|
||||
(let (window-scroll-functions)
|
||||
(eshell-smart-scroll-window wind (window-start))
|
||||
(setq affected t))))))
|
||||
0 frame)
|
||||
(if affected
|
||||
(let (window-scroll-functions)
|
||||
|
|
|
@ -124,6 +124,11 @@ Otherwise, `rmdir' is required."
|
|||
:type 'boolean
|
||||
:group 'eshell-unix)
|
||||
|
||||
(defcustom eshell-default-target-is-dot nil
|
||||
"*If non-nil, the default destination for cp, mv or ln is `.'."
|
||||
:type 'boolean
|
||||
:group 'eshell-unix)
|
||||
|
||||
(defcustom eshell-du-prefer-over-ange nil
|
||||
"*Use Eshell's du in ange-ftp remote directories.
|
||||
Otherwise, Emacs will attempt to use rsh to invoke du on the remote machine."
|
||||
|
@ -140,7 +145,12 @@ Otherwise, Emacs will attempt to use rsh to invoke du on the remote machine."
|
|||
(when (eshell-using-module 'eshell-cmpl)
|
||||
(make-local-hook 'pcomplete-try-first-hook)
|
||||
(add-hook 'pcomplete-try-first-hook
|
||||
'eshell-complete-host-reference nil t)))
|
||||
'eshell-complete-host-reference nil t))
|
||||
(make-local-variable 'eshell-complex-commands)
|
||||
(setq eshell-complex-commands
|
||||
(append '("grep" "egrep" "fgrep" "agrep" "glimpse" "locate"
|
||||
"cat" "time" "cp" "mv" "make" "du" "diff")
|
||||
eshell-complex-commands)))
|
||||
|
||||
(defalias 'eshell/date 'current-time-string)
|
||||
(defalias 'eshell/basename 'file-name-nondirectory)
|
||||
|
@ -157,6 +167,7 @@ Otherwise, Emacs will attempt to use rsh to invoke du on the remote machine."
|
|||
(funcall 'man (apply 'eshell-flatten-and-stringify args)))
|
||||
|
||||
(defun eshell-remove-entries (path files &optional top-level)
|
||||
"From PATH, remove all of the given FILES, perhaps interactively."
|
||||
(while files
|
||||
(if (string-match "\\`\\.\\.?\\'"
|
||||
(file-name-nondirectory (car files)))
|
||||
|
@ -302,8 +313,6 @@ Remove the DIRECTORY(ies), if they are empty.")
|
|||
|
||||
(defun eshell-shuffle-files (command action files target func deep &rest args)
|
||||
"Shuffle around some filesystem entries, using FUNC to do the work."
|
||||
(if (null target)
|
||||
(error "%s: missing destination file" command))
|
||||
(let ((attr-target (eshell-file-attributes target))
|
||||
(is-dir (or (file-directory-p target)
|
||||
(and preview (not eshell-warn-dot-directories))))
|
||||
|
@ -417,30 +426,35 @@ Remove the DIRECTORY(ies), if they are empty.")
|
|||
(format "tar %s %s" tar-args archive) args))))
|
||||
|
||||
;; this is to avoid duplicating code...
|
||||
(defmacro eshell-mvcp-template
|
||||
(command action func query-var force-var &optional preserve)
|
||||
`(if (and (string-match eshell-tar-regexp (car (last args)))
|
||||
(or (> (length args) 2)
|
||||
(and (file-directory-p (car args))
|
||||
(or (not no-dereference)
|
||||
(not (file-symlink-p (car args)))))))
|
||||
(eshell-shorthand-tar-command ,command args)
|
||||
(let (target ange-cache)
|
||||
(if (> (length args) 1)
|
||||
(progn
|
||||
(setq target (car (last args)))
|
||||
(setcdr (last args 2) nil))
|
||||
(setq args nil))
|
||||
(eshell-shuffle-files
|
||||
,command ,action args target ,func nil
|
||||
,@(append
|
||||
`((if (and (or interactive
|
||||
,query-var)
|
||||
(not force))
|
||||
1 (or force ,force-var)))
|
||||
(if preserve
|
||||
(list preserve)))))
|
||||
nil))
|
||||
(defmacro eshell-mvcpln-template (command action func query-var
|
||||
force-var &optional preserve)
|
||||
`(let ((len (length args)))
|
||||
(if (or (= len 0)
|
||||
(and (= len 1) (null eshell-default-target-is-dot)))
|
||||
(error "%s: missing destination file or directory" ,command))
|
||||
(if (= len 1)
|
||||
(nconc args '(".")))
|
||||
(setq args (eshell-stringify-list (eshell-flatten-list args)))
|
||||
(if (and ,(not (equal command "ln"))
|
||||
(string-match eshell-tar-regexp (car (last args)))
|
||||
(or (> (length args) 2)
|
||||
(and (file-directory-p (car args))
|
||||
(or (not no-dereference)
|
||||
(not (file-symlink-p (car args)))))))
|
||||
(eshell-shorthand-tar-command ,command args)
|
||||
(let ((target (car (last args)))
|
||||
ange-cache)
|
||||
(setcdr (last args 2) nil)
|
||||
(eshell-shuffle-files
|
||||
,command ,action args target ,func nil
|
||||
,@(append
|
||||
`((if (and (or interactive
|
||||
,query-var)
|
||||
(not force))
|
||||
1 (or force ,force-var)))
|
||||
(if preserve
|
||||
(list preserve)))))
|
||||
nil)))
|
||||
|
||||
(defun eshell/mv (&rest args)
|
||||
"Implementation of mv in Lisp."
|
||||
|
@ -455,6 +469,7 @@ Remove the DIRECTORY(ies), if they are empty.")
|
|||
(?v "verbose" nil verbose
|
||||
"explain what is being done")
|
||||
(nil "help" nil nil "show this usage screen")
|
||||
:preserve-args
|
||||
:external "mv"
|
||||
:show-usage
|
||||
:usage "[OPTION]... SOURCE DEST
|
||||
|
@ -462,9 +477,9 @@ Remove the DIRECTORY(ies), if they are empty.")
|
|||
Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.
|
||||
\[OPTION] DIRECTORY...")
|
||||
(let ((no-dereference t))
|
||||
(eshell-mvcp-template "mv" "moving" 'rename-file
|
||||
eshell-mv-interactive-query
|
||||
eshell-mv-overwrite-files))))
|
||||
(eshell-mvcpln-template "mv" "moving" 'rename-file
|
||||
eshell-mv-interactive-query
|
||||
eshell-mv-overwrite-files))))
|
||||
|
||||
(defun eshell/cp (&rest args)
|
||||
"Implementation of cp in Lisp."
|
||||
|
@ -487,6 +502,7 @@ Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.
|
|||
(?v "verbose" nil verbose
|
||||
"explain what is being done")
|
||||
(nil "help" nil nil "show this usage screen")
|
||||
:preserve-args
|
||||
:external "cp"
|
||||
:show-usage
|
||||
:usage "[OPTION]... SOURCE DEST
|
||||
|
@ -494,9 +510,9 @@ Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.
|
|||
Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.")
|
||||
(if archive
|
||||
(setq preserve t no-dereference t recursive t))
|
||||
(eshell-mvcp-template "cp" "copying" 'copy-file
|
||||
eshell-cp-interactive-query
|
||||
eshell-cp-overwrite-files preserve)))
|
||||
(eshell-mvcpln-template "cp" "copying" 'copy-file
|
||||
eshell-cp-interactive-query
|
||||
eshell-cp-overwrite-files preserve)))
|
||||
|
||||
(defun eshell/ln (&rest args)
|
||||
"Implementation of ln in Lisp."
|
||||
|
@ -505,11 +521,13 @@ Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.")
|
|||
'((?h "help" nil nil "show this usage screen")
|
||||
(?s "symbolic" nil symbolic
|
||||
"make symbolic links instead of hard links")
|
||||
(?i "interactive" nil interactive "request confirmation if target already exists")
|
||||
(?i "interactive" nil interactive
|
||||
"request confirmation if target already exists")
|
||||
(?f "force" nil force "remove existing destinations, never prompt")
|
||||
(?n "preview" nil preview
|
||||
"don't change anything on disk")
|
||||
(?v "verbose" nil verbose "explain what is being done")
|
||||
:preserve-args
|
||||
:external "ln"
|
||||
:show-usage
|
||||
:usage "[OPTION]... TARGET [LINK_NAME]
|
||||
|
@ -518,27 +536,19 @@ Create a link to the specified TARGET with optional LINK_NAME. If there is
|
|||
more than one TARGET, the last argument must be a directory; create links
|
||||
in DIRECTORY to each TARGET. Create hard links by default, symbolic links
|
||||
with '--symbolic'. When creating hard links, each TARGET must exist.")
|
||||
(let (target no-dereference ange-cache)
|
||||
(if (> (length args) 1)
|
||||
(progn
|
||||
(setq target (car (last args)))
|
||||
(setcdr (last args 2) nil))
|
||||
(setq args nil))
|
||||
(eshell-shuffle-files "ln" "linking" args target
|
||||
(if symbolic
|
||||
'make-symbolic-link
|
||||
'add-name-to-file) nil
|
||||
(if (and (or interactive
|
||||
eshell-ln-interactive-query)
|
||||
(not force))
|
||||
1 (or force eshell-ln-overwrite-files))))
|
||||
nil))
|
||||
(let ((no-dereference t))
|
||||
(eshell-mvcpln-template "ln" "linking"
|
||||
(if symbolic
|
||||
'make-symbolic-link
|
||||
'add-name-to-file)
|
||||
eshell-ln-interactive-query
|
||||
eshell-ln-overwrite-files))))
|
||||
|
||||
(defun eshell/cat (&rest args)
|
||||
"Implementation of cat in Lisp.
|
||||
If in a pipeline, or the file is not a regular file, directory or
|
||||
symlink, then revert to the system's definition of cat."
|
||||
(setq args (eshell-flatten-list args))
|
||||
(setq args (eshell-stringify-list (eshell-flatten-list args)))
|
||||
(if (or eshell-in-pipeline-p
|
||||
(catch 'special
|
||||
(eshell-for arg args
|
||||
|
@ -593,7 +603,8 @@ Concatenate FILE(s), or standard input, to standard output.")
|
|||
(list 'quote (eshell-copy-environment))))))
|
||||
(compile (concat "make " (eshell-flatten-and-stringify args))))
|
||||
(throw 'eshell-replace-command
|
||||
(eshell-parse-command "*make" (eshell-flatten-list args)))))
|
||||
(eshell-parse-command "*make" (eshell-stringify-list
|
||||
(eshell-flatten-list args))))))
|
||||
|
||||
(defun eshell-occur-mode-goto-occurrence ()
|
||||
"Go to the occurrence the current line describes."
|
||||
|
@ -627,7 +638,8 @@ available..."
|
|||
(default-directory default-dir))
|
||||
(erase-buffer)
|
||||
(occur-mode)
|
||||
(let ((files (eshell-flatten-list (cdr args)))
|
||||
(let ((files (eshell-stringify-list
|
||||
(eshell-flatten-list (cdr args))))
|
||||
(inhibit-redisplay t)
|
||||
string)
|
||||
(when (car args)
|
||||
|
@ -670,14 +682,16 @@ external command."
|
|||
(not eshell-in-subcommand-p))))
|
||||
(throw 'eshell-replace-command
|
||||
(eshell-parse-command (concat "*" command)
|
||||
(eshell-flatten-list args)))
|
||||
(eshell-stringify-list
|
||||
(eshell-flatten-list args))))
|
||||
(let* ((compilation-process-setup-function
|
||||
(list 'lambda nil
|
||||
(list 'setq 'process-environment
|
||||
(list 'quote (eshell-copy-environment)))))
|
||||
(args (mapconcat 'identity
|
||||
(mapcar 'shell-quote-argument
|
||||
(eshell-flatten-list args))
|
||||
(eshell-stringify-list
|
||||
(eshell-flatten-list args)))
|
||||
" "))
|
||||
(cmd (progn
|
||||
(set-text-properties 0 (length args)
|
||||
|
@ -797,7 +811,7 @@ external command."
|
|||
(defun eshell/du (&rest args)
|
||||
"Implementation of \"du\" in Lisp, passing ARGS."
|
||||
(setq args (if args
|
||||
(eshell-flatten-list args)
|
||||
(eshell-stringify-list (eshell-flatten-list args))
|
||||
'(".")))
|
||||
(let ((ext-du (eshell-search-path "du")))
|
||||
(if (and ext-du
|
||||
|
@ -909,7 +923,7 @@ Show wall-clock time elapsed during execution of COMMAND.")
|
|||
|
||||
(defun eshell/diff (&rest args)
|
||||
"Alias \"diff\" to call Emacs `diff' function."
|
||||
(let ((orig-args (eshell-flatten-list args)))
|
||||
(let ((orig-args (eshell-stringify-list (eshell-flatten-list args))))
|
||||
(if (or eshell-plain-diff-behavior
|
||||
(not (and (eshell-interactive-output-p)
|
||||
(not eshell-in-pipeline-p)
|
||||
|
@ -951,7 +965,8 @@ Show wall-clock time elapsed during execution of COMMAND.")
|
|||
(and (stringp (car args))
|
||||
(string-match "^-" (car args))))
|
||||
(throw 'eshell-replace-command
|
||||
(eshell-parse-command "*locate" (eshell-flatten-list args)))
|
||||
(eshell-parse-command "*locate" (eshell-stringify-list
|
||||
(eshell-flatten-list args))))
|
||||
(save-selected-window
|
||||
(let ((locate-history-list (list (car args))))
|
||||
(locate-with-filter (car args) (cadr args))))))
|
||||
|
|
|
@ -203,6 +203,21 @@ which may be modified directly. Any return value is ignored."
|
|||
:type 'hook
|
||||
:group 'eshell-cmd)
|
||||
|
||||
(defcustom eshell-complex-commands nil
|
||||
"*A list of commands names or functions, that determine complexity.
|
||||
That is, if a command is defined by a function named eshell/NAME,
|
||||
and NAME is part of this list, it is invoked as a complex command.
|
||||
Complex commands are always correct, but run much slower. If a
|
||||
command works fine without being part of this list, then it doesn't
|
||||
need to be.
|
||||
|
||||
If an entry is a function, it will be called with the name, and should
|
||||
return non-nil if the command is complex."
|
||||
:type '(repeat :tag "Commands"
|
||||
(choice (string :tag "Name")
|
||||
(function :tag "Predicate")))
|
||||
:group 'eshell-cmd)
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'esh-util)
|
||||
|
@ -518,8 +533,8 @@ implemented via rewriting, rather than as a function."
|
|||
(list 'car
|
||||
(list 'symbol-value
|
||||
(list 'quote 'for-items)))))
|
||||
(list 'eshell-copy-handles
|
||||
(eshell-invokify-arg body t)))
|
||||
(list 'eshell-protect
|
||||
(eshell-invokify-arg body t)))
|
||||
(list 'setcar 'for-items
|
||||
(list 'cadr
|
||||
(list 'symbol-value
|
||||
|
@ -583,7 +598,7 @@ must be implemented via rewriting, rather than as a function."
|
|||
(eshell-structure-basic-command
|
||||
'while '("while" "until") (car terms)
|
||||
(eshell-invokify-arg (cadr terms) nil t)
|
||||
(list 'eshell-copy-handles
|
||||
(list 'eshell-protect
|
||||
(eshell-invokify-arg (car (last terms)) t)))))
|
||||
|
||||
(defun eshell-rewrite-if-command (terms)
|
||||
|
@ -596,13 +611,15 @@ must be implemented via rewriting, rather than as a function."
|
|||
(eshell-structure-basic-command
|
||||
'if '("if" "unless") (car terms)
|
||||
(eshell-invokify-arg (cadr terms) nil t)
|
||||
(eshell-invokify-arg
|
||||
(if (= (length terms) 5)
|
||||
(car (last terms 3))
|
||||
(car (last terms))) t)
|
||||
(eshell-invokify-arg
|
||||
(if (= (length terms) 5)
|
||||
(car (last terms))) t))))
|
||||
(list 'eshell-protect
|
||||
(eshell-invokify-arg
|
||||
(if (= (length terms) 5)
|
||||
(car (last terms 3))
|
||||
(car (last terms))) t))
|
||||
(if (= (length terms) 5)
|
||||
(list 'eshell-protect
|
||||
(eshell-invokify-arg
|
||||
(car (last terms)))) t))))
|
||||
|
||||
(defun eshell-exit-success-p ()
|
||||
"Return non-nil if the last command was \"successful\".
|
||||
|
@ -651,8 +668,8 @@ For an external command, it means an exit code of 0."
|
|||
(assert (car sep-terms))
|
||||
(setq final (eshell-structure-basic-command
|
||||
'if (string= (car sep-terms) "&&") "if"
|
||||
(list 'eshell-commands (car results))
|
||||
final
|
||||
(list 'eshell-protect (car results))
|
||||
(list 'eshell-protect final)
|
||||
nil t)
|
||||
results (cdr results)
|
||||
sep-terms (cdr sep-terms)))
|
||||
|
@ -690,8 +707,8 @@ For an external command, it means an exit code of 0."
|
|||
(list 'eshell-lisp-command (list 'quote obj)))
|
||||
(ignore (goto-char here))))))
|
||||
|
||||
(defun eshell-separate-commands
|
||||
(terms separator &optional reversed last-terms-sym)
|
||||
(defun eshell-separate-commands (terms separator &optional
|
||||
reversed last-terms-sym)
|
||||
"Separate TERMS using SEPARATOR.
|
||||
If REVERSED is non-nil, the list of separated term groups will be
|
||||
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'..."
|
|||
(eshell-errorn (error-message-string err))
|
||||
(eshell-close-handles 1)))))
|
||||
|
||||
;; (defun eshell-copy-or-protect-handles ()
|
||||
;; (if (eshell-processp (car (aref eshell-current-handles
|
||||
;; eshell-output-handle)))
|
||||
;; (eshell-protect-handles eshell-current-handles)
|
||||
;; (eshell-create-handles
|
||||
;; (car (aref eshell-current-handles
|
||||
;; eshell-output-handle)) nil
|
||||
;; (car (aref eshell-current-handles
|
||||
;; eshell-error-handle)) nil)))
|
||||
|
||||
;; (defmacro eshell-copy-handles (object)
|
||||
;; "Duplicate current I/O handles, so OBJECT works with its own copy."
|
||||
;; `(let ((eshell-current-handles (eshell-copy-or-protect-handles)))
|
||||
;; ,object))
|
||||
|
||||
(defmacro eshell-copy-handles (object)
|
||||
"Duplicate current I/O handles, so OBJECT works with its own copy."
|
||||
`(let ((eshell-current-handles
|
||||
|
@ -965,6 +967,22 @@ at the moment are:
|
|||
(if subform
|
||||
(concat "\n\n" (eshell-stringify subform)) ""))))))
|
||||
|
||||
(defun eshell-invoke-directly (command input)
|
||||
(let ((base (cadr (nth 2 (nth 2 (cadr command))))) name)
|
||||
(if (and (eq (car base) 'eshell-trap-errors)
|
||||
(eq (car (cadr base)) 'eshell-named-command))
|
||||
(setq name (cadr (cadr base))))
|
||||
(and name (stringp name)
|
||||
(not (member name eshell-complex-commands))
|
||||
(catch 'simple
|
||||
(progn
|
||||
(eshell-for pred eshell-complex-commands
|
||||
(if (and (functionp pred)
|
||||
(funcall pred name))
|
||||
(throw 'simple nil)))
|
||||
t))
|
||||
(fboundp (intern-soft (concat "eshell/" name))))))
|
||||
|
||||
(defun eshell-eval-command (command &optional input)
|
||||
"Evaluate the given COMMAND iteratively."
|
||||
(if eshell-current-command
|
||||
|
@ -1163,29 +1181,29 @@ be finished later after the completion of an asynchronous subprocess."
|
|||
((eq (car form) 'prog1)
|
||||
(cadr form))
|
||||
(t
|
||||
;; If a command desire to replace its execution form with
|
||||
;; another command form, all it needs to do is throw the new
|
||||
;; form using the exception tag `eshell-replace-command'.
|
||||
;; For example, let's say that the form currently being
|
||||
;; eval'd is:
|
||||
;;
|
||||
;; (eshell-named-command "hello")
|
||||
;;
|
||||
;; Now, let's assume the 'hello' command is an Eshell alias,
|
||||
;; the definition of which yields the command:
|
||||
;;
|
||||
;; (eshell-named-command "echo" (list "Hello" "world"))
|
||||
;;
|
||||
;; What the alias code would like to do is simply substitute
|
||||
;; the alias form for the original form. To accomplish
|
||||
;; this, all it needs to do is to throw the substitution
|
||||
;; form with the `eshell-replace-command' tag, and the form
|
||||
;; will be replaced within the current command, and
|
||||
;; execution will then resume (iteratively) as before.
|
||||
;; Thus, aliases can even contain references to asynchronous
|
||||
;; sub-commands, and things will still work out as they
|
||||
;; should.
|
||||
(let (result new-form)
|
||||
;; If a command desire to replace its execution form with
|
||||
;; another command form, all it needs to do is throw the
|
||||
;; new form using the exception tag
|
||||
;; `eshell-replace-command'. For example, let's say that
|
||||
;; the form currently being eval'd is:
|
||||
;;
|
||||
;; (eshell-named-command \"hello\")
|
||||
;;
|
||||
;; Now, let's assume the 'hello' command is an Eshell
|
||||
;; alias, the definition of which yields the command:
|
||||
;;
|
||||
;; (eshell-named-command \"echo\" (list \"Hello\" \"world\"))
|
||||
;;
|
||||
;; What the alias code would like to do is simply
|
||||
;; substitute the alias form for the original form. To
|
||||
;; accomplish this, all it needs to do is to throw the
|
||||
;; substitution form with the `eshell-replace-command'
|
||||
;; tag, and the form will be replaced within the current
|
||||
;; command, and execution will then resume (iteratively)
|
||||
;; as before. Thus, aliases can even contain references
|
||||
;; to asynchronous sub-commands, and things will still
|
||||
;; work out as they should.
|
||||
(if (setq new-form
|
||||
(catch 'eshell-replace-command
|
||||
(ignore
|
||||
|
|
|
@ -132,4 +132,3 @@ functions, or as aliases which make some of Emacs' behavior more
|
|||
naturally accessible within Emacs."
|
||||
:tag "Extra alias functions"
|
||||
:group 'eshell-module)
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
;; (interactive)
|
||||
;; (require 'autoload)
|
||||
;; (setq generated-autoload-file
|
||||
;; (expand-file-name (car command-line-args-left)))
|
||||
;; (expand-file-name (car command-line-args-left)))
|
||||
;; (setq command-line-args-left (cdr command-line-args-left))
|
||||
;; (batch-update-autoloads))
|
||||
|
||||
|
@ -65,23 +65,23 @@
|
|||
;; Core Functionality\n")
|
||||
;; (eshell-for module
|
||||
;; (sort (eshell-subgroups 'eshell)
|
||||
;; (function
|
||||
;; (lambda (a b)
|
||||
;; (string-lessp (symbol-name a)
|
||||
;; (symbol-name b)))))
|
||||
;; (function
|
||||
;; (lambda (a b)
|
||||
;; (string-lessp (symbol-name a)
|
||||
;; (symbol-name b)))))
|
||||
;; (insert (format "* %-34s"
|
||||
;; (concat (get module 'custom-tag) "::"))
|
||||
;; (symbol-name module) ".\n"))
|
||||
;; (concat (get module 'custom-tag) "::"))
|
||||
;; (symbol-name module) ".\n"))
|
||||
;; (insert "\nOptional Functionality\n")
|
||||
;; (eshell-for module
|
||||
;; (sort (eshell-subgroups 'eshell-module)
|
||||
;; (function
|
||||
;; (lambda (a b)
|
||||
;; (string-lessp (symbol-name a)
|
||||
;; (symbol-name b)))))
|
||||
;; (function
|
||||
;; (lambda (a b)
|
||||
;; (string-lessp (symbol-name a)
|
||||
;; (symbol-name b)))))
|
||||
;; (insert (format "* %-34s"
|
||||
;; (concat (get module 'custom-tag) "::"))
|
||||
;; (symbol-name module) ".\n"))
|
||||
;; (concat (get module 'custom-tag) "::"))
|
||||
;; (symbol-name module) ".\n"))
|
||||
;; (insert "@end menu\n"))
|
||||
|
||||
;; (defun eshell-make-texi ()
|
||||
|
@ -91,27 +91,27 @@
|
|||
;; (require 'texidoc)
|
||||
;; (require 'pcomplete)
|
||||
;; (apply 'texidoc-files 'eshell-generate-main-menu "eshell.doci"
|
||||
;; (append
|
||||
;; (list "eshell.el")
|
||||
;; (sort (mapcar
|
||||
;; (function
|
||||
;; (lambda (sym)
|
||||
;; (let ((name (symbol-name sym)))
|
||||
;; (if (string-match "\\`eshell-\\(.*\\)" name)
|
||||
;; (setq name (concat "esh-" (match-string 1 name))))
|
||||
;; (concat name ".el"))))
|
||||
;; (eshell-subgroups 'eshell))
|
||||
;; 'string-lessp)
|
||||
;; (sort (mapcar
|
||||
;; (function
|
||||
;; (lambda (sym)
|
||||
;; (let ((name (symbol-name sym)))
|
||||
;; (if (string-match "\\`eshell-\\(.*\\)" name)
|
||||
;; (setq name (concat "em-" (match-string 1 name))))
|
||||
;; (concat name ".el"))))
|
||||
;; (eshell-subgroups 'eshell-module))
|
||||
;; 'string-lessp)
|
||||
;; (list "eshell.texi"))))
|
||||
;; (append
|
||||
;; (list "eshell.el")
|
||||
;; (sort (mapcar
|
||||
;; (function
|
||||
;; (lambda (sym)
|
||||
;; (let ((name (symbol-name sym)))
|
||||
;; (if (string-match "\\`eshell-\\(.*\\)" name)
|
||||
;; (setq name (concat "esh-" (match-string 1 name))))
|
||||
;; (concat name ".el"))))
|
||||
;; (eshell-subgroups 'eshell))
|
||||
;; 'string-lessp)
|
||||
;; (sort (mapcar
|
||||
;; (function
|
||||
;; (lambda (sym)
|
||||
;; (let ((name (symbol-name sym)))
|
||||
;; (if (string-match "\\`eshell-\\(.*\\)" name)
|
||||
;; (setq name (concat "em-" (match-string 1 name))))
|
||||
;; (concat name ".el"))))
|
||||
;; (eshell-subgroups 'eshell-module))
|
||||
;; 'string-lessp)
|
||||
;; (list "eshell.texi"))))
|
||||
|
||||
;; (defun eshell-make-readme ()
|
||||
;; "Make the README file from eshell.el."
|
||||
|
|
|
@ -180,9 +180,7 @@ inserted. They return the string as it should be inserted."
|
|||
:group 'eshell-mode)
|
||||
|
||||
(defcustom eshell-password-prompt-regexp
|
||||
"\\(\\([Oo]ld \\|[Nn]ew \\|Kerberos \\|CVS \\|'s \\|login \\|^\\)\
|
||||
[Pp]assword\\|pass phrase\\|\\(Enter\\|Repeat\\) passphrase\\)\
|
||||
\\( for [^@ \t\n]+@[^@ \t\n]+\\)?:\\s *\\'"
|
||||
"[Pp]ass\\(word\\|phrase\\).*:\\s *\\'"
|
||||
"*Regexp matching prompts for passwords in the inferior process.
|
||||
This is used by `eshell-watch-for-password-prompt'."
|
||||
:type 'regexp
|
||||
|
@ -462,7 +460,8 @@ sessions, such as when using `eshell-command'.")
|
|||
|
||||
(eshell-deftest var window-height
|
||||
"LINES equals window height"
|
||||
(eshell-command-result-p "= $LINES (window-height)" "t\n"))
|
||||
(let ((eshell-stringify-t t))
|
||||
(eshell-command-result-p "= $LINES (window-height)" "t\n")))
|
||||
|
||||
(defun eshell-command-started ()
|
||||
"Indicate in the modeline that a command has started."
|
||||
|
@ -736,7 +735,9 @@ newline."
|
|||
(run-hooks 'eshell-input-filter-functions)
|
||||
(and (catch 'eshell-terminal
|
||||
(ignore
|
||||
(eshell-eval-command cmd input)))
|
||||
(if (eshell-invoke-directly cmd input)
|
||||
(eval cmd)
|
||||
(eshell-eval-command cmd input))))
|
||||
(eshell-life-is-too-much)))))
|
||||
(quit
|
||||
(eshell-reset t)
|
||||
|
|
|
@ -24,7 +24,9 @@
|
|||
|
||||
(provide 'esh-module)
|
||||
|
||||
(eval-when-compile (require 'esh-maint) (require 'cl))
|
||||
(eval-when-compile
|
||||
(require 'esh-maint)
|
||||
(require 'cl))
|
||||
|
||||
(defgroup eshell-module nil
|
||||
"The `eshell-module' group is for Eshell extension modules, which
|
||||
|
@ -85,7 +87,7 @@ customizing the variable `eshell-modules-list'."
|
|||
(equal (file-name-nondirectory byte-compile-current-file)
|
||||
"esh-modu.el"))))
|
||||
(let* ((directory (file-name-directory byte-compile-current-file))
|
||||
(elc-file (expand-file-name "esh-groups.elc" directory)))
|
||||
(elc-file (expand-file-name "esh-groups.elc" directory)))
|
||||
(eshell-load-defgroups directory)
|
||||
(if (file-exists-p elc-file) (delete-file elc-file)))))
|
||||
|
||||
|
|
|
@ -173,12 +173,12 @@
|
|||
system-configuration
|
||||
(cond ((featurep 'motif) ", Motif")
|
||||
((featurep 'x-toolkit) ", X toolkit")
|
||||
(t ""))) "\n")
|
||||
(t ""))))
|
||||
(switch-to-buffer test-buffer)
|
||||
(delete-other-windows))
|
||||
(eshell-for funcname
|
||||
(sort (all-completions "eshell-test--" obarray 'functionp)
|
||||
'string-lessp)
|
||||
(eshell-for funcname (sort (all-completions "eshell-test--"
|
||||
obarray 'functionp)
|
||||
'string-lessp)
|
||||
(with-current-buffer test-buffer
|
||||
(insert "\n"))
|
||||
(funcall (intern-soft funcname)))
|
||||
|
|
|
@ -36,6 +36,14 @@
|
|||
|
||||
;;; User Variables:
|
||||
|
||||
(defcustom eshell-stringify-t t
|
||||
"*If non-nil, the string representation of t is 't'.
|
||||
If nil, t will be represented only in the exit code of the function,
|
||||
and not printed as a string. This causes Lisp functions to behave
|
||||
similarly to external commands, as far as successful result output."
|
||||
:type 'boolean
|
||||
:group 'eshell-util)
|
||||
|
||||
(defcustom eshell-group-file "/etc/group"
|
||||
"*If non-nil, the name of the group file on your system."
|
||||
: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."
|
|||
((numberp object)
|
||||
(number-to-string object))
|
||||
(t
|
||||
(pp-to-string object))))
|
||||
(unless (and (eq object t)
|
||||
(not eshell-stringify-t))
|
||||
(pp-to-string object)))))
|
||||
|
||||
(defsubst eshell-stringify-list (args)
|
||||
"Convert each element of ARGS into a string value."
|
||||
|
@ -611,7 +621,7 @@ Unless optional argument INPLACE is non-nil, return a new string."
|
|||
(autoload 'parse-time-string "parse-time"))
|
||||
|
||||
(eval-when-compile
|
||||
(require 'ange-ftp))
|
||||
(load "ange-ftp" t))
|
||||
|
||||
(defun eshell-parse-ange-ls (dir)
|
||||
(let (entry)
|
||||
|
|
|
@ -1986,7 +1986,7 @@ The word checked is the word at the mouse position."
|
|||
menu))))
|
||||
|
||||
;*---------------------------------------------------------------------*/
|
||||
;* Some example functions for real autocrrecting */
|
||||
;* Some example functions for real autocrrecting xb */
|
||||
;*---------------------------------------------------------------------*/
|
||||
(defun flyspell-maybe-correct-transposition (beg end poss)
|
||||
"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
|
|||
in POSS. Otherwise the change is undone.
|
||||
|
||||
This function is meant to be added to 'flyspell-incorrect-hook'."
|
||||
(when (consp poss)
|
||||
(when (consp poss)
|
||||
(catch 'done
|
||||
(save-excursion
|
||||
(goto-char (1+ beg))
|
||||
(while (< (point) end)
|
||||
(transpose-chars 1)
|
||||
(when (member (buffer-substring beg end) (nth 2 poss))
|
||||
(throw 'done t))
|
||||
(transpose-chars -1)
|
||||
(forward-char))
|
||||
nil))))
|
||||
(let ((str (buffer-substring beg end))
|
||||
(i 0) (len (- end beg)) tmp)
|
||||
(while (< (1+ i) len)
|
||||
(setq tmp (aref str i))
|
||||
(aset str i (aref str (1+ i)))
|
||||
(aset str (1+ i) tmp)
|
||||
(when (member str (nth 2 poss))
|
||||
(save-excursion
|
||||
(goto-char (+ beg i 1))
|
||||
(transpose-chars 1))
|
||||
(throw 'done t))
|
||||
(setq tmp (aref str i))
|
||||
(aset str i (aref str (1+ i)))
|
||||
(aset str (1+ i) tmp)
|
||||
(setq i (1+ i))))
|
||||
nil)))
|
||||
|
||||
(defun flyspell-maybe-correct-doubling (beg end poss)
|
||||
"For each doubled charachter in the region BEG to END, remove one and
|
||||
|
@ -2014,21 +2021,18 @@ in POSS. Otherwise the change is undone.
|
|||
This function is meant to be added to 'flyspell-incorrect-hook'."
|
||||
(when (consp poss)
|
||||
(catch 'done
|
||||
(save-excursion
|
||||
(let ((last (char-after beg))
|
||||
this)
|
||||
(goto-char (1+ beg))
|
||||
(while (< (point) end)
|
||||
(setq this (char-after))
|
||||
(if (not (char-equal this last))
|
||||
(forward-char)
|
||||
(delete-char 1)
|
||||
(when (member (buffer-substring beg (1- end)) (nth 2 poss))
|
||||
(throw 'done t))
|
||||
;; undo
|
||||
(insert-char this 1))
|
||||
(setq last this))
|
||||
nil)))))
|
||||
(let ((str (buffer-substring beg end))
|
||||
(i 0) (len (- end beg)))
|
||||
(while (< (1+ i) len)
|
||||
(when (and (= (aref str i) (aref str (1+ i)))
|
||||
(member (concat (substring str 0 (1+ i))
|
||||
(substring str (+ i 2)))
|
||||
(nth 2 poss)))
|
||||
(goto-char (+ beg i))
|
||||
(delete-char 1)
|
||||
(throw 'done t))
|
||||
(setq i (1+ i))))
|
||||
nil)))
|
||||
|
||||
;*---------------------------------------------------------------------*/
|
||||
;* flyspell-already-abbrevp ... */
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2000-10-28 John Wiegley <johnw@gnu.org>
|
||||
|
||||
* eshell.texi: Further editing, and finished the "bugs" section.
|
||||
|
||||
2000-10-28 Eli Zaretskii <eliz@is.elta.co.il>
|
||||
|
||||
* cmdargs.texi (Colors X): Document support for -fg, -bg, and -rv
|
||||
|
|
821
man/eshell.texi
821
man/eshell.texi
|
@ -1,6 +1,6 @@
|
|||
\input texinfo @c -*-texinfo-*-
|
||||
|
||||
@c "@(#)$Name: $:$Id: eshell.texi,v 1.2 2000/10/13 10:32:23 johnw Exp $"
|
||||
@c "@(#)$Name: $:$Id: eshell.texi,v 1.3 2000/10/16 18:24:30 eliz Exp $"
|
||||
|
||||
@c Documentation for Eshell: The Emacs Shell.
|
||||
@c Copyright (C) 1999-2000 Free Software Foundation, Inc.
|
||||
|
@ -28,7 +28,7 @@
|
|||
|
||||
@dircategory Emacs
|
||||
@direntry
|
||||
* Eshell: (eshell). A command shell implemented in Emacs Lisp.
|
||||
* Eshell: (eshell). A command shell implemented in Emacs Lisp.
|
||||
@end direntry
|
||||
@setchapternewpage on
|
||||
|
||||
|
@ -72,7 +72,7 @@ Software Foundation instead of in the original English.
|
|||
@center @titlefont{Eshell: The Emacs Shell}
|
||||
@ignore
|
||||
@sp 2
|
||||
@center release 2.3.2
|
||||
@center release 2.4
|
||||
@c -release-
|
||||
@end ignore
|
||||
@sp 3
|
||||
|
@ -114,18 +114,19 @@ Software Foundation instead of in the original English.
|
|||
@top Eshell
|
||||
|
||||
This manual documents Eshell, a shell-like command interpretor
|
||||
implemented entirely in Emacs Lisp. It invokes no external processes
|
||||
beyond those requested by the user. It is intended to be a functional
|
||||
implemented in Emacs Lisp. It invokes no external processes except for
|
||||
those requested by the user. It is intended to be a functional
|
||||
replacement for command shells such as @command{bash}, @command{zsh},
|
||||
@command{rc}, @command{4dos}; since Emacs itself is capable of handling
|
||||
most of the tasks accomplished by such tools.
|
||||
@c This manual is updated to release 2.3.2 of Eshell.
|
||||
@command{rc}, or @command{4dos}; since Emacs itself is capable of
|
||||
handling the sort of tasks accomplished by those tools.
|
||||
@c This manual is updated to release 2.4 of Eshell.
|
||||
@end ifinfo
|
||||
|
||||
@menu
|
||||
* What is Eshell?:: A brief introduction to the Emacs Shell.
|
||||
* Installation::
|
||||
* Bugs and ideas::
|
||||
* What is Eshell?:: A brief introduction to the Emacs Shell.
|
||||
* Installation:: For users of Emacs 20 and XEmacs.
|
||||
* Command basics:: The basics of command usage.
|
||||
* Bugs and ideas:: Known problems, and future ideas.
|
||||
* Concept Index::
|
||||
* Function and Variable Index::
|
||||
* Key Index::
|
||||
|
@ -136,12 +137,12 @@ most of the tasks accomplished by such tools.
|
|||
@cindex what is Eshell?
|
||||
@cindex Eshell, what it is
|
||||
|
||||
Eshell is a @dfn{command shell} written using Emacs Lisp. All of what it does
|
||||
it uses Emacs' facilities to do. This means Eshell is as portable as
|
||||
Emacs itself. It also means that cooperation with other Lisp code is
|
||||
natural and seamless.
|
||||
Eshell is a @dfn{command shell} written in Emacs Lisp. Everything it
|
||||
does it uses Emacs' facilities to do. This means that Eshell is as
|
||||
portable as Emacs itself. It also means that cooperation with Lisp code
|
||||
is natural and seamless.
|
||||
|
||||
So what is a command shell? To properly understand the role of a shell,
|
||||
What is a command shell? To properly understand the role of a shell,
|
||||
it's necessary to visualize what a computer does for you. Basically, a
|
||||
computer is a tool; in order to use that tool, you must tell it what to
|
||||
do---or give it ``commands''. These commands take many forms, such as
|
||||
|
@ -149,22 +150,22 @@ clicking with a mouse on certain parts of the screen. But that is only
|
|||
one form of command input.
|
||||
|
||||
By far the most versatile way to express what you want the computer to
|
||||
do is using an abbreviated language, called @dfn{a script}. In a
|
||||
script, instead
|
||||
of telling the computer, ``list my files, please'', we write just
|
||||
``list''. In fact, this command is so commonly used that we abbreviate
|
||||
it to ``ls''. Typing @kbd{ls} in a command shell is a script way of
|
||||
telling the computer to list your files. This is comparable to viewing
|
||||
the contents of a folder using a graphical display.
|
||||
do is by using an abbreviated language called @dfn{script}. In script,
|
||||
instead of telling the computer, ``list my files, please'', one writes
|
||||
just ``list''. In fact, this command is so commonly used that it is
|
||||
abbreviated to ``ls''. Typing @kbd{ls} in a command shell is a script
|
||||
way of telling the computer to list your files.@footnote{This is
|
||||
comparable to viewing the contents of a folder using a graphical
|
||||
display.}
|
||||
|
||||
The real flexibility is apparent only when you realize that there are
|
||||
many, many ways to list your files. Perhaps you want them sorted by
|
||||
name, or sorted by date, or in reverse order, or grouped by type. Most
|
||||
graphical browsers have simple ways to express this. But what about
|
||||
showing only a few files, or only files that meet a certain criteria?
|
||||
In very complex and specific situations, the request becomes too
|
||||
difficult to express with a mouse. It is just these kinds of requests
|
||||
that are solvable using a command shell.
|
||||
The real flexibility of this approach is apparent only when you realize
|
||||
that there are many, many different ways to list files. Perhaps you
|
||||
want them sorted by name, sorted by date, in reverse order, or grouped
|
||||
by type. Most graphical browsers have simple ways to express this. But
|
||||
what about showing only a few files, or only files that meet a certain
|
||||
criteria? In very complex and specific situations, the request becomes
|
||||
too difficult to express using a mouse or pointing device. It is just
|
||||
these kinds of requests that are easily solved using a command shell.
|
||||
|
||||
For example, what if you want to list every Word file on your hard
|
||||
drive, larger than 100 kilobytes in size, and which hasn't been looked
|
||||
|
@ -173,13 +174,13 @@ you go to clean up your hard drive. But have you ever tried asking your
|
|||
computer for such a list? There is no way to do it! At least, not
|
||||
without using a command shell.
|
||||
|
||||
So the role of a command shell is to give you more control over what
|
||||
your computer does for you. Not everyone needs this amount of control,
|
||||
and it does come at a cost: Learning the necessary script commands to
|
||||
The role of a command shell is to give you more control over what your
|
||||
computer does for you. Not everyone needs this amount of control, and
|
||||
it does come at a cost: Learning the necessary script commands to
|
||||
express what you want done. A complicated query, such as the example
|
||||
above, takes time to learn. But if you find yourself using your
|
||||
computer frequently enough, it is more than worthwhile in the long run.
|
||||
Any tool you use often deserves your time in learning to master it.
|
||||
Any tool you use often deserves the time spent learning to master it.
|
||||
@footnote{For the understandably curious, here is what that command
|
||||
looks like: But don't let it fool you; once you know what's going on,
|
||||
it's easier than it looks: @code{ls -lt **/*.doc(Lk+50aM+5)}.}
|
||||
|
@ -187,10 +188,10 @@ it's easier than it looks: @code{ls -lt **/*.doc(Lk+50aM+5)}.}
|
|||
As of Emacs 21, Eshell is part of the standard Emacs distribution.
|
||||
|
||||
@menu
|
||||
* Contributors to Eshell::
|
||||
* Contributors to Eshell:: People who have helped out!
|
||||
@end menu
|
||||
|
||||
@node Contributors to Eshell, , What is Eshell?, What is Eshell?
|
||||
@node Contributors to Eshell, , What is Eshell?, What is Eshell?
|
||||
@section Contributors to Eshell
|
||||
@cindex contributors
|
||||
@cindex authors
|
||||
|
@ -230,16 +231,16 @@ Apart from these, a lot of people have sent suggestions, ideas,
|
|||
requests, bug reports and encouragement. Thanks a lot! Without you
|
||||
there would be no new releases of Eshell.
|
||||
|
||||
@node Installation, Bugs and ideas, What is Eshell?, Top
|
||||
@node Installation, Command basics, What is Eshell?, Top
|
||||
@chapter Installation
|
||||
@cindex installation
|
||||
|
||||
As mentioned above, Eshell comes preinstalled since Emacs 21. If you're
|
||||
As mentioned above, Eshell comes preinstalled as of Emacs 21. If you're
|
||||
using Emacs 20.4 or later, or XEmacs 21, you can download the most
|
||||
recent version of Eshell from
|
||||
@url{http://www.gci-net.com/users/j/johnw/Emacs/eshell.tar.gz}.
|
||||
|
||||
If you are using Emacs 21, please skip this section.
|
||||
However, if you are using Emacs 21, you may skip this section.
|
||||
|
||||
@section Short Form
|
||||
|
||||
|
@ -420,57 +421,70 @@ you can use. For other printers, use a suitable DVI driver,
|
|||
e.g., @code{dvilj4} for LaserJet-compatible printers.
|
||||
@end enumerate
|
||||
|
||||
@c @node Forming commands, Known problems, What is Eshell?, Top
|
||||
@c @chapter Forming commands
|
||||
@node Command basics, Bugs and ideas, Installation, Top
|
||||
@chapter Command basics
|
||||
|
||||
@c A command shell is nothing more than a place to enter commands.
|
||||
A command shell is a mechanism for entering verbally-formed commands.
|
||||
This is really all that it does, and every feature described in this
|
||||
manual is a means to that end. Therefore, it's important to get a firm
|
||||
grasp on exactly what a command is, and how it fits into the overall
|
||||
picture of things.
|
||||
|
||||
@c What is a command?
|
||||
@menu
|
||||
* Commands verbs:: Commands always begin with a verb.
|
||||
* Command arguments:: Some verbs require arguments.
|
||||
@end menu
|
||||
|
||||
@c A command is piece of ``script''---or special shorthand
|
||||
@c language---that the computer can understand.
|
||||
@node Commands verbs, Command arguments, Command basics, Command basics
|
||||
@section Commands verbs
|
||||
|
||||
@c What does script look like?
|
||||
Commands are expressed using @dfn{script}, a special shorthand language
|
||||
that computers can understand without trouble.
|
||||
|
||||
@c Script is an extremely simplified language. Oddly enough, this
|
||||
@c actually makes it look more complicated than it is. Whereas normal
|
||||
@c languages can use many different embellishments, the form of a script
|
||||
@c command is always: a command verb, following by its arguments.
|
||||
Script is an extremely simplified language. Oddly enough, this actually
|
||||
makes it look more complicated than it is. Whereas normal languages use
|
||||
a variety of embellishments, the form of a script command is always:
|
||||
|
||||
@c A verb? Arguments?
|
||||
@example
|
||||
VERB [ARGUMENTS]
|
||||
@end example
|
||||
|
||||
@c The verb is the thing you want your computer to do. There are a set
|
||||
@c number of verbs, although this number is quite large. On my
|
||||
@c computer, it reaches almost 1400 in number! But of course, only a
|
||||
@c handful of these are necessary most of the time.
|
||||
The verb expresses what you want your computer to do. There are a fixed
|
||||
number of verbs, although this number is usually quite large. On the
|
||||
author's computer, it reaches almost 1400 in number. But of course,
|
||||
only a handful of these are really necessary.
|
||||
|
||||
@c Sometimes, the verb is all that's necessary. A verb is always a
|
||||
@c single word, usually related to the task it will perform.
|
||||
@c @command{reboot} is a good example. Entering that will cause your
|
||||
@c computer to reboot, assuming you have sufficient privileges.
|
||||
Sometimes, the verb is all that's written. A verb is always a single
|
||||
word, usually related to the task it will perform. @command{reboot} is
|
||||
a good example. Entering that will cause your computer to reboot,
|
||||
assuming you have sufficient privileges.
|
||||
|
||||
@c Other verbs need more information. These are usually very capable of
|
||||
@c verbs, but they must be told more specifically what to do. This
|
||||
@c extra information is given in the form of arguments. Arguments are
|
||||
@c also words, that appear after the verb. For example, @command{echo}
|
||||
@c is a command verb that will print back to you whatever you say.
|
||||
@c @command{echo} requires a set of arguments, to know what you want it
|
||||
@c to echo! So a proper use of echo might look like:
|
||||
Other verbs require more information. These are usually very capable of
|
||||
verbs, and must be told more specifically what to do. This extra
|
||||
information is given in the form of arguments. Arguments are also
|
||||
single words, that appear after the verb. For example, @command{echo}
|
||||
is a command verb that prints back whatever you say. @command{echo}
|
||||
requires arguments, so that it knows what to echo. A proper use of
|
||||
@command{echo} looks like this:
|
||||
|
||||
@c @example
|
||||
@c echo This is an example of using echo!
|
||||
@c @end example
|
||||
@example
|
||||
echo This is an example of using echo!
|
||||
@end example
|
||||
|
||||
@c This command would result in the computer printing back to you,
|
||||
@c ``This is an example of using echo!''. Pretty easy, no?
|
||||
This piece of script expresses a command that causes the computer to
|
||||
print back: ``This is an example of using echo!''.
|
||||
|
||||
@c Although commands are always simple words, arguments can take
|
||||
@c different forms. There are textual arguments, numeric arguments,
|
||||
@c even Lisp arguments. Distinguishing among these different types of
|
||||
@c arguments requires some special typing, because the computer needs
|
||||
@c very specific directions to understand what you mean.
|
||||
Although command verbs always take the form of simple words, such as
|
||||
@command{reboot} and @command{echo}, arguments have a wide vaierty of
|
||||
forms. There are textual arguments, numerical arguments---even Lisp
|
||||
arguments. Distinguishing between these different types of arguments
|
||||
requires special typing, since the computer needs to know exactly what
|
||||
you mean.
|
||||
|
||||
@node Bugs and ideas, Concept Index, Installation, Top
|
||||
@node Command arguments, , Commands verbs, Command basics
|
||||
@section Command arguments
|
||||
|
||||
@node Bugs and ideas, Concept Index, Command basics, Top
|
||||
@chapter Bugs and ideas
|
||||
@cindex reporting bugs and ideas
|
||||
@cindex bugs, how to report them
|
||||
|
@ -498,10 +512,19 @@ find this package useful!
|
|||
@cindex bugs, known
|
||||
|
||||
Below is a partial list of currently known problems with Eshell version
|
||||
2.3.2, which is the version distributed with Emacs 21.1.
|
||||
2.4, which is the version distributed with Emacs 21.1.
|
||||
|
||||
@table @asis
|
||||
@item @samp{for i in 1 2 3 @{ grep -q a b && *echo has it @} | wc -l} fails
|
||||
@item Differentiate between aliases and functions
|
||||
|
||||
Allow for a bash-compatible syntax, such as:
|
||||
|
||||
@example
|
||||
alias arg=blah
|
||||
function arg () { blah $* }
|
||||
@end example
|
||||
|
||||
@item @samp{for i in 1 2 3 @{ grep -q a b && *echo has it @} | wc -l} outputs result after prompt
|
||||
|
||||
In fact, piping to a process from a looping construct doesn't work in
|
||||
general. If I change the call to @code{eshell-copy-handles} in
|
||||
|
@ -514,11 +537,6 @@ structured command thing is too complicated at present.
|
|||
On some XEmacs system, the subprocess interaction test fails
|
||||
inexplicably, although @command{bc} works fine at the command prompt.
|
||||
|
||||
@item @command{ls} in remote directories sometimes fails
|
||||
|
||||
For XEmacs users, using @command{ls} in a remote directory sometimes
|
||||
fails. The reason why has not yet been found.
|
||||
|
||||
@item Eshell does not delete @file{*Help*} buffers in XEmacs 21.1.8+
|
||||
|
||||
In XEmacs 21.1.8, the @file{*Help*} buffer has been renamed such that
|
||||
|
@ -563,266 +581,385 @@ since.
|
|||
|
||||
Make it so that the Lisp command on the right of the pipe is repeatedly
|
||||
called with the input strings as arguments. This will require changing
|
||||
eshell-do-pipeline to handle non-process targets.
|
||||
@code{eshell-do-pipeline} to handle non-process targets.
|
||||
|
||||
@item Input redirection is not supported
|
||||
|
||||
See the entry above.
|
||||
See the above entry.
|
||||
|
||||
@item Problem running @command{less} without argument on Windows
|
||||
|
||||
The result in the Eshell buffer is:
|
||||
|
||||
@example
|
||||
Spawning child process: invalid argument
|
||||
@end example
|
||||
|
||||
Also a new @command{less} buffer was created with nothing in it@dots{}
|
||||
(presumably this holds the output of @command{less}).
|
||||
|
||||
If @command{less.exe} is invoked from the Eshell command line, the
|
||||
expected output is written to the buffer.
|
||||
|
||||
Note that this happens on NT-Emacs 20.6.1 on Win2000. The term.el
|
||||
package and the supplied shell both use the @command{cmdproxy} for
|
||||
running shells.
|
||||
|
||||
@item Implement @samp{-r}, @samp{-n} and @samp{-s} switches for @command{cp}
|
||||
|
||||
@item Make @kbd{M-5 M-x eshell} switch to ``*eshell<5>*'', creating if need be
|
||||
|
||||
@item @samp{mv DIR FILE.tar} does not remove directories
|
||||
|
||||
This is because the tar option --remove-files doesn't do so. Should it
|
||||
be Eshell's job?
|
||||
|
||||
@item Bind @code{standard-output} and @code{standard-error}
|
||||
|
||||
This would be so that if a Lisp function calls @code{print}, everything
|
||||
will happen as it should (albeit slowly).
|
||||
|
||||
@item When an extension module fails to load, @samp{cd /} gives a Lisp error
|
||||
|
||||
@item If a globbing pattern returns one match, should it be a list?
|
||||
|
||||
@item Make sure syntax table is correct in Eshell mode
|
||||
|
||||
So that @kbd{M-DEL} acts in a predictable manner, etc.
|
||||
|
||||
@item Allow all Eshell buffers to share the same history and list-dir
|
||||
|
||||
@item There is a problem with script commands that output to @file{/dev/null}
|
||||
|
||||
If a script file, somewhere in the middle, uses @samp{> /dev/null},
|
||||
output from all subsequent commands is swallowed.
|
||||
|
||||
@item Split up parsing of text after @samp{$} in @file{esh-var.el}
|
||||
|
||||
Make it similar to the way that @file{esh-arg.el} is structured.
|
||||
Then add parsing of @samp{$[?\n]}.
|
||||
|
||||
@item After pressing @kbd{M-RET}, redisplay before running the next command
|
||||
|
||||
@item Argument predicates and modifiers should work anywhere in a path
|
||||
|
||||
@example
|
||||
/usr/local/src/editors/vim $ vi **/CVS(/)/Root(.)
|
||||
Invalid regexp: "Unmatched ( or \\("
|
||||
@end example
|
||||
|
||||
With @command{zsh}, the glob above expands to all files named
|
||||
@file{Root} in directories named @file{CVS}.
|
||||
|
||||
@item Typing @samp{echo ${locate locate}/bin<TAB>} results in a Lisp error
|
||||
|
||||
Perhaps it should interpolate all permutations, and make that the
|
||||
globbing result, since otherwise hitting return here will result in
|
||||
``(list of filenames)/bin'', which is never valuable. Thus, one could
|
||||
@command{cat} only C backup files by using @samp{ls ${identity *.c}~}.
|
||||
In that case, having an alias command name @command{glob} for
|
||||
@command{identity} would be useful.
|
||||
|
||||
@item Fix `file-name-all-completions' for XEmacs on Win32
|
||||
|
||||
Make sure it returns directory names terminated by
|
||||
@code{directory-sep-char} (which is initialized to be @samp{?/}), rather
|
||||
than backslash.
|
||||
|
||||
@item Once symbolic mode is supported for @command{umask}, implement @command{chmod} in Lisp
|
||||
|
||||
@item Create @code{eshell-expand-file-name}
|
||||
|
||||
This would use a data table to transform things such as @samp{~+},
|
||||
@samp{...}, etc.
|
||||
|
||||
@item Abstract @file{em-smart.el} into @file{smart-scroll.el}
|
||||
|
||||
It only really needs: to be hooked onto the output filter and the
|
||||
pre-command hook, and to have the input-end and input-start markers.
|
||||
And to know whether the last output group was ``successful''.
|
||||
|
||||
@item Allow for fully persisting the state of Eshell
|
||||
|
||||
This would include: variables, history, buffer, input, dir stack, etc.
|
||||
|
||||
@item Implement D as an argument predicate
|
||||
|
||||
It means that files beginning with a dot should be included in the
|
||||
glob match.
|
||||
|
||||
@item A comma in a predicate list should mean OR
|
||||
|
||||
At the moment, this is not supported.
|
||||
|
||||
@item Error if a glob doesn't expand due to a predicate
|
||||
|
||||
An error should be generated only if @code{eshell-error-if-no-glob} is
|
||||
non-nil.
|
||||
|
||||
@item @samp{(+ RET SPC TAB} does not cause @code{indent-according-to-mode} to occur
|
||||
|
||||
@item Create @code{eshell-auto-accumulate-list}
|
||||
|
||||
This is a list of commands for which, if the user presses @kbd{RET}, the
|
||||
text is staged as the next Eshell command, rather than being sent to the
|
||||
current interactive process.
|
||||
|
||||
@item Display file and line number if an error occurs in a script
|
||||
|
||||
@item @command{wait} doesn't work with process ids at the moment
|
||||
|
||||
@item Enable the direct-to-process input code in @file{em-term.el}
|
||||
|
||||
@item Problem with repeating @samp{echo $@{find /tmp@}}
|
||||
|
||||
With smart display active, if @kbd{RET} is held down, after a while it
|
||||
can't keep up anymore and starts outputting blank lines. It only
|
||||
happens if an asynchronous process is involved@dots{}
|
||||
|
||||
I think the problem is that @code{eshell-send-input} is resetting the
|
||||
input target location, so that if the asynchronous process is not done
|
||||
by the time the next @kbd{RET} is received, the input processor thinks
|
||||
that the input is meant for the process; which, when smart display is
|
||||
enabled, will be the text of the last command line! That is a bug in
|
||||
itself.
|
||||
|
||||
In holding down @kbd{RET} while an asynchronous process is running,
|
||||
there will be a point in between termination of the process, and the
|
||||
running of @code{eshell-post-command-hook}, which would cause
|
||||
@code{eshell-send-input} to call @code{eshell-copy-old-input}, and then
|
||||
process that text as a command to be run after the process. Perhaps
|
||||
there should be a way of killing pending input between the death of the
|
||||
process, and the @code{post-command-hook}.
|
||||
|
||||
@item Allow for a more aggressive smart display mode
|
||||
|
||||
Perhaps toggled by a command, that makes each output block a smart
|
||||
display block.
|
||||
|
||||
@item Create more meta variables
|
||||
|
||||
@table @samp
|
||||
@item $!
|
||||
The reason for the failure of the last disk command, or the text of the
|
||||
last Lisp error.
|
||||
|
||||
@item $=
|
||||
A special associate array, which can take references of the form
|
||||
@samp{$=[REGEXP]}. It indexes into the directory ring.
|
||||
@end table
|
||||
|
||||
@item Eshell scripts can't execute in the background
|
||||
|
||||
@item Support zsh's ``Parameter Expansion'' syntax, i.e. @samp{$@{NAME:-VAL@}}
|
||||
|
||||
@item Write an @command{info} alias that can take arguments
|
||||
|
||||
So that the user can enter @samp{info chmod}, for example.
|
||||
|
||||
@item Create a mode @code{eshell-browse}
|
||||
|
||||
It would treat the Eshell buffer as a outline. Collapsing the outline
|
||||
hides all of the output text. Collapsing again would show only the
|
||||
first command run in each directory
|
||||
|
||||
@item Allow other revisions of a file to be referenced using @samp{file@{rev@}}
|
||||
|
||||
This would be expanded by @code{eshell-expand-file-name} (see above).
|
||||
|
||||
@item Print ``You have new mail'' when the ``Mail'' icon is turned on
|
||||
|
||||
@item Implement @kbd{M-|} for Eshell
|
||||
|
||||
@item Implement input redirection
|
||||
|
||||
If it's a Lisp function, input redirection implies @command{xargs} (in a
|
||||
way@dots{}). If input redirection is added, also update the
|
||||
@code{file-name-quote-list}, and the delimiter list.
|
||||
|
||||
@item Allow @samp{#<WORD ARG>} as a generic syntax
|
||||
|
||||
With the handling of @emph{word} specified by an
|
||||
@code{eshell-special-alist}.
|
||||
|
||||
@item In @code{eshell-eval-using-options}, allow a @code{:complete} tag
|
||||
|
||||
It would be used to provide completion rules for that command. Then the
|
||||
macro will automagically define the completion function.
|
||||
|
||||
@item For @code{eshell-command-on-region}, apply redirections to the result
|
||||
|
||||
So that @samp{+ > 'blah} would cause the result of the @code{+} (using
|
||||
input from the current region) to be inserting into the symbol
|
||||
@code{blah}.
|
||||
|
||||
If an external command is being invoked, the input is sent as standard
|
||||
input, as if a @samp{cat <region> |} had been invoked.
|
||||
|
||||
If a Lisp command, or an alias, is invoked, then if the line has no
|
||||
newline characters, it is divided by whitespace and passed as arguments
|
||||
to the Lisp function. Otherwise, it is divided at the newline
|
||||
characters. Thus, invoking @code{+} on a series of numbers will add
|
||||
them; @code{min} would display the smallest figure, etc.
|
||||
|
||||
@item Write @code{eshell-script-mode} as a minor mode
|
||||
|
||||
It would provide syntax, abbrev, highlighting and indenting support like
|
||||
@code{emacs-lisp-mode} and @code{shell-mode}.
|
||||
|
||||
@item In the history mechanism, finish the @command{bash}-style support
|
||||
|
||||
This means @samp{!n}, @samp{!#}, @samp{!:%}, and @samp{!:1-} as separate
|
||||
from @samp{!:1*}.
|
||||
|
||||
@item Support the -n command line option for @command{history}
|
||||
|
||||
@item Implement @command{fc} in Lisp
|
||||
|
||||
@item Specifying a frame as a redirection target should imply the currently active window's buffer
|
||||
|
||||
@item Implement @samp{>FUNC-OR-FUNC-LIST}
|
||||
|
||||
This would allow for an ``output translators'', that take a function to
|
||||
modify output with, and a target. Devise a syntax that works well with
|
||||
pipes, and can accomodate multiple functions (i.e., @samp{>'(upcase
|
||||
regexp-quote)} or @samp{>'upcase}).
|
||||
|
||||
@item Allow Eshell to read/write to/from standard input and output
|
||||
|
||||
This would be optional, rather than always using the Eshell buffer.
|
||||
This would allow it to be run from the command line (perhaps).
|
||||
|
||||
@item Write a @command{help} command
|
||||
|
||||
It would call subcommands with ``--help'', or ``-h'' or ``/?'', as
|
||||
appropriate.
|
||||
|
||||
@item Implement @command{stty} in Lisp
|
||||
|
||||
@item Support @command{rc}'s matching operator, e.g. @samp{~ (list) regexp}
|
||||
|
||||
@item Implement @command{bg} and @command{fg} as editors of @code{eshell-process-list}
|
||||
|
||||
Using @command{bg} on a process that is already in the background does
|
||||
nothing. Specifying redirection targets replaces (or adds) to the list
|
||||
current being used.
|
||||
|
||||
@item Have @command{jobs} print only the processes for the current shell
|
||||
|
||||
@item How can Eshell learn if a background process has requested input?
|
||||
|
||||
@item Support @samp{2>&1} and @samp{>&} and @samp{2>} and @samp{|&}
|
||||
|
||||
The syntax table for parsing these should be customizable, such that the
|
||||
user could change it to use rc syntax: @samp{>[2=1]}.
|
||||
|
||||
@item Allow @samp{$_[-1]}, which would indicate the last element of the array
|
||||
|
||||
@item Make @samp{$x[*]} equal to listing out the full contents of @samp{x}
|
||||
|
||||
Return them as a list, so that @samp{$_[*]} is all the arguments of the
|
||||
last command.
|
||||
|
||||
@item Copy ANSI code handling from @file{term.el} into @file{em-term.el}
|
||||
|
||||
Make it possible for the user to send char-by-char to the underlying
|
||||
process. Ultimately, I should be able to move away from using term.el
|
||||
altogether, since everything but the ANSI code handling is already part
|
||||
of Eshell. Then, things would work correctly on Win32 as well (which
|
||||
doesn't have @file{/bin/sh}, although @file{term.el} tries to use it)
|
||||
|
||||
@item Make the shell spawning commands be visual
|
||||
|
||||
That is, make (@command{su}, @command{bash}, @command{telnet},
|
||||
@command{rlogin}, @command{rsh}, etc.) be part of
|
||||
@code{eshell-visual-commands}. The only exception is if the shell is
|
||||
being used to invoke a single command. Then, the behavior should be
|
||||
based on what that command is.
|
||||
|
||||
@item Create an smart viewing command named @command{open}
|
||||
|
||||
This would search for some way to open its argument (similar to opening
|
||||
a file in the Windows Explorer).
|
||||
|
||||
@item Alias @command{read} to be the same as @command{open}, only read-only
|
||||
|
||||
@item Write a @command{tail} command which uses @code{view-file}
|
||||
|
||||
It would move point to the end of the buffer, and then turns on
|
||||
auto-revert mode in that buffer at frequent intervals---and a
|
||||
@command{head} alias which assums an upper limit of
|
||||
@code{eshell-maximum-line-length} characters per line.
|
||||
|
||||
@item Make @command{dgrep} load @code{dired}, mark everything, then invoke @code{dired-do-search}
|
||||
|
||||
@item Write emsh.c
|
||||
|
||||
This would run Emacs with the appropriate arguments to invoke Eshell
|
||||
only. That way, it could be listed as a login shell.
|
||||
|
||||
@item Use an intangible @code{PS2} string for multi-line input prompts
|
||||
|
||||
@item Auto-detect when a command is visual, by checking @code{TERMCAP} usage
|
||||
|
||||
@item The first keypress after @kbd{M-x watson} triggers `eshell-send-input'
|
||||
|
||||
@item Make @kbd{/} electric
|
||||
|
||||
So that it automatically expands and corrects pathnames. Or make
|
||||
pathname completion for Pcomplete auto-expand @samp{/u/i/std<TAB>} to
|
||||
@samp{/usr/include/std<TAB>}.
|
||||
|
||||
@item Write the @command{pushd} stack to disk along with @code{last-dir-ring}
|
||||
|
||||
@item Add options to @code{eshell/cat} which would allow it to sort and uniq
|
||||
|
||||
@item Implement @command{wc} in Lisp
|
||||
|
||||
Add support for counting sentences, paragraphs, pages, etc.
|
||||
|
||||
@item Once piping is added, implement @command{sort} and @command{uniq} in Lisp
|
||||
|
||||
@item Implement @command{touch} in Lisp
|
||||
|
||||
@item Implement @command{comm} in Lisp
|
||||
|
||||
@item Implement an @command{epatch} command in Lisp
|
||||
|
||||
This would call @code{ediff-patch-file}, or @code{ediff-patch-buffer},
|
||||
depending on its argument.
|
||||
|
||||
@item Have an option such that @samp{ls -l} generates a dired buffer
|
||||
|
||||
@item Write a version of @command{xargs} based on command rewriting
|
||||
|
||||
That is, @samp{find X | xargs Y} would be indicated using @samp{Y
|
||||
$@{find X@}}. Maybe @code{eshell-do-pipelines} could be changed to
|
||||
perform this on-thy-fly rewriting.
|
||||
|
||||
@item Write an alias for @command{less} that brings up a @code{view-mode} buffer
|
||||
|
||||
Such that the user can press @kbd{SPC} and @kbd{DEL}, and then @kbd{q}
|
||||
to return to Eshell. It would be equivalent to:
|
||||
@samp{X > #<buffer Y>; view-buffer #<buffer Y>}.
|
||||
|
||||
@item Make @code{eshell-mode} as much a full citizen as @code{shell-mode}
|
||||
|
||||
Everywhere in Emacs where @code{shell-mode} is specially noticed, add
|
||||
@code{eshell-mode} there.
|
||||
|
||||
@item Permit the umask to be selectively set on a @command{cp} target
|
||||
|
||||
@item Problem using @kbd{M-x eshell} after using @code{eshell-command}
|
||||
|
||||
If the first thing that I do after entering Emacs is to run
|
||||
@code{eshell-command} and invoke @command{ls}, and then use @kbd{M-x
|
||||
eshell}, it doesn't display anything.
|
||||
|
||||
@item @kbd{M-RET} during a long command (using smart display) doesn't work
|
||||
|
||||
Since it keeps the cursor up where the command was invoked.
|
||||
|
||||
@c @item problem running "less" without argument on Windows
|
||||
@c Before running telnet, I noticed that 'less' (for example) was already
|
||||
@c configured as a visual command. So I invoked it from eshell to see what
|
||||
@c would happen.
|
||||
@c
|
||||
@c Here's the result in the eshell buffer:
|
||||
@c
|
||||
@c Spawning child process: invalid argument
|
||||
@c
|
||||
@c Also a new 'less' buffer was created with nothing in it .. (presumably this
|
||||
@c holds the output of less)
|
||||
@c
|
||||
@c If I run 'less.exe' from the eshell command line, I get the output I expect
|
||||
@c simply written to the buffer.
|
||||
@c
|
||||
@c Note that I'm using FSF NT-Emacs 20.6.1 on Win2000. The term.el package and
|
||||
@c the supplied shell both seem to use the 'cmdproxy' program to run things
|
||||
@c like shells.
|
||||
@c @item implement -r, -n and -s switches for cp
|
||||
@c @item Make M-5 eshell -> switch to *eshell<5>*, creating it if need be
|
||||
@c @item mv DIR FILE.tar does not remove directories
|
||||
@c This is because the tar option --remove-files doesn't do so. Should
|
||||
@c it be Eshell's job?
|
||||
@c @item Write an article about Eshell for the LinuxWorld journal.
|
||||
@c @item bind standard-output and standard-error, so that if a Lisp function
|
||||
@c calls `print', everything will happen as it should (albeit slowly)
|
||||
@c @item when the extension modules fail to load, cd / gives a Lisp error
|
||||
@c @item if a globbing patterns returns only one match, should it still be a
|
||||
@c list?
|
||||
@c @item make sure that the syntax table correctly in eshell mode
|
||||
@c So that M-DEL acts in a predictable manner, etc.
|
||||
@c @item allow all Eshell buffers to share the same history and list-dir
|
||||
@c @item error with script commands and outputting to /dev/null
|
||||
@c If a script file, somewhere in the middle, does a "> /dev/null",
|
||||
@c output from all subsequent commands will be swallowed
|
||||
@c @item split up parsing of the text after a $ in eshell-var
|
||||
@c Similar to way that eshell-arg is structured. Then add parsing of
|
||||
@c $[?\n]
|
||||
@c @item after pressing M-RET, redisplay before running the next command
|
||||
@c @item argument predicates and modifiers should work anywhere in a path
|
||||
@c /usr/local/src/editors/vim $ vi **/CVS(/)/Root(.)
|
||||
@c Invalid regexp: "Unmatched ( or \\("
|
||||
@c
|
||||
@c with zsh, the glob above expands to all files named Root in
|
||||
@c directories named CVS.
|
||||
@c @item typing "echo ${locate locate}/bin<tab>" results in a Lisp error
|
||||
@c Perhaps it should interpolate all permutations, and make that the
|
||||
@c globbing result, since otherwise hitting return here will result in
|
||||
@c "(list of filenames)/bin", which is never very valuable. Thus, one
|
||||
@c could cat only c backup files by using "ls ${identity *.c}~". In that
|
||||
@c case, having an alias command name `glob' for `identity' would be
|
||||
@c useful
|
||||
@c @item for XEmacs on Win32, fix `file-name-all-completions'
|
||||
@c Make sure it returns directory names terminated by
|
||||
@c `directory-sep-char' (which is initialized to be ?/), rather than
|
||||
@c backslash
|
||||
@c @item once symbolic mode is supported for umask, implement chmod in Lisp
|
||||
@c @item create `eshell-expand-file-name'
|
||||
@c Which uses a data table to transform things like "~+", "...", etc
|
||||
@c @item abstract `eshell-smart.el' into `smart-scroll.el'
|
||||
@c It only really needs: to be hooked onto the output filter and the
|
||||
@c pre-command hook, and to have the input-end and input-start markers.
|
||||
@c And to know whether the last output group was "successful".
|
||||
@c @item allow for fully persisting the state of Eshell
|
||||
@c vars, history, buffer, input, dir stack, etc.
|
||||
@c @item implement D in the predicate list
|
||||
@c It means that files beginning with a dot should be included in the
|
||||
@c glob match
|
||||
@c @item a comma in a predicate list means OR
|
||||
@c @item error if a glob doesn't expand due to a predicate
|
||||
@c An error should be generated only if `eshell-error-if-no-glob' is
|
||||
@c non-nil
|
||||
@c @item the following doesn't cause an indent-according-to-mode to occur
|
||||
@c (+ RET SPC TAB
|
||||
@c @item create `eshell-auto-accumulate-list'
|
||||
@c It is a list of commands for which, if the user presses RET, the text
|
||||
@c gets staged as the next Eshell command, rather than being sent to the
|
||||
@c current interactive
|
||||
@c @item display file and line number if an error occurs in a script
|
||||
@c @item wait doesn't work with process ids at the moment
|
||||
@c @item enable the direct-to-process input code in eshell-term.el
|
||||
@c @item problem with repeating "echo ${find /tmp}"
|
||||
@c With smart display active, if I hold down RET, after a while it can't
|
||||
@c keep up anymore and starts outputting blank lines. It only happens if
|
||||
@c an asynchronous process is involved...
|
||||
@c
|
||||
@c I think the problem is that `eshell-send-input' is resetting the input
|
||||
@c target location, so that if the asynchronous process is not done by
|
||||
@c the time the next RET is received, the input processor thinks that the
|
||||
@c input is meant for the process; which, because smart display is
|
||||
@c enabled, will be the text of the last command line! That is a bug in
|
||||
@c itself.
|
||||
@c
|
||||
@c In holding down RET while an asynchronous process is running, there
|
||||
@c will be a point in between termination of the process, and the running
|
||||
@c of eshell-post-command-hook, which would cause `eshell-send-input' to
|
||||
@c call `eshell-copy-old-input', and then process that text as a command
|
||||
@c to be run after the process. Perhaps there should be a way of killing
|
||||
@c pending input between the death of the process, and the
|
||||
@c post-command-hook.
|
||||
@c @item allow for a more aggressive smart display mode
|
||||
@c Perhaps toggled by a command, that makes each output block a smart
|
||||
@c display block
|
||||
@c @item create more meta variables
|
||||
@c $! -- the reason for the failure of the last disk command, or the text
|
||||
@c of the last Lisp error
|
||||
@c
|
||||
@c $= -- a special associate array, which can take references of the form
|
||||
@c $=[REGEXP]. It also indexes into the directory ring
|
||||
@c @item eshell scripts can't execute in the background
|
||||
@c @item support zsh's "Parameter Expansion" syntax, i.e. ${NAME:-VAL}
|
||||
@c @item write an `info' alias that can take arguments
|
||||
@c So that the user can enter "info chmod"
|
||||
@c @item split off more generic code from Eshell
|
||||
@c parse-args.el --- parse a list of arguments
|
||||
@c interpolate.el --- interpolate $variable $(lisp)... references
|
||||
@c interp.el --- find which interpretor to run a script with
|
||||
@c sh-ring.el --- extend ring.el for persistant, searchable history
|
||||
@c zsh-glob.el --- zsh-style globbing and predicate/modifiers
|
||||
@c smartdisp.el --- smart scrolling in input buffers
|
||||
@c egetopt.el --- `eshell-eval-using-options'
|
||||
@c prompt.el --- code for outputting and navigating prompts
|
||||
@c cmd-rebind.el --- rebind certain keys in the input text
|
||||
@c unix.el --- provides Lispish UNIX command, such as unix-rm, etc.
|
||||
@c emacs-ls.el --- implementation of ls in Emacs Lisp
|
||||
@c texidoc.el
|
||||
@c pushd.el --- implementation of pushd/popd in Lisp
|
||||
@c interface.el -- a mode for reading command-line input from the user
|
||||
@c @item create a mode `eshell-browse'
|
||||
@c It would treat the Eshell buffer as a outline. Collapsing the outline
|
||||
@c hides all of the output text. Collapsing again would show only the
|
||||
@c first command run in each directory
|
||||
@c @item look through the Korn Shell book for feature ideas
|
||||
@c @item allow other version of a file to be referenced by "file{rev}"
|
||||
@c This would be expanded by `eshell-expand-file-name'
|
||||
@c @item print "You have new mail" when the "Mail" icon gets turned on
|
||||
@c @item implement M-|
|
||||
@c @item implement input redirection
|
||||
@c If it's a lisp function, input redirection implies "xargs" (in a
|
||||
@c way..). And if input redirection is added, don't forget to update the
|
||||
@c file-name-quote-list, and the delimiter list.
|
||||
@c @item allow #<WORD ARG> to be a generic syntax
|
||||
@c With the handling of "word" specified by an `eshell-special-alist'.
|
||||
@c @item in `eval-using-options', have a :complete tag
|
||||
@c It would be used to provide completion rules for that command. Then
|
||||
@c the macro will automagically define the completion function
|
||||
@c @item for `eshell-command-on-region', redirections apply to the result
|
||||
@c So that "+ > 'blah" will cause the result of the `+' (using input from
|
||||
@c the current region) to be inserting in the symbol `blah'.
|
||||
@c
|
||||
@c If a disk command is being invoked, the input is sent as standard
|
||||
@c input, as if a "cat <region> |" were invoked.
|
||||
@c
|
||||
@c If a lisp command, or an alias, is invoked, then: if the line has no
|
||||
@c ^J characters, it is divided by whitespace and passed as arguments to
|
||||
@c the lisp function. Otherwise, it is divided at the ^J characters.
|
||||
@c Thus, invoking `+' on a series of numbers will add them; `min' would
|
||||
@c display the smallest figure.
|
||||
@c @item write `eshell-script-mode' as a minor mode
|
||||
@c It would provide syntax, abbrev, highlighting and indenting support
|
||||
@c like emacs-lisp-mode + shell-mode.
|
||||
@c @item in the history mechanism, finish bash-style support
|
||||
@c For !n, !#, !:%, and !:1- as separate from !:1*
|
||||
@c @item support the -n command line option for "history"
|
||||
@c @item implement `fc'
|
||||
@c @item specifying a frame as a redirection target implies point's buffer
|
||||
@c @item implement ">FUNC-OR-FUNC-LIST"
|
||||
@c This would allow for an "output translator", that takes a function to
|
||||
@c modify output with, and the target. Devise a syntax that words well
|
||||
@c with pipes, and can accomodate multiple functions (i.e.,">'(upcase
|
||||
@c regexp-quote)" or ">'upcase").
|
||||
@c @item allow Eshell to read/write to/from standard input and output
|
||||
@c This would be optional, rather than always using the Eshell buffer.
|
||||
@c This would allow it to be run from the command line.
|
||||
@c @item write a "help" command
|
||||
@c It could even call subcommands with "--help" (or "-h" or "/?").
|
||||
@c @item implement stty
|
||||
@c @item support rc's matching operator, "~ (list) regexp"
|
||||
@c @item implement "bg" and "fg" to edit `eshell-process-list'
|
||||
@c Using "bg" on a process that is already in the background does
|
||||
@c nothing. Specifying redirection targets replaces (or adds) to the
|
||||
@c list current being used.
|
||||
@c @item have "jobs" print only the processes for the current eshell
|
||||
@c @item how do I discover that a background process has requested input?
|
||||
@c @item support 2>&1 and >& and 2> and |&
|
||||
@c The syntax table for parsing these should be customizable, such that
|
||||
@c the user could change it to use rc syntax: >[2=1].
|
||||
@c @item allow $_[-1], which reads the last element of the array, etc.
|
||||
@c @item make $x[*] equal to listing out the full contents of x
|
||||
@c Return them as a list, so that $_[*] is all the arguments of the last
|
||||
@c command.
|
||||
@c @item move ANSI code handling from `term' into `eshell-term'
|
||||
@c And make it possible for the user to send char-by-char to the
|
||||
@c underlying process. Ultimately, I should be able to move away from
|
||||
@c using term.el altogether, since everything but the ANSI code handling
|
||||
@c is already part of Eshell. Then, things would work correctly on Win32
|
||||
@c as well (which doesn't have "/bin/sh", though term tries to use it)
|
||||
@c @item have other shell spawning commands be visual
|
||||
@c Make (su, bash, telnet, rlogin, rsh, etc.) be part of
|
||||
@c `eshell-visual-commands'. The only exception is if rsh/su/bash are
|
||||
@c simply being used to invoke a single command. Then, it should be
|
||||
@c based on what that command is.
|
||||
@c @item create an alias "open"
|
||||
@c This will search for some way to open its argument (similar to opening
|
||||
@c a file in the Windows Explorer). Perhaps using ffap...
|
||||
@c @item alias "read" to be the same as "open", except read-only
|
||||
@c @item write a "tail -f" alias which does a view-file
|
||||
@c I.e., it moves point to the end of the buffer, and then turns on
|
||||
@c auto-revert mode in that buffer at frequent intervals -- and a head
|
||||
@c alias which assums an upper limit of `eshell-maximum-line-length'
|
||||
@c characters per line.
|
||||
@c @item make dgrep load dired, mark everything, then execute the A binding
|
||||
@c @item write emsh.c
|
||||
@c It just runs Emacs with the appropriate arguments to invoke eshell.
|
||||
@c That way, it could be listed as a login shell.
|
||||
@c @item use an intangible PS2 string for multi-line input prompts
|
||||
@c @item auto-detect when a command is visual, by checking TERMCAP usage
|
||||
@c @item First keypress after M-x watson triggers `eshell-send-input'
|
||||
@c @item Emacs 20.3: Figure out why pcomplete won't make
|
||||
@c @item Make / electric
|
||||
@c So that it automatically expands and corrects pathnames. Or make
|
||||
@c pathname completion for pcomplete auto-expand "/u/i/std<TAB>" to
|
||||
@c "/usr/include/std<TAB>".
|
||||
@c @item Write pushd/popd out to disk along with last-dir-ring
|
||||
@c @item add options to eshell/cat which would cause it to sort and uniq
|
||||
@c @item implement in Lisp: wc. Also count sentences, paragraphs, pages.
|
||||
@c @item once piping is added, implement sort and uniq
|
||||
@c @item implement touch
|
||||
@c @item implement epatch
|
||||
@c Calls ediff-patch-file, or ediff-patch-buffer, depending on its
|
||||
@c argument.
|
||||
@c @item have an option for bringing up ls -l result in a dired buffer
|
||||
@c @item write a version of xargs that's based on command rewriting
|
||||
@c find X | xargs Y == Y ${find X}. Maybe I could change
|
||||
@c eshell-do-pipelines to perform this on-thy-fly rewriting.
|
||||
@c @item implement head and tail in Lisp
|
||||
@c @item write an alias for less and more that brings up a view buffer
|
||||
@c Such that they can press SPC and DEL, and then q to return to eshell.
|
||||
@c The more command would be equivalent to: X > #<buffer Y>; view-buffer
|
||||
@c #<buffer Y>
|
||||
@c @item differentiate between aliases and functions
|
||||
@c Allow for a bash-compatible syntax, such as:
|
||||
@c
|
||||
@c alias arg=blah
|
||||
@c function arg () { blah $* }
|
||||
@c @item find the various references to shell-mode within Emacs
|
||||
@c And add support for Eshell there, since now Eshell is going to be part
|
||||
@c of Emacs.
|
||||
@c @item permit umask to be set on a cp target during the cp command
|
||||
@c @item if the first thing that I do after I enter Emacs
|
||||
@c is to run eshell-command and invoke ls, and then I use M-x eshell, it
|
||||
@c doesn't show me anything.
|
||||
@c @item M-RET during a long command doesn't quite work
|
||||
@c Since it keeps the cursor up where the command was invoked.
|
||||
@end table
|
||||
|
||||
@node Concept Index, Function and Variable Index, Bugs and ideas, Top
|
||||
|
@ -835,7 +972,7 @@ See the entry above.
|
|||
|
||||
@printindex fn
|
||||
|
||||
@node Key Index, , Function and Variable Index, Top
|
||||
@node Key Index, , Function and Variable Index, Top
|
||||
@unnumbered Key Index
|
||||
|
||||
@printindex ky
|
||||
|
|
Loading…
Add table
Reference in a new issue