1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-10-04 08:30:54 +02:00

Vin Shelton: 23027: typo in calsys.yo

unposted: missing autoload in calendar_add, improve age date shortcuts
This commit is contained in:
Peter Stephenson 2006-12-04 10:59:10 +00:00
parent 34381548da
commit 7960ae5d4c
5 changed files with 176 additions and 61 deletions

View file

@ -1,3 +1,13 @@
2006-12-04 Peter Stephenson <pws@csr.com>
* unposted: Doc/Zsh/calsys.yo, Functions/Calendar/age,
Functions/Calendar/calendar_add,
Functions/Calendar/calendar_scandate: autoload missing in
calendar_add; add some date shortcuts for the use of age.
* 23027: Vin Shelton: Doc/Zsh/calsys.yo: texinfo links were
reversed.
2006-12-03 Peter Stephenson <p.w.stephenson@ntlworld.com>
* 22026: Src/exec.c, Src/subst.c, Src/utils.c, Src/zsh.h,

View file

@ -172,8 +172,17 @@ in the list above. Otherwise, a time is only recognised as being
associated with a date if there is only whitespace in between, or if the
time was embedded in the date.
Days of the week are not scanned, but will be ignored if they occur
at the start of the date pattern only.
Days of the week are not normally scanned, but will be ignored if they
occur at the start of the date pattern only. However, in contexts where it
is useful to specify dates relative to today, days of the week with no
other date specification may be given. The day is assumed to be either
today or within the past week. Likewise, the words tt(yesterday),
tt(today) and tt(tomorrow) are handled. All matches are case-insensitive.
Hence if today is Monday, then tt(Sunday) is equivalent to tt(yesterday),
tt(Monday) is equivalent to tt(today), but tt(Tuesday) gives a date six
days ago. This is not generally useful within the calendar file.
Dates in this format may be combined with a time specification; for
example tt(Tomorrow, 8 p.m.).
For example, the standard date format:
@ -379,7 +388,20 @@ directly as command or arguments, or separately as shell parameters.
example(print *+LPAR()e:age 2006/10/04 2006/10/09:+RPAR())
The example above matches all files modified between the start of those
dates.
dates. The second argument may alternatively be a relative time
introduced by a tt(PLUS()):
example(print *+LPAR()e:age 2006/10/04 +5d:+RPAR())
The example above is equivalent to the previous example.
In addition to the special use of days of the week, tt(today) and
tt(yesterday), times with no date may be specified; these apply to today.
Obviously such uses become problematic around midnight.
example(print *+LPAR()e-age 12:00 13:30-+RPAR())
The example above shows files modified between 12:00 and 13:00 today.
example(print *+LPAR()e:age 2006/10/04:+RPAR())
@ -508,6 +530,11 @@ In addition to setting tt(REPLY), set tt(REPLY2) to the remainder of
the argument after the date and time have been stripped. This is
empty if the option tt(-A) was given.
)
item(tt(-t))(
Allow a time with no date specification. The date is assumed to be
today. The behaviour is unspecified if the iron tongue of midnight
is tolling twelve.
)
enditem()
)
)
@ -526,7 +553,7 @@ command tt(xmessage) to display a window with the event details.
)
enditem()
texinode(Calendar Bugs)(Calendar Utility Functions)()(Calendar Function System)
texinode(Calendar Bugs)()(Calendar Utility Functions)(Calendar Function System)
sect(Bugs)
There is no tt(calendar_delete) function.

View file

@ -55,11 +55,18 @@ fi
integer mtime=$vals[1] date1 date2
local REPLY
if calendar_scandate $AGEREF; then
# allow a time only (meaning today)
if calendar_scandate -t $AGEREF; then
date1=$REPLY
if [[ -n $AGEREF2 ]] && calendar_scandate $AGEREF2; then
date2=$REPLY
if [[ -n $AGEREF2 ]]; then
if [[ $AGEREF2 = +* ]]; then
calendar_scandate -rt $AGEREF2[2,-1] || return 1
(( date2 = date1 + REPLY ))
else
calendar_scandate -t $AGEREF2 || return 1
date2=$REPLY
fi
else
(( date2 = date1 + 24 * 60 * 60 ))
fi

View file

@ -14,7 +14,7 @@ local calendar newfile REPLY lastline
local -a calendar_entries lockfiles
integer newdate done rstat
autoload -U calendar_{read,lockfiles}
autoload -U calendar_{read,lockfiles,scandate}
# Read the calendar file from the calendar-file style
zstyle -s ':datetime:calendar_add:' calendar-file calendar ||

View file

@ -161,6 +161,7 @@ local daypat="${schars}#(sun|mon|tue|wed|thu|fri|sat)[a-z]#${schars}#"
# the day of the week is greedy, so the day of the week gets ignored
# if it's optional.)
local dspat_anchor="(|(#B)${daypat}(#b)${schars}#)"
local dspat_anchor_noday="(|${schars}#)"
# Date start pattern when not anchored at the start.
local dspat_noanchor="(|*${schars})"
# end pattern for relative times: similar remark about use of $schars.
@ -171,18 +172,20 @@ local repat="(|s)(|${schars}*)"
local monthpat="(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[a-z]#"
# days, not handled but we need to ignore them. also not localized.
integer year month day hour minute second
integer year month day hour minute second then
local opt line orig_line mname MATCH MBEGIN MEND tz
local -a match mbegin mend
# Flags that we found a date or a time (maybe a relative time)
integer date_found time_found
# Flag that it's OK to have a time only
integer time_ok
# Indices of positions of start and end of time and dates found.
# These are actual character indices as zsh would normally use, i.e.
# line[time_start,time_end] is the string for the time.
integer time_start time_end date_start date_end
integer anchor anchor_end debug relative reladd setvar
while getopts "aAdrs" opt; do
while getopts "aAdrst" opt; do
case $opt in
(a)
# anchor
@ -207,6 +210,10 @@ while getopts "aAdrs" opt; do
(( setvar = 1 ))
;;
(t)
(( time_ok = 1 ))
;;
(*)
return 1
;;
@ -216,10 +223,11 @@ shift $(( OPTIND - 1 ))
line=$1 orig_line=$1
local dspat tspat
local dspat dspat_noday tspat
if (( anchor )); then
# Anchored at the start.
dspat=$dspat_anchor
dspat_noday=$dspat_anchor_noday
if (( relative )); then
tspat=$tspat_anchor
else
@ -228,6 +236,7 @@ if (( anchor )); then
fi
else
dspat=$dspat_noanchor
dspat_noday=$dspat_noanchor
tspat=$tspat_noanchor
fi
@ -370,70 +379,132 @@ if (( relative == 0 )); then
date_start=$mbegin[2] date_end=$mend[7]
date_found=1
;;
# Look for WEEKDAY
((#bi)${~dspat_noday}(${~daypat})*)
integer wday_now wday
local wdaystr=${(L)match[3]}
date_start=$mbegin[2] date_end=$mend[2]
# Find the day number.
local -a wdays
# This is the ordering of %w in strtfime (zero-offset).
wdays=(sun mon tue wed thu fri sat sun)
(( wday = ${wdays[(i)$wdaystr]} - 1 ))
# Find the date for that day.
(( then = EPOCHSECONDS ))
strftime -s wday_now "%w" $then
# Day is either today or in the past.
(( wday_now < wday )) && (( wday_now += 7 ))
(( then -= (wday_now - wday) * 24 * 60 * 60 ))
strftime -s year "%Y" $then
strftime -s month "%m" $then
strftime -s day "%d" $then
date_found=1
;;
# Look for "today", "yesterday", "tomorrow"
((#bi)${~dspat_noday}(yesterday|today|tomorrow)(|${schars})*)
(( then = EPOCHSECONDS ))
case ${(L)match[2]} in
(yesterday)
(( then -= 24 * 60 * 60 ))
;;
(tomorrow)
(( then += 24 * 60 * 60 ))
;;
esac
strftime -s year "%Y" $then
strftime -s month "%m" $then
strftime -s day "%d" $then
date_start=$mbegin[2] date_end=$mend[2]
date_found=1
;;
esac
fi
if (( date_found )); then
if (( date_found || (time_ok && time_found) )); then
# date found
# see if there's a day at the start
if [[ ${line[1,$date_start-1]} = (#bi)${~daypat} ]]; then
date_start=$mbegin[1]
if (( date_found )); then
if [[ ${line[1,$date_start-1]} = (#bi)${~daypat} ]]; then
date_start=$mbegin[1]
fi
line=${line[1,$date_start-1]}${line[$date_end+1,-1]}
fi
line=${line[1,$date_start-1]}${line[$date_end+1,-1]}
if (( time_found )); then
# If we found a time, it must be associated with the date,
# or we can't use it. Since we removed the time from the
# string to find the date, however, it's complicated to
# know where both were found. Reconstruct the date indices of
# the original string.
if (( time_start <= date_start )); then
# Time came before start of date; add length in.
(( date_start += time_end - time_start + 1 ))
fi
if (( time_start <= date_end )); then
(( date_end += time_end - time_start + 1 ))
fi
if (( date_found )); then
# If we found a time, it must be associated with the date,
# or we can't use it. Since we removed the time from the
# string to find the date, however, it's complicated to
# know where both were found. Reconstruct the date indices of
# the original string.
if (( time_start <= date_start )); then
# Time came before start of date; add length in.
(( date_start += time_end - time_start + 1 ))
fi
if (( time_start <= date_end )); then
(( date_end += time_end - time_start + 1 ))
fi
if (( time_end + 1 < date_start )); then
# If time wholly before date, OK if only separator characters
# in between. (This allows some illogical stuff with commas
# but that's probably not important.)
if [[ ${orig_line[time_end+1,date_start-1]} != ${~schars}# ]]; then
# Clearly this can't work if anchor is set. In principle,
# we could match the date and ignore the time if it wasn't.
# However, that seems dodgy.
if (( time_end + 1 < date_start )); then
# If time wholly before date, OK if only separator characters
# in between. (This allows some illogical stuff with commas
# but that's probably not important.)
if [[ ${orig_line[time_end+1,date_start-1]} != ${~schars}# ]]; then
# Clearly this can't work if anchor is set. In principle,
# we could match the date and ignore the time if it wasn't.
# However, that seems dodgy.
return 1
else
# Form massaged line by removing the entire date/time chunk.
line="${orig_line[1,time_start-1]}${orig_line[date_end+1,-1]}"
fi
elif (( date_end + 1 < time_start )); then
# If date wholly before time, OK if only time separator characters
# in between. This allows 2006/10/12:13:43 etc.
if [[ ${orig_line[date_end+1,time_start-1]} != ${~tschars}# ]]; then
# Here, we assume the time is associated with something later
# in the line. This is pretty much inevitable for the sort
# of use we are expecting. For example,
# 2006/10/24 Meeting from early, may go on till 12:00.
# or with some uses of the calendar system,
# 2006/10/24 MR 1 Another pointless meeting WARN 01:00
# The 01:00 says warn an hour before, not that the meeting starts
# at 1 am. About the only safe way round would be to force
# a time to be present, but that's not how the traditional
# calendar programme works.
#
# Hence we need to reconstruct.
(( time_found = 0, hour = 0, minute = 0, second = 0 ))
line="${orig_line[1,date_start-1]}${orig_line[date_end+1,-1]}"
else
# As above.
line="${orig_line[1,date_start-1]}${orig_line[time_end+1,-1]}"
fi
fi
else
# Time only.
# We didn't test anchors for time originally, since it
# might have been embedded in the date. If there's no date,
# we need to test specially.
if (( anchor )) &&
[[ ${orig_line[1,time_start-1]} != ${~tschars}# ]]; then
# Anchor at start failed.
return 1
else
# Form massaged line by removing the entire date/time chunk.
line="${orig_line[1,time_start-1]}${orig_line[date_end+1,-1]}"
fi
elif (( date_end + 1 < time_start )); then
# If date wholly before time, OK if only time separator characters
# in between. This allows 2006/10/12:13:43 etc.
if [[ ${orig_line[date_end+1,time_start-1]} != ${~tschars}# ]]; then
# Here, we assume the time is associated with something later
# in the line. This is pretty much inevitable for the sort
# of use we are expecting. For example,
# 2006/10/24 Meeting from early, may go on till 12:00.
# or with some uses of the calendar system,
# 2006/10/24 MR 1 Another pointless meeting WARN 01:00
# The 01:00 says warn an hour before, not that the meeting starts
# at 1 am. About the only safe way round would be to force
# a time to be present, but that's not how the traditional
# calendar programme works.
#
# Hence we need to reconstruct.
(( time_found = 0, hour = 0, minute = 0, second = 0 ))
line="${orig_line[1,date_start-1]}${orig_line[date_end+1,-1]}"
else
# As above.
line="${orig_line[1,date_start-1]}${orig_line[time_end+1,-1]}"
fi
strftime -s year "%Y" $EPOCHSECONDS
strftime -s month "%m" $EPOCHSECONDS
strftime -s day "%d" $EPOCHSECONDS
# Date now handled.
(( date_found = 1 ))
fi
if (( debug )); then
print "Time string: $time_start,$time_end:" \
"'$orig_line[time_start,time_end]'"
print "Date string: $date_start,$date_end:" \
(( date_ok )) && print "Date string: $date_start,$date_end:" \
"'$orig_line[date_start,date_end]'"
print "Remaining line: '$line'"
fi