aboutsummaryrefslogtreecommitdiff
path: root/zsh/functions/todoist.zsh
blob: ff2b54573a1371e5994431c219998344ea9c27b2 (plain)
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
function t() {
  case "$1" in
    "t")
      shift
      local tasks_today=$(todoist --project-namespace list --filter today)
      local selected_index=$(echo "$tasks_today" | awk '{$1=$2=$3=$4=""; print substr($0,5)}' | nl -nln | fzf \
        --preview-window=up \
        --with-nth=2.. \
        --preview "echo '$tasks_today' | sed -n '{1}p' | awk '{print \$1}' | xargs todoist --project-namespace show" \
        --bind "ctrl-x:execute(echo '$tasks_today' | sed -n '{1}p' | awk '{print \$1}' | xargs todoist close)+abort" \
        --header "Enter: show task | <C-x> complete" | awk '{print $1}')

      if [[ -n "$selected_index" ]]; then
        local task_id=$(echo "$tasks_today" | sed -n "${selected_index}p" | awk '{print $1}')
        todoist --project-namespace show "$task_id"
      fi
      ;;
    "a")
      shift
      todoist quick "$@"
      ;;
    "l")
      shift
      local all_tasks=$(todoist --project-namespace list)
      local selected_index=$(echo "$all_tasks" | awk '{$1=$4=""; print substr($0,2)}' | nl -nln | fzf \
        --preview-window=up \
        --with-nth=2.. \
        --preview "echo '$all_tasks' | sed -n '{1}p' | awk '{print \$1}' | xargs todoist --project-namespace show" \
        --bind "ctrl-t:execute(echo '$all_tasks' | sed -n '{1}p' | awk '{print \$1}' | xargs todoist modify --date $(date +%Y/%m/%d))+reload(echo '$all_tasks' | awk '{\$1=\$4=\"\"; print substr(\$0,2)}' | nl -nln)" \
        --bind "ctrl-x:execute(echo '$all_tasks' | sed -n '{1}p' | awk '{print \$1}' | xargs todoist close)+abort" \
        --header "Enter: show task | <C-t> today | <C-x> complete" | awk '{print $1}')

      if [[ -n "$selected_index" ]]; then
        local task_id=$(echo "$all_tasks" | sed -n "${selected_index}p" | awk '{print $1}')
        todoist --project-namespace show "$task_id"
      fi
      ;;
    "p")
      shift
      local all_projects=$(todoist --project-namespace projects)
      local selected_index=$(echo "$all_projects" | awk '{$1=""; print substr($0,2)}' | nl -nln | fzf \
        --preview-window=up:1 \
        --with-nth=2.. \
        --preview "echo 'Project:' {2..}" \
        --header "Select project to view tasks" | awk '{print $1}')

      if [[ -n "$selected_index" ]]; then
        local project_name=$(echo "$all_projects" | sed -n "${selected_index}p" | cut -d' ' -f2-)
        local clean_name=$(echo "$project_name" | sed 's/^#//')
        
        local filter_query
        if [[ "$clean_name" == *":"* ]]; then
          # Convert namespace format: "a:b:c:d" -> "##a & ##b & ##c & #d"
          local segments=(${(s/:/)clean_name})
          filter_query=""
          for ((i=1; i<=${#segments}; i++)); do
            local segment=$(echo "${segments[i]}" | tr '[:upper:]' '[:lower:]' | awk '{print $1}')
            
            # Add separator if not first segment
            if [[ $i -gt 1 ]]; then
              filter_query="${filter_query} & "
            fi
            
            # Last segment gets single #, all others get ##
            if [[ $i -eq ${#segments} ]]; then
              filter_query="${filter_query}#${segment}"
            else
              filter_query="${filter_query}##${segment}"
            fi
          done
        else
          filter_query="#$(echo "$clean_name" | tr '[:upper:]' '[:lower:]')"
        fi
        local project_tasks=$(todoist --project-namespace list --filter "$filter_query")
        local formatted_tasks=$(echo "$project_tasks" | awk -v proj="$project_name" '{
          # Split line into fields, find project column and remove it
          id = $1
          prio = $2  
          date = $3
          time = $4
          
          # Find where project ends by looking for the project name
          rest = substr($0, length(id " " prio " " date " " time " ") + 1)
          proj_idx = index(rest, proj)
          if (proj_idx > 0) {
            task_part = substr(rest, proj_idx + length(proj))
            gsub(/^ +/, "", task_part)  # trim leading spaces
            print id, prio, date, task_part
          } else {
            # Fallback: assume project is in field 5 and task starts from field 6
            task = ""
            for(i=6; i<=NF; i++) task = task $i (i<NF?" ":"")
            print id, prio, date, task
          }
        }')
        local selected_index=$(echo "$formatted_tasks" | awk '{$1=""; print substr($0,2)}' | nl -nln | fzf \
          --preview-window=up \
          --with-nth=2.. \
          --preview "echo '$formatted_tasks' | sed -n '{1}p' | awk '{print \$1}' | xargs todoist --project-namespace show" \
          --bind "ctrl-t:execute(echo '$formatted_tasks' | sed -n '{1}p' | awk '{print \$1}' | xargs todoist modify --date $(date +%Y/%m/%d))+reload(echo '$project_tasks' | awk 'BEGIN{OFS=\" \"} {id=\$1; prio=\$2; date=\$3; time=\$4; project=\$5; task=\"\"; for(i=6;i<=NF;i++) task=task \$i (i<NF?\" \":\"\"); print id, prio, date, task}' | awk '{\$1=\"\"; print substr(\$0,2)}' | nl -nln)" \
          --bind "ctrl-x:execute(echo '$formatted_tasks' | sed -n '{1}p' | awk '{print \$1}' | xargs todoist close)+abort" \
          --header "$project_name - Enter: show task | <C-t> today | <C-x> complete" | awk '{print $1}')

        if [[ -n "$selected_index" ]]; then
          local task_id=$(echo "$project_tasks" | sed -n "${selected_index}p" | awk '{print $1}')
          todoist --project-namespace show "$task_id"
        fi
      fi
      ;;
    "i")
      shift
      local inbox_tasks=$(todoist list --filter '#inbox')
      local selected_index=$(echo "$inbox_tasks" | awk '{$1=$2=$3=""; print substr($0,4)}' | nl -nln | fzf \
        --preview-window=up \
        --with-nth=2.. \
        --preview "echo '$inbox_tasks' | sed -n '{1}p' | awk '{print \$1}' | xargs todoist --project-namespace show" \
        --bind "ctrl-t:execute(echo '$inbox_tasks' | sed -n '{1}p' | awk '{print \$1}' | xargs todoist modify --date $(date +%Y/%m/%d))+reload(echo '$inbox_tasks' | awk '{\$1=\$2=\$3=\"\"; print substr(\$0,4)}' | nl -nln)" \
        --bind "ctrl-x:execute(echo '$inbox_tasks' | sed -n '{1}p' | awk '{print \$1}' | xargs todoist close)+abort" \
        --header "Enter: show task | <C-t> today | <C-x> complete" | awk '{print $1}')

      if [[ -n "$selected_index" ]]; then
        local task_id=$(echo "$inbox_tasks" | sed -n "${selected_index}p" | awk '{print $1}')
        todoist --project-namespace show "$task_id"
      fi
      ;;
    *)
      todoist "$@"
      ;;
  esac
}