aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorlonkaars <loek@pipeframe.xyz>2024-03-11 18:33:02 +0100
committerlonkaars <loek@pipeframe.xyz>2024-03-11 18:33:02 +0100
commite6c1cacb60010ec75e02cf72acf34278417670fd (patch)
tree97e8f8042f4d8461e7cec9f403787bad20ffde9e /core
initial commit (basic functionality)
Diffstat (limited to 'core')
-rw-r--r--core/config8
-rwxr-xr-xcore/help37
-rw-r--r--core/lib18
-rw-r--r--core/path5
-rwxr-xr-xcore/pause13
-rwxr-xr-xcore/reset5
-rwxr-xr-xcore/start39
-rwxr-xr-xcore/state21
l---------core/stop1
-rwxr-xr-xcore/toggle7
-rw-r--r--core/update55
11 files changed, 209 insertions, 0 deletions
diff --git a/core/config b/core/config
new file mode 100644
index 0000000..34c96b8
--- /dev/null
+++ b/core/config
@@ -0,0 +1,8 @@
+#!/bin/sh
+# initialize default configuration values
+export POMODORO_STATE_PATH="${POMODORO_STATE_PATH:-$XDG_CACHE_HOME/$progname}" # ~/.cache/dppt
+export POMODORO_NORMAL_DURATION="${POMODORO_NORMAL_DURATION:-$(( 25 * 60 ))}" # 25 minutes
+export POMODORO_BREAK_SHORT_DURATION="${POMODORO_BREAK_SHORT_DURATION:-$(( 5 * 60 ))}" # 5 minutes
+export POMODORO_BREAK_LONG_DURATION="${POMODORO_BREAK_LONG_DURATION:-$(( 15 * 60 ))}" # 15 minutes
+export POMODORO_BREAK_SHORT_INTERVAL="${POMODORO_BREAK_INTERVAL:-2}" # every other lap
+export POMODORO_BREAK_LONG_INTERVAL="${POMODORO_BREAK_INTERVAL:-6}" # every 3rd break
diff --git a/core/help b/core/help
new file mode 100755
index 0000000..98abd1e
--- /dev/null
+++ b/core/help
@@ -0,0 +1,37 @@
+#!/bin/sh
+[ "$1" = "info" ] && echo "show this very message" && exit 2
+
+cat << EOF
+$progname -- daemonless posix pomodoro timer
+
+usage:
+ $progname [options] [action] [action options]
+
+options:
+ -h, --help show help
+
+actions:
+EOF
+
+IFS=':'
+find $path -type l,f -perm /u=x,g=x,o=x 2>/dev/null | while read -r action ; do
+ action_name="$(basename "$action")"
+ if [ -L "$action" ] ; then
+ printf '%s\t%s\n' "$action_name" "same as $(basename "$(readlink -f "$action")")"
+ else
+ action_info="$("$action" info)"
+ [ $? -eq 2 ] && printf '%s\t%s\n' "$action_name" "$action_info"
+ fi
+done | awk '
+ BEGIN { FS = "\t" }
+ {
+ if (printed[$1]) next
+ printf("\t%-13s %s\n", $1, $2)
+ printed[$1] = 1
+ }
+'
+
+cat << EOF
+
+if no action is provided, the \`state\` action is chosen by default
+EOF
diff --git a/core/lib b/core/lib
new file mode 100644
index 0000000..9892663
--- /dev/null
+++ b/core/lib
@@ -0,0 +1,18 @@
+#!/bin/sh
+# utility variables and functions
+XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}" # XDG basedir specification
+
+# this variable grows automatically as long as this file is included in each
+# subcommand
+export subcmd="$subcmd${subcmd:+ }$(basename "$0")"
+
+# print an error to stdout and exit
+err() {
+ echo "error: $*" >&2
+ echo "run \`$subcmd --help\` for options" >&2
+ exit 1
+}
+
+# debug:
+# bc() { tee /dev/stderr | /usr/bin/bc ; }
+
diff --git a/core/path b/core/path
new file mode 100644
index 0000000..23f7f5c
--- /dev/null
+++ b/core/path
@@ -0,0 +1,5 @@
+#!/bin/sh
+# initialize default search path for core + plugins
+path="$core_path"
+path="$XDG_DATA_HOME/$progname:$path"
+export path
diff --git a/core/pause b/core/pause
new file mode 100755
index 0000000..a55bd30
--- /dev/null
+++ b/core/pause
@@ -0,0 +1,13 @@
+#!/bin/sh
+[ "$1" = "info" ] && echo "pause the timer" && exit 2
+
+. "$core_path/lib"
+. "$core_path/update"
+
+[ "$state" != 'running' ] && err "timer is not running"
+
+time="$("$time - $now" | bc)"
+state='paused'
+
+save_state
+
diff --git a/core/reset b/core/reset
new file mode 100755
index 0000000..5492dce
--- /dev/null
+++ b/core/reset
@@ -0,0 +1,5 @@
+#!/bin/sh
+[ "$1" = "info" ] && echo "reset the timer and lap counter" && exit 2
+
+rm -rf "$POMODORO_STATE_PATH"
+
diff --git a/core/start b/core/start
new file mode 100755
index 0000000..ae471ad
--- /dev/null
+++ b/core/start
@@ -0,0 +1,39 @@
+#!/bin/sh
+[ "$1" = "info" ] && echo "start or resume the timer" && exit 2
+
+usage() {
+ cat << EOF
+usage:
+ $subcmd [options]
+
+options:
+ -h, --help display this help text
+ -s, --skip skip to next lap, even if the timer is currently running
+
+EOF
+}
+
+. "$core_path/lib"
+. "$core_path/update"
+
+allow_skip=0
+while [ $# -gt 0 ] ; do
+ case "$1" in
+ -h|--help) usage && exit 0 ;;
+ -s|--skip) shift ; allow_skip=1 ;;
+ --) shift ; break ;;
+ *) err "unknown parameter: $1" ;;
+ esac
+done
+
+if [ "$state" = 'running' ] ; then
+ [ $allow_skip -eq 0 ] && err "timer is already running, use -s to skip lap"
+ time="0.0"
+ lap=$(( $lap + 1 ))
+ . "$core_path/update"
+fi
+
+time="$(echo "$now + $time" | bc)"
+state='running'
+
+save_state
diff --git a/core/state b/core/state
new file mode 100755
index 0000000..fcf327d
--- /dev/null
+++ b/core/state
@@ -0,0 +1,21 @@
+#!/bin/sh
+[ "$1" = "info" ] && echo "show timer" && exit 2
+. "$core_path/lib"
+
+usage() {
+ cat << EOF
+$subcmd -- show timer
+
+usage:
+ $subcmd [options]
+
+options:
+ -h, --help show help
+
+actions:
+EOF
+}
+
+. "$core_path/update"
+echo "[$state] $lap: ${remaining}s"
+
diff --git a/core/stop b/core/stop
new file mode 120000
index 0000000..398b326
--- /dev/null
+++ b/core/stop
@@ -0,0 +1 @@
+reset \ No newline at end of file
diff --git a/core/toggle b/core/toggle
new file mode 100755
index 0000000..bfb96d2
--- /dev/null
+++ b/core/toggle
@@ -0,0 +1,7 @@
+#!/bin/sh
+[ "$1" = "info" ] && echo "toggle the timer between running and paused" && exit 2
+
+. "$core_path/update"
+
+[ "$state" = 'running' ] && exec "$prog" pause || exec "$prog" start
+
diff --git a/core/update b/core/update
new file mode 100644
index 0000000..04fd29c
--- /dev/null
+++ b/core/update
@@ -0,0 +1,55 @@
+#!/bin/sh
+export now="$(date +%s.%N)"
+
+update_time=0
+
+mkdir -p "$POMODORO_STATE_PATH"
+load_or_init() {
+ property="$1"
+ default_value="$2"
+ property_path="$POMODORO_STATE_PATH/$property"
+ if [ -f "$property_path" ] ; then
+ eval $property='"$(cat "$property_path")"'
+ else
+ eval $property='$default_value'
+ fi
+}
+[ -z "$lap" ] && load_or_init lap 0
+[ -z "$state" ] && load_or_init state 'reset'
+[ -z "$time" ] && load_or_init time 0.0
+[ "$time" = "0.0" ] && update_time=1
+
+# calculate remaining time on timer
+if [ -z "$remaining" ] ; then
+ remaining="$time"
+ [ "$state" = 'running' ] && remaining="$(echo "( $time - $now ) / 1" | bc)"
+fi
+
+# go to next lap if this timer expired
+if [ "$state" = 'running' ] && [ "${remaining#-}" != "${remaining}" ] ; then
+ lap=$(( $lap + 1 ))
+ state='paused'
+ update_time=1
+fi
+
+# update remaining time if in reset
+[ "$state" = 'reset' ] && update_time=1
+
+if [ $update_time -eq 1 ] ; then
+ time="$POMODORO_NORMAL_DURATION"
+ [ $(( $lap % $POMODORO_BREAK_SHORT_INTERVAL )) -eq $(( $POMODORO_BREAK_SHORT_INTERVAL - 1 )) ] && time=$POMODORO_BREAK_SHORT_DURATION
+ [ $(( $lap % $POMODORO_BREAK_LONG_INTERVAL )) -eq $(( $POMODORO_BREAK_LONG_INTERVAL - 1 )) ] && time=$POMODORO_BREAK_LONG_DURATION
+ remaining="$time"
+fi
+
+# save state
+save_state() {
+ mkdir -p "$POMODORO_STATE_PATH"
+ echo "$lap" > "$POMODORO_STATE_PATH/lap"
+ echo "$state" > "$POMODORO_STATE_PATH/state"
+ echo "$time" > "$POMODORO_STATE_PATH/time"
+}
+
+# export state variables
+export lap state time
+