#!/bin/env zsh # All arguments are joined with spaces and inserted into the calendar # file at the appropriate point. # # While the function compares the date of the new entry with dates in the # existing calendar file, it does not do any sorting; it inserts the new # entry before the first existing entry with a later date and time. emulate -L zsh setopt extendedglob local calendar newfile REPLY lastline opt local -a calendar_entries lockfiles integer my_date done rstat nolock nobackup autoload -U calendar_{read,lockfiles,scandate} while getopts "BL" opt; do case $opt in (B) nobackup=1 ;; (L) nolock=1 ;; (*) return 1 ;; esac done shift $(( OPTIND - 1 )) # Read the calendar file from the calendar-file style zstyle -s ':datetime:calendar_add:' calendar-file calendar || calendar=~/calendar newfile=$calendar.new.$HOST.$$ if ! calendar_scandate -a "$*"; then print "$0: failed to parse date/time" >&2 return 1 fi (( my_date = $REPLY )) # $calendar doesn't necessarily exist yet. local -a match mbegin mend local my_uid their_uid # Match a UID, a unique identifier for the entry inherited from # text/calendar format. local uidpat='(|*[[:space:]])UID[[:space:]]##(#b)([[:xdigit:]]##)(|[[:space:]]*)' if [[ "$*" = ${~uidpat} ]]; then my_uid=$match[1] fi # start of block for following always to clear up lockfiles. { (( nolock )) || calendar_lockfiles $calendar || return 1 if [[ -f $calendar ]]; then calendar_read $calendar { for line in $calendar_entries; do if (( ! done )) && calendar_scandate -a $line && (( REPLY > my_date )); then print -r -- "$*" (( done = 1 )) fi # Don't save this entry if it has the same UID as the new one. if [[ -n $my_uid && $line = ${~uidpat} ]]; then their_uid=$match[1] [[ ${(U)my_uid} = ${(U)their_uid} ]] && continue fi if [[ $REPLY -eq $my_date && $line = "$*" ]]; then (( done )) && continue # paranoia: shouldn't happen (( done = 1 )) fi print -r -- $line done (( done )) || print -r -- "$*" } >$newfile if (( ! nobackup )); then if ! mv $calendar $calendar.old; then print "Couldn't back up $calendar to $calendar.old. New calendar left in $newfile." >&2 (( rstat = 1 )) fi fi else print -r -- $line >$newfile fi if (( !rstat )) && ! mv $newfile $calendar; then print "Failed to rename $newfile to $calendar. Old calendar left in $calendar.old." >&2 (( rstat = 1 )) fi } always { (( ${#lockfiles} )) && rm -f $lockfiles } return $rstat