1

Context

I'm trying to build a dialog box feeded with my timewarrior data, so I can directly select what I'm going back to rather than timew s :ids filter_tag, then time cont @12.

So, first I created the data set that is attempted to populate the Dialog options:

timew s :ids $(date -I -d'8 days ago') - $(date -I -d'tomorrow') |
    # most recent first, only the top 30 (4 additional lines are decoration)
    tac | head -n 34 |
    # format the whole thing as '1 "some label "' and so on
    sed -ne 's:.*@::p' |
    sed -e 's|\s\+[0-9]\+:.*| |g' -e's:\s\+: ":' -e's:\s*$:":' -e's:^: :'

This generates reports like the following:

 1 "some_info, some_info"
 2 "some_info, some_info"
 3 "some_info, some_info"
 4 "some_info"
 5 "some_info, some_info"
 6 "some_info, some_info, some_info"
 7 "some_info, some_info"
 8 "some_info, some_info-some_info, some_info, some_info"
 9 "some_info, some_info"
 10 "some_info, some_info-some_info, some_info, some_info"
 11 "some_info, some_info"
 12 "some_info, some_info"
 13 "some_info"
 14 "some_info, some_info"
 14 "some_info, some_info"
 15 "some_info, some_info, some_info"
 16 "some_info, some_info, some_info, some_info, some_info, some_info"
 17 "some_info, some_info, some_info"
 18 "some_info"
 19 "some_info, some_info"
 20 "some_info"
 21 "some_info, some_info, some_info, some_info, some_info, some_info"
 22 "some_info, some_info"
 23 "some_info, some_info, some_info, some_info, some_info, some_info"
 24 "some_info, some_info45, some_info some_info some_info, some_info"
 25 "some_info"
 26 "some_info"
 27 "some_info, some_info, some_info"
 28 "some_info, some_info, some_info, some_info"
 29 "some_info, some_info, some_info"
 30 "some_info"

The Dialog scaffold

So I found this scaffold to

#!/bin/bash

HEIGHT=15
WIDTH=40
CHOICE_HEIGHT=4
BACKTITLE="Backtitle here"
TITLE="Title here"
MENU="Choose one of the following options:"

OPTIONS=(1 "Option 1"
         2 "Option 2"
         3 "Option 3")

CHOICE=$(dialog --clear \
                --backtitle "$BACKTITLE" \
                --title "$TITLE" \
                --menu "$MENU" \
                $HEIGHT $WIDTH $CHOICE_HEIGHT \
                "${OPTIONS[@]}" \
                2>&1 >/dev/tty)

clear
case $CHOICE in
        1)
            echo "You chose Option 1"
            ;;
        2)
            echo "You chose Option 2"
            ;;
        3)
            echo "You chose Option 3"
            ;;
esac

Issue

So I naively thought that using OPTIONS=( $(timew s :ids $(date -I -d'8 days ago') - $(date -I -d'tomorrow') | tac | head -n 34 | sed -ne 's:.*@::p' | sed -e 's|\s\+[0-9]\+:.*| |g' -e's:\s\+: ":' -e's:\s*$:":')) as a replacement in the previous code would do the trick. But it seems that quotes won't be taken into consideration so easily. I tried to hack that around in various ways, including in a while read loop and using Shell parameter expansion: ${variable@Q}, and other horrifying stuffs, but didn't found anything that would work.

Question

How do I populate correctly the Dialog options with the output of my Timewarrior output?

1 Answer 1

2

This should achieve the effect you wanted :

#!/bin/bash

HEIGHT=15
WIDTH=40
CHOICE_HEIGHT=4
BACKTITLE="Backtitle here"
TITLE="Title here"
MENU="Choose one of the following options:"

generate_options(){
    cat << EOF
Option 1
Option 2
Option 3
EOF
}

declare -a OPTIONS
count=1
while IFS= read -r line; do
    OPTIONS+=( $((count++)) "$line" )
done < <(generate_options)

CHOICE=$(dialog --clear \
                --backtitle "$BACKTITLE" \
                --title "$TITLE" \
                --menu "$MENU" \
                $HEIGHT $WIDTH $CHOICE_HEIGHT \
                "${OPTIONS[@]}" \
                2>&1 >/dev/tty)

clear
case $CHOICE in
        1)
            echo "You chose Option 1"
            ;;
        2)
            echo "You chose Option 2"
            ;;
        3)
            echo "You chose Option 3"
            ;;
esac

You just need to replace cat command with your command (without the number at the beginning of the line).

So a full solution for this problem is:

#!/bin/bash

HEIGHT=40
WIDTH=80
CHOICE_HEIGHT=30
BACKTITLE="Timewarrior"
TITLE="Resume Selector"
MENU="Select task to resume"

generate_options(){
  # events of the last week, filtered by $@
  timew s :ids $(date -I -d'8 days ago') - $(date -I -d'tomorrow') "$@" |
    # most recent first, keep only a 60 entry buffer
    tac | head -n 60 |
    # format the whole thing as '1 some labels' and so on
    sed -ne 's:.*@::p' |
    sed -e 's|\s\+[0-9]\+:.*| |g' -e's:^: :' |
    # keep only 30 entries
    uniq | head -n 30
}

declare -a OPTIONS
while IFS= read -r line; do
  bid=$(echo "$line" | awk '{print $1}')
  peg=$(echo "$line" | sed 's:[0-9]\+\ \+::')
  # get ride of duplicates
  case "${OPTIONS[@]}" in  *"$peg"*) continue ;; esac
  OPTIONS+=( "$bid" "$peg" )
done < <(generate_options "$@")

CHOICE=$(dialog --clear \
                --backtitle "$BACKTITLE" \
                --title "$TITLE" \
                --menu "$MENU" \
                $HEIGHT $WIDTH $CHOICE_HEIGHT \
                "${OPTIONS[@]}" \
                2>&1 >/dev/tty)

clear
if [[ -z $CHOICE ]] ; then
  exit
fi
timew cont "@$CHOICE"
Sign up to request clarification or add additional context in comments.

1 Comment

Wonderful @philippe, thanks so much. I permitted myself to complete your answer with the solution that it enabled me to build.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.