Compare commits

..

No commits in common. "1093bc15e57e9a06ae6b66780a1140574bbfabfd" and "caec86c5a0720c821a1a28b666f7c1fc96dd92a3" have entirely different histories.

6 changed files with 28 additions and 140 deletions

View File

@ -107,8 +107,6 @@ Here is the list of all available keybindings:
| `ctrl-s` | synchronize | | `ctrl-s` | synchronize |
| `ctrl-n` | add new entry | | `ctrl-n` | add new entry |
| `\` | search all appointment s| | `\` | search all appointment s|
| `x` | Cancel and confirm entry |
| `c` | Unconfirm and confirm entry |
### Day view ### Day view

View File

@ -10,54 +10,37 @@
# Functions # Functions
# Set event color based on status
# @input status: Event status, one of TENTATIVE, CONFIRMED, CANCELLED
# @return: Color modifier
function color_from_status(status) {
return status == "CANCELLED" ? STRIKE CYAN : status == "TENTATIVE" ? FAINT CYAN : CYAN
}
# Return line for all-day event. # Return line for all-day event.
# #
# @local variables: color
# @input collection: Collection symbol # @input collection: Collection symbol
# @input desc: Event description # @input desc: Event description
# @input status: Event status, one of TENTATIVE, CONFIRMED, CANCELLED
# @return: Single-line string # @return: Single-line string
function allday(collection, desc, status, color) { function allday(collection, desc) {
color = color_from_status(status) return collection " " ITALIC FAINT " (allday) " OFF desc
return collection " " LIGHT_CYAN ITALIC FAINT " (allday) " OFF color desc OFF
} }
# Return line for multi-day event, or event that starts at midnight, which ends today. # Return line for multi-day event, or event that starts at midnight, which ends today.
# #
# @local variables: color
# @input stop: Time at which the event ends # @input stop: Time at which the event ends
# @input collection: Collection symbol # @input collection: Collection symbol
# @input desc: Event description # @input desc: Event description
# @input status: Event status, one of TENTATIVE, CONFIRMED, CANCELLED
# @return: Single-line string # @return: Single-line string
function endstoday(stop, collection, desc, status) { function endstoday(stop, collection, desc) {
color = color_from_status(status) return collection " " CYAN " -- " stop OFF ": " desc
return collection " " LIGHT_CYAN " -- " stop OFF ": " color desc OFF
} }
# Return line for event that starts sometime today. # Return line for event that starts sometime today.
# #
# @local variables: color
# @input start: Time at which the event starts # @input start: Time at which the event starts
# @input stop: Time at which the event ends # @input stop: Time at which the event ends
# @input collection: Collection symbol # @input collection: Collection symbol
# @input desc: Event description # @input desc: Event description
# @input status: Event status, one of TENTATIVE, CONFIRMED, CANCELLED
# @return: Single-line string # @return: Single-line string
function slice(start, stop, collection, desc, status) { function slice(start, stop, collection, desc) {
color = color_from_status(status)
if (stop == "00:00") if (stop == "00:00")
return collection " " LIGHT_CYAN start " -- " OFF ": " color desc OFF return collection " " CYAN start " -- " OFF ": " desc
else else
return collection " " LIGHT_CYAN start OFF " -- " LIGHT_CYAN stop OFF ": " color desc OFF return collection " " CYAN start OFF " -- " CYAN stop OFF ": " desc
} }
# Print line for a single hour entry. # Print line for a single hour entry.
@ -92,18 +75,16 @@ function hrlines(start, stop, h, starth, stoph, tmp, i) {
# AWK program # AWK program
BEGIN { BEGIN {
FS = "|" FS = "|"
LIGHT_CYAN = "\033[1;36m"
CYAN = "\033[1;36m" CYAN = "\033[1;36m"
ITALIC = "\033[3m" ITALIC = "\033[3m"
FAINT = "\033[2m" FAINT = "\033[2m"
STRIKE = "\033[9m"
OFF = "\033[m" OFF = "\033[m"
OFS = "|" OFS = "|"
} }
$1 == "00:00" && $2 == "00:00" { print today, $1, $3, $4, $5, allday($6, $7, $8); next } $1 == "00:00" && $2 == "00:00" { print today, $1, $3, $4, $5, allday($6, $7); next }
$1 == "00:00" { print today, $1, $3, $4, $5, endstoday($2, $6, $7, $8); next } $1 == "00:00" { print today, $1, $3, $4, $5, endstoday($2, $6, $7); next }
$1 ~ /^[0-9]{2}:[0-9]{2}$/ { $1 ~ /^[0-9]{2}:[0-9]{2}$/ {
daystart = hrlines($1, $2, daystart) daystart = hrlines($1, $2, daystart)
print today, $1, $3, $4, $5, slice($1, $2, $6, $7, $8) print today, $1, $3, $4, $5, slice($1, $2, $6, $7)
} }
END { hrlines(dayend":00", 0, daystart) } END { hrlines(dayend":00", 0, daystart) }

View File

@ -129,7 +129,7 @@ END {
print "CREATED:" zulu print "CREATED:" zulu
print "SEQUENCE:1" print "SEQUENCE:1"
print "LAST-MODIFIED:" zulu print "LAST-MODIFIED:" zulu
print "STATUS:CONFIRMED" print "STATUS:VEVENT"
print "DTSTART;VALUE=" from_type ":" from print "DTSTART;VALUE=" from_type ":" from
print "DTEND;VALUE=" to_type ":" to print "DTEND;VALUE=" to_type ":" to
if (summary) print_fold("SUMMARY:", summary) if (summary) print_fold("SUMMARY:", summary)

View File

@ -1,7 +1,7 @@
## src/awk/parse.awk ## src/awk/parse.awk
## Parse iCalendar file and print its key aspects: ## Parse iCalendar file and print its key aspects:
## ``` ## ```
## <start> <end> <fpath> <collection> <status> <summary> ## <start> <end> <fpath> <collection> <summary>
## ```. ## ```.
## ##
## @assign collection_labels: See configuration of the current program. ## @assign collection_labels: See configuration of the current program.
@ -72,8 +72,7 @@ function print_data(start, dur, end, summary, cmd, collection, depth, path) {
cmd = "date -d '" end "' +\"%s\"" cmd = "date -d '" end "' +\"%s\""
cmd | getline end cmd | getline end
close(cmd) close(cmd)
status = status ? status : "CONFIRMED" print start, end, fpath, collection, summary
print start, end, fpath, collection, status, summary
} }
# AWK program # AWK program
@ -90,7 +89,6 @@ BEGIN {
/^DTSTART/ && inside { start = parse() } /^DTSTART/ && inside { start = parse() }
/^DTEND/ && inside { end = parse() } /^DTEND/ && inside { end = parse() }
/^DURATION/ && inside { end = parse_duration($NF); dur = 1 } /^DURATION/ && inside { end = parse_duration($NF); dur = 1 }
/^STATUS/ && inside { status = $NF }
/^[^ ]/ && rs { rs = 0 } /^[^ ]/ && rs { rs = 0 }
/^ / && rs { summary = summary substr($0, 2) } /^ / && rs { summary = summary substr($0, 2) }
/^SUMMARY/ && inside { rs = 1; summary = $0 } /^SUMMARY/ && inside { rs = 1; summary = $0 }

View File

@ -22,21 +22,12 @@ function escape(str)
# AWK program # AWK program
BEGIN { FS = "[:;]"; zulu = strftime("%Y%m%dT%H%M%SZ", systime(), 1) } BEGIN { FS = "[:;]" }
/^BEGIN:VEVENT$/ { inside = 1 } /^BEGIN:VEVENT$/ { inside = 1 }
/^END:VEVENT$/ { /^END:VEVENT$/ { inside = 0; if (!duplic) print field ":" escape(value) }
inside = 0
if (!duplic)
print field ":" escape(value)
seq = seq ? seq + 1 : 1
print "SEQUENCE:" seq
print "LAST-MODIFIED:" zulu
}
$1 == field && inside { con = 1; duplic = 1; print field ":" escape(value); next } $1 == field && inside { con = 1; duplic = 1; print field ":" escape(value); next }
$1 == field && duplic { con = 1; next } $1 == field && duplic { con = 1; next }
/^ / && con { next } /^ / && con { next }
/^ / && con { next } /^ / && con { next }
/^[^ ]/ && con { con = 0 } /^[^ ]/ && con { con = 0 }
/^SEQUENCE/ && inside { seq = $2; next } # store sequence number and skip
/^LAST-MODIFIED/ && inside { next }
{ print } { print }

View File

@ -124,13 +124,7 @@ if [ "${1:-}" = "--preview-event" ]; then
start=$(datetime_str "$start" "%a ") start=$(datetime_str "$start" "%a ")
end=$(datetime_str "$end" "%a ") end=$(datetime_str "$end" "%a ")
location=$(awk -v field="LOCATION" "$AWK_GET" "$fpath") location=$(awk -v field="LOCATION" "$AWK_GET" "$fpath")
status=$(awk -v field="STATUS" "$AWK_GET" "$fpath") echo "📅 ${CYAN}$start${OFF}${CYAN}$end${OFF}"
if [ "$status" = "TENTATIVE" ]; then
symb="🟡"
elif [ "$status" = "CANCELLED" ]; then
symb="❌"
fi
echo "📅${symb:-} ${CYAN}$start${OFF}${CYAN}$end${OFF}"
if [ -n "${location:-}" ]; then if [ -n "${location:-}" ]; then
echo "📍 ${CYAN}$location${OFF}" echo "📍 ${CYAN}$location${OFF}"
fi fi
@ -250,8 +244,6 @@ __view_day() {
shift shift
collection="$1" collection="$1"
shift shift
status="$1"
shift
description="$(echo "$*" | sed 's/|/:/g')" # we will use | as delimiter description="$(echo "$*" | sed 's/|/:/g')" # we will use | as delimiter
# #
daystart=$(date -d "$today 00:00:00" +"%s") daystart=$(date -d "$today 00:00:00" +"%s")
@ -271,7 +263,7 @@ __view_day() {
else else
continue continue
fi fi
echo "$s|$e|$starttime|$endtime|$fpath|$collection|$description|$status" echo "$s|$e|$starttime|$endtime|$fpath|$collection|$description"
done) done)
fi fi
echo "$sef" | sort -n | awk -v today="$today" -v daystart="$DAY_START" -v dayend="$DAY_END" "$AWK_DAYVIEW" echo "$sef" | sort -n | awk -v today="$today" -v daystart="$DAY_START" -v dayend="$DAY_END" "$AWK_DAYVIEW"
@ -285,7 +277,6 @@ __view_day() {
# @req $ROOT: Path that contains the collections (see configuration) # @req $ROOT: Path that contains the collections (see configuration)
# @req $COLLECTION_LABELS: Mapping between collections and lables (see configuration) # @req $COLLECTION_LABELS: Mapping between collections and lables (see configuration)
# @req $AWK_WEEKVIEW: Week-view awk script # @req $AWK_WEEKVIEW: Week-view awk script
# @req colors
__view_week() { __view_week() {
weeknr=$(date -d "$DISPLAY_DATE" +"%G.%V") weeknr=$(date -d "$DISPLAY_DATE" +"%G.%V")
files=$(grep "^$weeknr\ " "$WEEKLY_DATA_FILE" | cut -d " " -f 2-) files=$(grep "^$weeknr\ " "$WEEKLY_DATA_FILE" | cut -d " " -f 2-)
@ -311,16 +302,7 @@ __view_week() {
shift shift
#fpath="$1" #fpath="$1"
shift shift
collection="$1" description="$*"
shift
status="$1"
shift
if [ "$status" = "TENTATIVE" ]; then
symb="$FAINT$CYAN"
elif [ "$status" = "CANCELLED" ]; then
symb="$STRIKE"
fi
description="${symb:-}$*$OFF"
for i in $(seq 0 7); do for i in $(seq 0 7); do
daystart=$(date -d "$startofweek +$i days 00:00:00" +"%s") daystart=$(date -d "$startofweek +$i days 00:00:00" +"%s")
dayend=$(date -d "$startofweek +$i days 23:59:59" +"%s") dayend=$(date -d "$startofweek +$i days 23:59:59" +"%s")
@ -554,9 +536,8 @@ EOF
#RED="\033[1;31m" #RED="\033[1;31m"
WHITE="\033[1;97m" WHITE="\033[1;97m"
CYAN="\033[1;36m" CYAN="\033[1;36m"
STRIKE="\033[9m"
ITALIC="\033[3m" ITALIC="\033[3m"
FAINT="\033[2m" #FAINT="\033[2m"
OFF="\033[m" OFF="\033[m"
### ###
@ -615,9 +596,8 @@ __refresh_data() {
} }
### ###
### Helper functions ### UX helper functions
### __datetime_human_machine ### __datetime_human_machine
### __summary_for_commit
### ###
# __datetime_human_machine() # __datetime_human_machine()
@ -634,15 +614,6 @@ __datetime_human_machine() {
date -d "@$s" +"$dfmt" date -d "@$s" +"$dfmt"
} }
# __summary_for_commit()
# Get summary string that can be used in for git-commit messages.
#
# @input $1: iCalendar file path
# @req $AWK_GET: Awk script to extract fields from iCalendar file
__summary_for_commit() {
awk -v field="SUMMARY" "$AWK_GET" "$1" | tr -c -d "[:alnum:][:blank:]" | head -c 15
}
### ###
### iCalendar modification wrapper ### iCalendar modification wrapper
### ###
@ -650,8 +621,6 @@ __summary_for_commit() {
### __new ### __new
### __delete ### __delete
### __import_to_collection ### __import_to_collection
### __cancel_toggle
### __tentative_toggle
# __edit() # __edit()
# Edit iCalendar file. # Edit iCalendar file.
@ -692,7 +661,7 @@ __edit() {
mv "$filenew" "$fpath" mv "$filenew" "$fpath"
if [ -n "${GIT:-}" ]; then if [ -n "${GIT:-}" ]; then
$GIT add "$fpath" $GIT add "$fpath"
$GIT commit -m "Modified event '$(__summary_for_commit "$fpath") ...'" -- "$fpath" $GIT commit -m "Modified event" -- "$fpath"
fi fi
__refresh_data __refresh_data
else else
@ -758,7 +727,7 @@ __new() {
mv "$filenew" "$fpath" mv "$filenew" "$fpath"
if [ -n "${GIT:-}" ]; then if [ -n "${GIT:-}" ]; then
$GIT add "$fpath" $GIT add "$fpath"
$GIT commit -m "Added event '$(__summary_for_commit "$fpath") ...'" -- "$fpath" $GIT commit -m "Added event" -- "$fpath"
fi fi
start=$(awk -v field="DTSTART" "$AWK_GET" "$fpath" | grep -o '[0-9]\{8\}') start=$(awk -v field="DTSTART" "$AWK_GET" "$fpath" | grep -o '[0-9]\{8\}')
else else
@ -788,7 +757,7 @@ __delete() {
rm -v "$fpath" rm -v "$fpath"
if [ -n "${GIT:-}" ]; then if [ -n "${GIT:-}" ]; then
$GIT add "$fpath" $GIT add "$fpath"
$GIT commit -m "Deleted event '$(__summary_for_commit "$fpath") ...'" -- "$fpath" $GIT commit -m "Deleted event" -- "$fpath"
fi fi
break break
;; ;;
@ -824,52 +793,7 @@ __import_to_collection() {
mv "$filetmp" "$fpath" mv "$filetmp" "$fpath"
if [ -n "${GIT:-}" ]; then if [ -n "${GIT:-}" ]; then
$GIT add "$fpath" $GIT add "$fpath"
$GIT commit -m "Imported event '$(__summary_for_commit "$fpath") ...'" -- "$fpath" $GIT commit -m "Imported event" -- "$fpath"
fi
}
# __cancel_toggle()
# Set status of appointment to CANCELLED or CONFIRMED (toggle)
#
# @input $1: path to iCalendar file
# @req $ROOT: Path that contains the collections (see configuration)
# @req $AWK_SET: Awk script to set field value
# @req $AWK_GET: Awk script to extract fields from iCalendar file
__cancel_toggle() {
fpath="$ROOT/$1"
status=$(awk -v field="STATUS" "$AWK_GET" "$fpath")
newstatus="CANCELLED"
if [ "${status:-}" = "$newstatus" ]; then
newstatus="CONFIRMED"
fi
filetmp=$(mktemp)
awk -v field="STATUS" -v value="$newstatus" "$AWK_SET" "$fpath" >"$filetmp"
mv "$filetmp" "$fpath"
if [ -n "${GIT:-}" ]; then
$GIT add "$fpath"
$GIT commit -m "Event '$(__summary_for_commit "$fpath") ...' has now status $status" -- "$fpath"
fi
}
# __tentative_toggle
# Toggle status flag: CONFIRMED <-> TENTATIVE
# @input $1: path to iCalendar file
# @req $ROOT: Path that contains the collections (see configuration)
# @req $AWK_SET: Awk script to set field value
# @req $AWK_GET: Awk script to extract fields from iCalendar file
__tentative_toggle() {
fpath="$ROOT/$1"
status=$(awk -v field="STATUS" "$AWK_GET" "$fpath")
newstatus="TENTATIVE"
if [ "${status:-}" = "$newstatus" ]; then
newstatus="CONFIRMED"
fi
filetmp=$(mktemp)
awk -v field="STATUS" -v value="$newstatus" "$AWK_SET" "$fpath" >"$filetmp"
mv "$filetmp" "$fpath"
if [ -n "${GIT:-}" ]; then
$GIT add "$fpath"
$GIT commit -m "Event '$(__summary_for_commit "$fpath") ...' has now status $status" -- "$fpath"
fi fi
} }
@ -1022,7 +946,7 @@ __refresh_data
### Exports ### Exports
# The preview calls run in subprocesses. These require the following variables: # The preview calls run in subprocesses. These require the following variables:
export ROOT CAT AWK_GET AWK_CALSHIFT AWK_CALANNOT CYAN STRIKE FAINT WHITE ITALIC OFF export ROOT CAT AWK_GET AWK_CALSHIFT AWK_CALANNOT CYAN WHITE ITALIC OFF
# The reload commands also run in subprocesses, and use in addition # The reload commands also run in subprocesses, and use in addition
export COLLECTION_LABELS DAY_START DAY_END AWK_DAYVIEW AWK_WEEKVIEW AWK_PARSE export COLLECTION_LABELS DAY_START DAY_END AWK_DAYVIEW AWK_WEEKVIEW AWK_PARSE
# as well as the following variables that will be dynamically specified. So, we # as well as the following variables that will be dynamically specified. So, we
@ -1131,7 +1055,7 @@ while true; do
--with-nth='{6}' \ --with-nth='{6}' \
--accept-nth='1,2,3,4,5' \ --accept-nth='1,2,3,4,5' \
--preview="$0 --preview-event {}" \ --preview="$0 --preview-event {}" \
--expect="ctrl-n,ctrl-t,ctrl-g,ctrl-alt-d,esc,backspace,q,alt-v,x,c" \ --expect="ctrl-n,ctrl-t,ctrl-g,ctrl-alt-d,esc,backspace,q,alt-v" \
--bind="load:pos(1)+transform( --bind="load:pos(1)+transform(
echo change-border-label:🗓️ \$(date -d {1} +\"%A %e %B %Y\") echo change-border-label:🗓️ \$(date -d {1} +\"%A %e %B %Y\")
)+transform( )+transform(
@ -1187,10 +1111,6 @@ while true; do
set -- "--week" "$DISPLAY_DATE" set -- "--week" "$DISPLAY_DATE"
elif [ "$key" = "alt-v" ] && [ -f "$ROOT/$fpath" ]; then elif [ "$key" = "alt-v" ] && [ -f "$ROOT/$fpath" ]; then
$EDITOR "$ROOT/$fpath" $EDITOR "$ROOT/$fpath"
elif [ "$key" = "x" ] && [ -f "$ROOT/$fpath" ]; then
__cancel_toggle "$fpath"
elif [ "$key" = "c" ] && [ -f "$ROOT/$fpath" ]; then
__tentative_toggle "$fpath"
elif [ -z "$key" ] && [ -n "$fpath" ]; then elif [ -z "$key" ] && [ -n "$fpath" ]; then
__edit "$start" "$end" "$fpath" __edit "$start" "$end" "$fpath"
set -- "--day" "$DISPLAY_DATE" set -- "--day" "$DISPLAY_DATE"