feat: STATUS support
This commit is contained in:
parent
9e2e3bc35b
commit
1093bc15e5
@ -106,7 +106,9 @@ Here is the list of all available keybindings:
|
|||||||
| `ctrl-t` | set timezon |
|
| `ctrl-t` | set timezon |
|
||||||
| `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
|
||||||
|
|
||||||
|
@ -10,37 +10,54 @@
|
|||||||
|
|
||||||
# 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) {
|
function allday(collection, desc, status, color) {
|
||||||
return collection " " LIGHT_CYAN ITALIC FAINT " (allday) " OFF CYAN desc OFF
|
color = color_from_status(status)
|
||||||
|
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) {
|
function endstoday(stop, collection, desc, status) {
|
||||||
return collection " " LIGHT_CYAN " -- " stop OFF ": " CYAN desc OFF
|
color = color_from_status(status)
|
||||||
|
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) {
|
function slice(start, stop, collection, desc, status) {
|
||||||
|
color = color_from_status(status)
|
||||||
if (stop == "00:00")
|
if (stop == "00:00")
|
||||||
return collection " " LIGHT_CYAN start " -- " OFF ": " CYAN desc OFF
|
return collection " " LIGHT_CYAN start " -- " OFF ": " color desc OFF
|
||||||
else
|
else
|
||||||
return collection " " LIGHT_CYAN start OFF " -- " LIGHT_CYAN stop OFF ": " CYAN desc OFF
|
return collection " " LIGHT_CYAN start OFF " -- " LIGHT_CYAN stop OFF ": " color desc OFF
|
||||||
}
|
}
|
||||||
|
|
||||||
# Print line for a single hour entry.
|
# Print line for a single hour entry.
|
||||||
@ -79,13 +96,14 @@ BEGIN {
|
|||||||
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); next }
|
$1 == "00:00" && $2 == "00:00" { print today, $1, $3, $4, $5, allday($6, $7, $8); next }
|
||||||
$1 == "00:00" { print today, $1, $3, $4, $5, endstoday($2, $6, $7); next }
|
$1 == "00:00" { print today, $1, $3, $4, $5, endstoday($2, $6, $7, $8); 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)
|
print today, $1, $3, $4, $5, slice($1, $2, $6, $7, $8)
|
||||||
}
|
}
|
||||||
END { hrlines(dayend":00", 0, daystart) }
|
END { hrlines(dayend":00", 0, daystart) }
|
||||||
|
@ -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:VEVENT"
|
print "STATUS:CONFIRMED"
|
||||||
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)
|
||||||
|
@ -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> <summary>
|
## <start> <end> <fpath> <collection> <status> <summary>
|
||||||
## ```.
|
## ```.
|
||||||
##
|
##
|
||||||
## @assign collection_labels: See configuration of the current program.
|
## @assign collection_labels: See configuration of the current program.
|
||||||
@ -72,7 +72,8 @@ 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)
|
||||||
print start, end, fpath, collection, summary
|
status = status ? status : "CONFIRMED"
|
||||||
|
print start, end, fpath, collection, status, summary
|
||||||
}
|
}
|
||||||
|
|
||||||
# AWK program
|
# AWK program
|
||||||
@ -89,6 +90,7 @@ 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 }
|
||||||
|
@ -22,12 +22,21 @@ function escape(str)
|
|||||||
|
|
||||||
# AWK program
|
# AWK program
|
||||||
|
|
||||||
BEGIN { FS = "[:;]" }
|
BEGIN { FS = "[:;]"; zulu = strftime("%Y%m%dT%H%M%SZ", systime(), 1) }
|
||||||
/^BEGIN:VEVENT$/ { inside = 1 }
|
/^BEGIN:VEVENT$/ { inside = 1 }
|
||||||
/^END:VEVENT$/ { inside = 0; if (!duplic) print field ":" escape(value) }
|
/^END:VEVENT$/ {
|
||||||
|
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 }
|
||||||
|
82
src/main.sh
82
src/main.sh
@ -124,7 +124,13 @@ 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")
|
||||||
echo "📅 ${CYAN}$start${OFF} → ${CYAN}$end${OFF}"
|
status=$(awk -v field="STATUS" "$AWK_GET" "$fpath")
|
||||||
|
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
|
||||||
@ -244,6 +250,8 @@ __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")
|
||||||
@ -263,7 +271,7 @@ __view_day() {
|
|||||||
else
|
else
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
echo "$s|$e|$starttime|$endtime|$fpath|$collection|$description"
|
echo "$s|$e|$starttime|$endtime|$fpath|$collection|$description|$status"
|
||||||
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"
|
||||||
@ -277,6 +285,7 @@ __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-)
|
||||||
@ -302,7 +311,16 @@ __view_week() {
|
|||||||
shift
|
shift
|
||||||
#fpath="$1"
|
#fpath="$1"
|
||||||
shift
|
shift
|
||||||
description="$*"
|
collection="$1"
|
||||||
|
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")
|
||||||
@ -536,8 +554,9 @@ 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"
|
||||||
|
|
||||||
###
|
###
|
||||||
@ -631,6 +650,8 @@ __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.
|
||||||
@ -807,6 +828,51 @@ __import_to_collection() {
|
|||||||
fi
|
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
|
||||||
|
}
|
||||||
|
|
||||||
###
|
###
|
||||||
### Extra command-line options
|
### Extra command-line options
|
||||||
### --import-ni
|
### --import-ni
|
||||||
@ -956,7 +1022,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 WHITE ITALIC OFF
|
export ROOT CAT AWK_GET AWK_CALSHIFT AWK_CALANNOT CYAN STRIKE FAINT 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
|
||||||
@ -1065,7 +1131,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" \
|
--expect="ctrl-n,ctrl-t,ctrl-g,ctrl-alt-d,esc,backspace,q,alt-v,x,c" \
|
||||||
--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(
|
||||||
@ -1121,6 +1187,10 @@ 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"
|
||||||
|
Loading…
Reference in New Issue
Block a user