summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2006-12-04 10:59:10 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2006-12-04 10:59:10 +0000
commit7960ae5d4c057d28f67263dc547d84e3ea8e06fc (patch)
tree1252b6aedbdb39c30ae225b1141744ff45d1c1d9
parent34381548da094d1be0b06f802d131f960b061ffe (diff)
downloadzsh-7960ae5d4c057d28f67263dc547d84e3ea8e06fc.tar.gz
zsh-7960ae5d4c057d28f67263dc547d84e3ea8e06fc.zip
Vin Shelton: 23027: typo in calsys.yo
unposted: missing autoload in calendar_add, improve age date shortcuts
-rw-r--r--ChangeLog10
-rw-r--r--Doc/Zsh/calsys.yo35
-rw-r--r--Functions/Calendar/age13
-rw-r--r--Functions/Calendar/calendar_add2
-rw-r--r--Functions/Calendar/calendar_scandate177
5 files changed, 176 insertions, 61 deletions
diff --git a/ChangeLog b/ChangeLog
index 8aabed72e..b487f40d3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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,
diff --git a/Doc/Zsh/calsys.yo b/Doc/Zsh/calsys.yo
index 543bf0935..b2196e448 100644
--- a/Doc/Zsh/calsys.yo
+++ b/Doc/Zsh/calsys.yo
@@ -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.
diff --git a/Functions/Calendar/age b/Functions/Calendar/age
index 2d193f473..b6f648adb 100644
--- a/Functions/Calendar/age
+++ b/Functions/Calendar/age
@@ -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
diff --git a/Functions/Calendar/calendar_add b/Functions/Calendar/calendar_add
index 2a00811fd..f7f60e136 100644
--- a/Functions/Calendar/calendar_add
+++ b/Functions/Calendar/calendar_add
@@ -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 ||
diff --git a/Functions/Calendar/calendar_scandate b/Functions/Calendar/calendar_scandate
index f0024b89a..825aaf65b 100644
--- a/Functions/Calendar/calendar_scandate
+++ b/Functions/Calendar/calendar_scandate
@@ -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.
- 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]}"
+ 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
- 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]}"
+ 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
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