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
}
|