about summary refs log tree commit diff
path: root/Completion/Unix/Command/_todo.sh
blob: 287c9ff78d538c67dfbc7bbfef8d6481fb80f895 (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
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#compdef todo.sh

# See http://todotxt.com for todo.sh.
#
# Featurettes:
#  - "replace" will complete the original text for editing
#  - completing priorities will cycle through A to Z (even without
#    menu completion)
#  - list and listall will complete +<project> and @<where> from
#    values in existing entries
#  - will complete after + and @ if typed in message text

setopt localoptions braceccl

local expl curcontext="$curcontext" state line pri nextstate item
local -a cmdlist itemlist match mbegin mend
integer NORMARG

_arguments -s -n : \
  '-@[hide context names]' \
  '-\+[hide project names]' \
  '-c[color mode]' \
  '-d[alternate config file]:config file:_files' \
  '-f[force, no confirmation]' \
  '-h[display help]' \
  '-p[plain mode, no colours]' \
  '-P[hide priority labels]' \
  "-a[don't auto-archive tasks when done]" \
  '-A[auto-archive tasks when done]' \
  '-n[automatically remove blank lines]' \
  '-N[preserve line numbers]' \
  '-t[add current date to task on creation]' \
  "-T[don't add current date to task]" \
  '-v[verbose mode, confirmation messages]' \
  '-vv[extra verbose (debug)]' \
  '-V[display version etc.]' \
  '-x[disable final filter]' \
  '1:command:->commands' \
  '*:arguments:->arguments' && return 0

local projmsg="context or project"
local txtmsg="text with contexts or projects"

# Skip "command" as command prefix if words after
if [[ $words[NORMARG] == command && NORMARG -lt CURRENT ]]; then
  (( NORMARG++ ))
fi

case $state in
  (commands)
  cmdlist=(
    "add:add TODO ITEM to todo.txt."
    "addm:add TODO ITEMs, one per line, to todo.txt."
    "addto:add text to file (not item)"
    "append:adds to item on line NUMBER the text TEXT."
    "archive:moves done items from todo.txt to done.txt."
    "command:run internal commands only"
    "del:deletes the item on line NUMBER in todo.txt."
    "depri:remove prioritization from item"
    "do:marks item on line NUMBER as done in todo.txt."
    "help:display help"
    "list:displays all todo items containing TERM(s), sorted by priority."
    "listall:displays items including done ones containing TERM(s)"
    "listcon:list all contexts"
    "listfile:display all files in .todo directory"
    "listpri:displays all items prioritized at PRIORITY."
    "move:move item between files"
    "prepend:adds to the beginning of the item on line NUMBER text TEXT."
    "pri:adds or replace in NUMBER the priority PRIORITY (upper case letter)."
    "replace:replace in NUMBER the TEXT."
    "remdup:remove exact duplicates from todo.txt."
    "report:adds the number of open and done items to report.txt."
  )
  _describe -t todo-commands 'todo.sh command' cmdlist
  ;;

  (arguments)
  case $words[NORMARG] in
    (append|command|del|move|mv|prepend|pri|replace|rm)
    if (( NORMARG == CURRENT - 1 )); then
      nextstate=item
    else
      case $words[NORMARG] in
	(pri)
	nextstate=pri
	;;
	(append|prepend)
	nextstate=proj
	;;
	(move|mv)
	nextstate=file
	;;
	(replace)
	item=${words[CURRENT-1]##0##}
	compadd -Q -- "${(qq)$(todo.sh -p list "^[ 0]*$item " | sed '/^--/,$d')##<-> (\([A-Z]\) |)}"
	;;
      esac
    fi
    ;;

    (depri|do|dp)
    nextstate=item
    ;;

    (a|add|addm|list|ls|listall|lsa)
    nextstate=proj
    ;;

    (addto)
    if (( NORMARG == CURRENT - 1 )); then
      nextstate=file
    else
      nexstate=proj
    fi
    ;;

    (listfile|lf)
    if (( NORMARG == CURRENT -1 )); then
      nextstate=file
    else
      _message "Term to search file for"
    fi
    ;;

    (listpri|lsp)
    nextstate=pri
    ;;

    (*)
    return 1
    ;;
  esac
  ;;
esac

case $nextstate in
  (file)
  _path_files -W ~/.todo
  ;;

  (item)
  itemlist=(${${(M)${(f)"$(todo.sh -p list | sed '/^--/,$d')"}##<-> *}/(#b)(<->) (*)/${match[1]}:${match[2]}})
  _describe -t todo-items 'todo item' itemlist
  ;;

  (pri)
  if [[ $words[CURRENT] = (|[A-Z]) ]]; then
    if [[ $words[CURRENT] = (|Z) ]]; then
      pri=A
    else
      # cycle priority
      pri=$words[CURRENT]
      pri=${(#)$(( #pri + 1 ))}
    fi
    _wanted priority expl 'priority' compadd -U -S '' -- $pri
  else
    _wanted priority expl 'priority' compadd {A-Z}
  fi
  ;;

  (proj)
  # This completes stuff beginning with + (projects) or @ (contexts);
  # these are todo.sh conventions.
  if [[ ! -prefix + && ! -prefix @ ]]; then
    projmsg=$txtmsg
  fi
  # In case there are quotes, ignore anything up to whitespace before
  # the + or @ (which may not even be there yet).
  compset -P '*[[:space:]]'
  _wanted search expl $projmsg \
    compadd $(todo.sh lsprj) $(todo.sh lsc)
  ;;
esac