about summary refs log tree commit diff stats
path: root/bash/acmetodo-toggle
blob: bffccecf7be5051886e4c1cc1118766f5161900d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#!/bin/sh
# acmetodo-toggle: Toggles the status of a selected todo item.

PLAN9=${PLAN9:-"/usr/local/plan9"}
TODO_FILE="$PLAN9/lib/todo"
ACME_BIN="$PLAN9/bin/acme"

# Read the selected line(s) from standard input (Acme pipes the selection)
selected_lines=$(cat)

if [ -z "$selected_lines" ]; then
    echo "No line selected to toggle." >/dev/stderr
    exit 1
fi

# Process only the first line of the selection for toggling
line_to_toggle=$(echo "$selected_lines" | head -n 1)

new_line=""
case "$line_to_toggle" in
    '[] '*)
        new_line="[>] ${line_to_toggle:3}" # Extract content after '[ ]'
        ;;
    '[>] '*)
        new_line="[x] ${line_to_toggle:3}" # Extract content after '[>]'
        ;;
    '[x] '*)
        new_line="[ ] ${line_to_toggle:3}" # Extract content after '[x]'
        ;;
    *)
        echo "Warning: Selected line does not match a known todo item format: $line_to_toggle" >/dev/stderr
        exit 0 # Exit gracefully if not a todo item
        ;;
esac

if [ -n "$new_line" ]; then
    # Use awk for a robust in-place replacement.
    # It reads the entire file, replaces the first exact match, then prints.
    awk -v old_line="$line_to_toggle" -v new_line="$new_line" '
        BEGIN { replaced = 0 }
        $0 == old_line && !replaced {
            print new_line
            replaced = 1
            next
        }
        { print }
    ' "$TODO_FILE" > "${TODO_FILE}.tmp" && mv "${TODO_FILE}.tmp" "$TODO_FILE"

    # Find the winid of the main acmetodo window to refresh it.
    MAIN_TODO_WINID=$($ACME_BIN -w | grep "^$TODO_FILE" | cut -d' ' -f1 | head -n 1)
    if [ -n "$MAIN_TODO_WINID" ]; then
        echo 'Get' | $ACME_BIN -a "$MAIN_TODO_WINID"
    else
        echo "Warning: Main acmetodo window not found to refresh." >/dev/stderr
    fi
fi