Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
emacs
emacs
Commits
dace60cf
Commit
dace60cf
authored
Oct 29, 2000
by
John Wiegley
Browse files
See ChangeLog
parent
657f9cb8
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
821 additions
and
292 deletions
+821
-292
etc/ChangeLog
etc/ChangeLog
+4
-0
etc/NEWS
etc/NEWS
+4
-1
lisp/ChangeLog
lisp/ChangeLog
+122
-1
lisp/calendar/timeclock.el
lisp/calendar/timeclock.el
+378
-56
lisp/eshell/em-alias.el
lisp/eshell/em-alias.el
+6
-1
lisp/eshell/em-dirs.el
lisp/eshell/em-dirs.el
+3
-3
lisp/eshell/em-glob.el
lisp/eshell/em-glob.el
+3
-2
lisp/eshell/em-ls.el
lisp/eshell/em-ls.el
+44
-30
lisp/eshell/em-script.el
lisp/eshell/em-script.el
+3
-0
lisp/eshell/em-smart.el
lisp/eshell/em-smart.el
+19
-16
lisp/eshell/em-unix.el
lisp/eshell/em-unix.el
+72
-57
lisp/eshell/esh-cmd.el
lisp/eshell/esh-cmd.el
+69
-51
lisp/eshell/esh-groups.el
lisp/eshell/esh-groups.el
+0
-1
lisp/eshell/esh-maint.el
lisp/eshell/esh-maint.el
+34
-34
lisp/eshell/esh-mode.el
lisp/eshell/esh-mode.el
+6
-5
lisp/eshell/esh-module.el
lisp/eshell/esh-module.el
+4
-2
lisp/eshell/esh-test.el
lisp/eshell/esh-test.el
+4
-4
lisp/eshell/esh-util.el
lisp/eshell/esh-util.el
+12
-2
lisp/textmodes/flyspell.el
lisp/textmodes/flyspell.el
+30
-26
man/ChangeLog
man/ChangeLog
+4
-0
No files found.
etc/ChangeLog
View file @
dace60cf
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.
...
...
etc/NEWS
View file @
dace60cf
...
...
@@ -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
...
...
lisp/ChangeLog
View file @
dace60cf
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 s
a
me
* calendar/timeclock.el (timeclock-find-discrep): A fix to s
o
me
faulty math, where holiday hours were being computing as seconds.
2000-10-13 John Wiegley <johnw@gnu.org>
...
...
lisp/calendar/timeclock.el
View file @
dace60cf
...
...
@@ -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
))))
(
def
un
timeclock-workday-remaining
(
&optional
today-only
)
(
def
subst
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
)))
(
def
un
timeclock-currently-in-p
()
(
def
subst
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
)))
(
def
un
timeclock-workday-elapsed
(
&optional
relative
)
(
def
subst
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
)))
(
def
un
timeclock-when-to-leave
(
&optional
today-only
)
(
def
subst
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
))))))
(
defun
timeclock-time-to-seconds
(
time
)
(
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
))))
(
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
)))
(
def
un
timeclock-seconds-to-time
(
seconds
)
(
def
subst
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
))))
(
def
un
timeclock-time-to-date
(
time
)
(
def
subst
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
)