sent-tools

A small toolkit of shell scripts for compiling suckless sent slideshows.
git clone https://scm.kuandu.systems/git-raw/sent-tools.git
Log | Files | Refs | README

sent-dev.sh (3837B)


      1 #!/bin/sh
      2 set -eu
      3 # sent-dev.sh — tmux-based development environment for sent slide decks
      4 #
      5 # This script:
      6 #  - Opens your editor on a sent slide spec file, creating it if missing.
      7 #  - Watches that file for changes and recompiles it to .sent.
      8 #  - Provides a pane with a shell for interactive work.
      9 #  - Watches the tables/ directory for Markdown tables + auto compiles.
     10 #
     11 # Each process runs in its own tmux pane/window.
     12 # Requires: tmux, entr, compile-sentspec-wrapper, compile-sentspec, compile-sent-tables
     13 #
     14 # Usage: sent-dev.sh <deck.sentspec>
     15 #
     16 
     17 # === Globals ===
     18 SPEC=""
     19 SPECDIR=""
     20 CONFIG_FILE=""
     21 SESSION=""
     22 COMPILE_SENTSPEC_ARGS=""
     23 EDITOR_CMD="${EDITOR:-vi}"
     24 
     25 # === Functions ===
     26 
     27 error() {
     28   printf "Error: %s\n" "$1" >&2
     29   exit 1
     30 }
     31 
     32 usage() {
     33   printf "Usage: %s <deck.sentspec>\n" "$0" >&2
     34   exit 1
     35 }
     36 
     37 check_deps() {
     38   missing=0
     39   for dep in tmux entr compile-sentspec-wrapper compile-sentspec compile-sent-tables; do
     40     if ! command -v "$dep" > /dev/null 2>&1; then
     41       printf "Dependency not found: %s\n" "$dep" >&2
     42       missing=1
     43     fi
     44   done
     45   if [ "$missing" -eq 1 ]; then
     46     error "Please install the missing dependencies and try again."
     47   fi
     48 }
     49 
     50 parse_args() {
     51   if [ "$#" -ne 1 ]; then
     52     usage
     53   fi
     54 
     55   case "$1" in
     56     *.sentspec) ;;
     57     *) error "Input file must have .sentspec extension." ;;
     58   esac
     59 
     60   # Make SPEC absolute
     61   case "$1" in
     62     /*) SPEC="$1" ;;
     63     *)
     64       SPEC=$(cd "$(dirname -- "$1")" && pwd)/$(basename -- "$1") \
     65         || error "Invalid spec path: $1"
     66       ;;
     67   esac
     68 
     69   [ -f "$SPEC" ] || : > "$SPEC"
     70 
     71   SPECDIR=$(dirname -- "$SPEC")
     72   CONFIG_FILE="$SPECDIR/config"
     73 
     74   if [ -f "$CONFIG_FILE" ]; then
     75     # shellcheck disable=SC1090
     76     . "$CONFIG_FILE"
     77   fi
     78 
     79   COMPILE_SENTSPEC_ARGS=${COMPILE_SENTSPEC_ARGS:-}
     80 }
     81 
     82 ensure_workdirs() {
     83   [ -d "$SPECDIR/tables" ] || mkdir -p "$SPECDIR/tables"
     84 }
     85 
     86 start_tmux() {
     87   # Detect if inside tmux BEFORE unsetting TMUX
     88   inside_tmux=0
     89   if [ -n "${TMUX:-}" ]; then
     90     inside_tmux=1
     91   fi
     92 
     93   if tmux has-session -t "$SESSION" 2> /dev/null; then
     94     if [ "$inside_tmux" -eq 1 ]; then
     95       tmux switch-client -t "$SESSION"
     96     else
     97       exec tmux attach-session -t "$SESSION"
     98     fi
     99     exit 0
    100   fi
    101 
    102   unset TMUX # Prevent nesting issues
    103 
    104   # === Pane Layout ===
    105 
    106   # 1. Editor pane
    107   tmux new-session -d -s "$SESSION" -n edit -c "$SPECDIR"
    108   tmux send-keys -t "$SESSION:0.0" "$EDITOR_CMD '$SPEC'" C-m
    109 
    110   # 2. Compile watcher (top right)
    111   tmux split-window -h -t "$SESSION:0" -c "$SPECDIR"
    112   tmux send-keys -t "$SESSION:0.1" "ls '$SPEC' | entr -c compile-sentspec-wrapper '$SPEC'" C-m
    113 
    114   # 3. Table watcher (below compile watcher)
    115   if [ -d "$SPECDIR/tables" ]; then
    116     if ! find "$SPECDIR/tables" -name '*.md' | grep -q .; then
    117       : > "$SPECDIR/tables/.sent-empty.md"
    118     fi
    119     tmux split-window -v -t "$SESSION:0.1" -c "$SPECDIR"
    120     tmux send-keys -t "$SESSION:0.2" \
    121       "while true; do find \"$SPECDIR/tables\" -name '*.md' | entr -d compile-sent-tables; done" C-m
    122   else
    123     # Table dir doesn't exist – create pane as shell
    124     tmux split-window -v -t "$SESSION:0.1" -c "$SPECDIR"
    125   fi
    126 
    127   # 4. Shell pane (always at bottom)
    128   tmux split-window -v -t "$SESSION:0.2"
    129   tmux send-keys -t "$SESSION:0.2" "sleep 0.1; cd '$SPECDIR'" C-m
    130 
    131   # Cleanup: Focus back to editor
    132   tmux select-window -t "$SESSION:0"
    133   tmux select-pane -t "$SESSION:0.0"
    134 
    135   # Attach or switch based on whether inside tmux *detected earlier*
    136   if [ "$inside_tmux" -eq 1 ]; then
    137     tmux switch-client -t "$SESSION"
    138   else
    139     exec tmux attach-session -t "$SESSION"
    140   fi
    141 }
    142 
    143 main() {
    144   check_deps
    145   parse_args "$@"
    146 
    147   # Unique session name based on SPEC path
    148   basename=$(basename "$SPEC" | sed 's|\.sentspec$||')
    149   cksum_val=$(printf "%s" "$SPEC" | cksum | awk '{print $1}')
    150   SESSION="sentdev-${basename}-${cksum_val}"
    151 
    152   ensure_workdirs
    153   start_tmux
    154 }
    155 
    156 main "$@"