A dmenu calendar.

git clone git://watertao.xyz/programs/calcurse_dmenu.git

commit cb33014693d6fecde840d80021f3071da73ce292
parent 1d5b17849f3b75d8270e4fb5c49765a6751bf2fa
Author: Jeff <dev@watertao.xyz>
Date:   Fri,  8 Aug 2025 16:52:46 -0700

Added entry editing capability

Diffstat:
MREADME | 16++++++++++------
Mcalcurse_dmenu.sh | 116++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
Mconfig.sh | 15+++++++++------
Mentries.awk | 5+++++
Aentry_edit_parser.awk | 41+++++++++++++++++++++++++++++++++++++++++
5 files changed, 156 insertions(+), 37 deletions(-)

diff --git a/README b/README @@ -92,18 +92,23 @@ Tag Commands Tag commands are tags, set by default and configurable in config.sh. They comprise currently five functions: +- :a - Show alarm entries +- :e - Entry edit +- :h - Show calendar history entries - :n - Entry note create/edit - :r - Entry remove - :t - Show todo entries -- :h - Show calendar history entries -- :a - Show alarm entries -The entry note and remove tags work by tagging an entry's entire line. -So for the following entry: +The entry edit, remove and note tags work by tagging an entry's entire +line. So for the following entry: Mon 29 > Work week begins {1W} <4 -The following returned selection will open $EDITOR to edit entry note: +The following returned selection initiates editing the entry in dmenu: + + Mon 29 > Work week begins {1W} <4:e + +And to open an $EDITOR for entry note creation/editing: Mon 29 > Work week begins {1W} <4:n @@ -166,7 +171,6 @@ Requirements Todo ---- -- Entry edit capability - Alarms diff --git a/calcurse_dmenu.sh b/calcurse_dmenu.sh @@ -19,18 +19,27 @@ cu(){ trap cu INT +cal_msg(){ + msg_m="${1:-""}" + msg_p="${2:-""}" + msg_r="${3:-0}" + printf "%s\n" "$msg_m" | $dmenu -p "$msg_p" && return $msg_r +} + cal_lno_dmenu_string(){ - l="$(<$u sed -n "s/^.*<\([0-9]\+\)\(${rm_tag}\)*\(${n_tag}\)*$/\1/p")" && \ + l="$(<$u sed -n "s/^.*<\([0-9]\+\)\(${rm_tag}\)*\(${n_tag}\)*\(${e_tag}\)*$/\1/p")" && \ [ -n "$l" ] && \ return 0 || return 1 } __cal_title(){ s="$S_TITLE" + d="$(date +"%A, %B %d %Y")" case "$typeflag" in - "h") s="$S_HISTORY" ;; + "h") s="$S_HISTORY | $d" ;; "t") s="$S_TODO" ;; "a") s="$S_ALARM" ;; + *) s="$d" ;; esac printf "%s" "$s" } @@ -70,9 +79,7 @@ cal_rm_note_ref(){ } cal_rm_entry(){ - [ "$l" -gt 0 ] && \ - sed -i "${l}d" "$db_file" && \ - cal_rm_note_file + [ "$l" -gt 0 ] && sed -i "${l}d" "$db_file" } cal_note_view(){ @@ -97,8 +104,23 @@ flag_reset(){ typeflag="c" } +cal_note_add(){ + + if cal_is_todo; then + sed -i " + ${note_lno}s/\(^\[[0-9]\+\]\)\(.*\)$/\1>${n}\2/ + " "$cal_note_add_file" && return 0 || return 1 + else + sed -i " + ${note_lno}s/\(^[0-9\/]\+ \)\(@[- 0-9\>\/:@]\+\)\({.*} \)*\(|\)/\1\2\3>${n} \4/ + ${note_lno}s/\(^[0-9\/]\+ \)\(\[[0-9]\+\] \)\({.*} \)*/\1\2\3>${n} / + " "$cal_note_add_file" && return 0 || return 1 + fi +} + cal_note_create(){ - # Add note + + # Create note >$t && "$term" $EDITOR $t if [ -s "$t" ] then @@ -107,15 +129,11 @@ cal_note_create(){ # Copy temp to new note file cp $t "${cal_notes}/${n}" # Update apts db entry with note reference - if cal_is_todo; then - sed -i " - ${l}s/\(^\[[0-9]\+\]\)\(.*\)$/\1>${n}\2/ - " "$db_file" - else - sed -i " - ${l}s/\(^[0-9\/]\+ \)\(@[- 0-9\>\/:@]\+\)\({.*} \)*\(|\)/\1\2\3>${n} \4/ - ${l}s/\(^[0-9\/]\+ \)\(\[[0-9]\+\] \)\({.*} \)*/\1\2\3>${n} / - " "$db_file" + cal_note_add_file="$db_file" + note_lno="$l" + if ! cal_note_add; then + rm -v "${cal_notes}/${n}" + cal_msg "removed note file, aborting cal_note_create" "cal_note_create error" fi fi } @@ -139,6 +157,59 @@ sort_todo(){ sed "s/^\(\[[0-9]\]\)\( .*\)\(${note_pattern}\)$/\1\3\2/" >> $x && \ return 0 || return 1 } +sort_finalize(){ + >$x && \ + sort_entries "^[[:digit:]/]{10} \[[[:digit:]]+\] {" && \ + sort_entries "^[[:digit:]/]{10} @.{29}{" && \ + sort_entries "^[[:digit:]/]{10} @.{28}[>|]" && \ + sort_entries "^[[:digit:]/]{10} \[[[:digit:]]+\] [^{]" && \ + sort_todo "^\[[1-9]\]" && \ + sort_todo "^\[0\]" && \ + cp $x "$db_file" && \ + return 0 || return 1 +} + +cal_entry_edit(){ + # Edit entry: + # Parse line into calcurse_dmenu syntax + # Then run it into dmenu to make changes + # Then rm old entry + # Then send it into the awk processing below + # for new changes to be added to db file. + # There's more to do here than I + # initially thought... + #if entry_edit="$(<$v awk -f "$entry_edit_parser_awk" | $dmenu)"; then + if <$v awk -f "$entry_edit_parser_awk" | $dmenu >$t; then + # If edit empty, ignore + <$t grep -q "^[[:space:]]*$" || [ ! -s $t ] && return 0 + # Add double colon date/description seperator if needed + <$t grep -q "^.*::.\+$" || sed -i 's/^/::/' $t + # Attemp parse of entry edit + if awk -vtypeflag="$typeflag" -f "$entry_add_awk" $t > $y; then + # If note, add it back to entry + if [ -n "$n" ]; then + cal_note_add_file="$y" + note_lno="1" + if ! cal_note_add; then + cal_msg "Error adding note back into edited entry. Aborting edit." + fi + fi + + # Remove original entry (but keep note file) + cal_rm_entry + + # Add freshly edited entry + if [ -f "$db_file" ]; then + cat "$db_file" "$y" > "$v" + sort_finalize || cal_msg "Error sorting/finalizing entry edit. Aborting edit." + fi + + cal_msg "$(<$y awk -f "$entry_edit_parser_awk")" "Entry Edit Success" + else + cal_msg "Entry edit error, aborting edit." + fi + fi +} cal_view(){ @@ -148,6 +219,7 @@ cal_view(){ if <$u grep -q "$rm_tag$" then cal_rm_entry + cal_rm_note_file elif <$u grep -q "$n_tag$" then @@ -168,6 +240,9 @@ cal_view(){ else cal_note_create fi + elif <$u grep -q "$e_tag$" + then + cal_entry_edit else cal_entry_view fi @@ -217,20 +292,11 @@ cal_view(){ # 3 > apt # 4 > event - >$x >$v [ -f "$db_file" ] && cp "$db_file" "$v" - awk -vtypeflag="$typeflag" -f "$entry_add_awk" $u >> $v && \ - sort_entries "^[[:digit:]/]{10} \[[[:digit:]]+\] {" && \ - sort_entries "^[[:digit:]/]{10} @.{29}{" && \ - sort_entries "^[[:digit:]/]{10} @.{28}[>|]" && \ - sort_entries "^[[:digit:]/]{10} \[[[:digit:]]+\] [^{]" && \ - sort_todo "^\[[1-9]\]" && \ - sort_todo "^\[0\]" && \ - cp $x "$db_file" && \ + sort_finalize && \ return 0 - return 1 fi } diff --git a/config.sh b/config.sh @@ -9,16 +9,18 @@ for i in $a; do [ -f "/usr/bin/${i}" ] && dmenu="$i" && break; done a="sxmo_terminal.sh st" for i in $a; do [ -f "/usr/bin/${i}" ] && term="$i" && break; done -# Remove entry tag -rm_tag=":r" +# Alarm tag +a_tag=":a" +# Edit tag +e_tag=":e" # Historia tag h_tag=":h" -# Todo tag -t_tag=":t" # Note tag n_tag=":n" -# Alarm tag -a_tag=":a" +# Remove entry tag +rm_tag=":r" +# Todo tag +t_tag=":t" # Strings S_YESTERDAY="Yesterday" @@ -43,4 +45,5 @@ cal_apts="$cal_dir/apts" cal_todo="$cal_dir/todo" cal_alarm="$cal_dir/alarm" entry_add_awk="$PROGDIR/entry_add.awk" +entry_edit_parser_awk="$PROGDIR/entry_edit_parser.awk" note_pattern=">[a-f0-9]\{40\}" diff --git a/entries.awk b/entries.awk @@ -59,6 +59,9 @@ function print_seperator() }else if ( p_date_type != date_type ){ print sseperator } + + # Add Month names and Years + } function entry_out() @@ -130,6 +133,8 @@ function entry_out() BEGIN{ cdate = strftime( "%Y%m%d" ) + yr = substr( 1, 4, cdate ) + mnth = substr( 5, 2, cdate ) epoch = strftime( "%s" ) cyr = strftime( "%Y" ) ymd_x = "^[0-9]{8}" diff --git a/entry_edit_parser.awk b/entry_edit_parser.awk @@ -0,0 +1,41 @@ +#!/bin/awk +{ + e_type="" + recur="" + + # Remove note + sub( />[0-9a-f]{40} */, "" ) + + # Recurrence + if ( match($0, /\{.*\}/ )){ + # Capture it + recur = " #" substr($0, RSTART + 1, RLENGTH - 2) + sub(/ ->/,"", recur) + # Remove it + sub( /[[:space:]]\{[[:alnum:]\/\->[:space:]]+\}[[:space:]]/, "" ) + } + + # Apt + if ( match( $0, ymd_x" @" )){ + match($0, /^[0-9\/ -\>@]+|/) + d=substr($0, RSTART, RLENGTH) + gsub(/ @/,"",d) + split(d, da, " -> ") + d = (da[1] == da[2]) ? da[1] : da[1] " - " da[2] + s = substr($0, RLENGTH + 2) + + # Evt + } else if ( match( $0, ymd_x" \\[" )){ + d = substr($0, 1, 10) + match($0, / *\[[0-9]+\] */) + s = substr($0, RSTART + RLENGTH) + + # Todo + } else if ( match( $0, /^\[/ )){ + match($0, /^\[[[:digit:]]+\]/) + d=substr($0, RSTART + 1, RLENGTH - 2) + s = substr($0, RLENGTH + 1) + } + + print d recur, "::", s +}