todo-jsonl 1.0.0 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/bin/todo.rb +38 -28
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1f9f0379dadc07a6aa67bc1dc0662fcb6df0b4183f55de8abbda1020e8393bfc
4
- data.tar.gz: c61ac4593f27a6bb737fe2c419fb28b356eed555291c68b33dd17a7a2589ce8b
3
+ metadata.gz: 2b0c251bf65b4b67f7e2650f10b6e898047a8dc1b5fcd89f1ebc364b27334f07
4
+ data.tar.gz: 86d3647f960571d3a7b5c9f33c55352a2852c6c193696eee090aeb93854009f8
5
5
  SHA512:
6
- metadata.gz: ce2c81b1964521382cfef561aa92e7c954a4537664966243132d9d6b8752593bcc8fe4386ff7e565e751856697ca08e1a12a798b26cb2f83856db78adea4e2a2
7
- data.tar.gz: 6235a7b73886fd6a9a8944287c8c47f012797affac60f492eb7551dd19e4690f06ad7986d63523474cf730d74507ab0caae03de5af6b296ba9613788ed408581
6
+ metadata.gz: 1e6a0153c341b7e2f7593cc2cd651e26493ea885718392d237f609c3f7b4035d538a2db20b5ba89b56639d14fafb06e7d225bcb417edf5fd5918e26574122174
7
+ data.tar.gz: 47daf98ef96b84241eeca49cbecd2ff33a4ad53663fdcbfaeba1377cabfb504b1273c71a90a462396bcec74e44f2deb4e2f37490bc1ae1a559e889f615946b61
data/bin/todo.rb CHANGED
@@ -69,7 +69,7 @@ class Todo
69
69
  DUE_DATE_TAG_PATTERN = /(^| )due:([a-zA-Z0-9-]+)/
70
70
  CONTEXT_TAG_PATTERN = /(^| )[@+][\w-]+/
71
71
  PRIORITY_FLAG = '*'
72
- TODO_FILE = "#{ENV['HOME']}/todo.jsonl"
72
+ TODO_FILE = File.join(Dir.home, 'todo.jsonl')
73
73
 
74
74
  def execute(arguments)
75
75
  begin
@@ -107,8 +107,8 @@ class Todo
107
107
  raise action + ' command requires at least two parameters' if args.length < 2
108
108
  add_note(args.first.to_i, args[1..-1].join(' '))
109
109
  when 'delnote'
110
- raise action + ' command requires exactly one parameter' if args.length != 1
111
- delete_note(args.first.to_i)
110
+ raise action + ' command requires one or two parameters' if args.length < 1 || args.length > 2
111
+ delete_note(args.first.to_i, args[1])
112
112
  when 'list'
113
113
  list(nil, args)
114
114
  when 'show'
@@ -126,7 +126,7 @@ class Todo
126
126
  else
127
127
  list(nil, arguments)
128
128
  end
129
- rescue => error
129
+ rescue StandardError => error
130
130
  puts "#{colorize('ERROR:', :red)} #{error}"
131
131
  end
132
132
  self
@@ -151,7 +151,7 @@ class Todo
151
151
  * rename <tasknumber> <text> rename task
152
152
  * del <tasknumber> delete task
153
153
  * note <tasknumber> <text> add note to task
154
- * delnote <tasknumber> delete all notes from task
154
+ * delnote <tasknumber> [number] delete a specific or all notes from task
155
155
 
156
156
  * list <regex> [regex...] list tasks (only active tasks by default)
157
157
  * show <tasknumber> show all task details
@@ -159,13 +159,14 @@ class Todo
159
159
  * cleanup <regex> [regex...] cleanup completed tasks by regex
160
160
  * help this help screen
161
161
 
162
- With list command the following pre-defined regex patterns can be also used:
163
- #{@queries.keys.join(', ')}
162
+ With list command the following pre-defined queries can be also used:
163
+ #{@queries.keys.each_with_index.map { |k, i| (i == 8 ? "\n" : '') + k }.join(', ')}
164
164
 
165
165
  Due dates can be also added via tags in task title: "due:YYYY-MM-DD"
166
+ In addition to formatted dates, you can use date synonyms:
167
+ "due:today", "due:tomorrow", and day names e.g. "due:monday" or "due:tue"
166
168
 
167
- Legend:
168
- #{STATES.select { |k, v| k != 'default' }.map { |k, v| "#{k} #{v}" }.join(', ') }, priority #{PRIORITY_FLAG}
169
+ Legend: #{STATES.select { |k, v| k != 'default' }.map { |k, v| "#{k} #{v}" }.join(', ') }, priority #{PRIORITY_FLAG}
169
170
 
170
171
  Todo file: #{TODO_FILE}
171
172
  USAGE
@@ -183,9 +184,13 @@ class Todo
183
184
  ':started' => lambda { |task| 'started' == task[:state] },
184
185
  ':new' => lambda { |task| 'new' == task[:state] },
185
186
  ':all' => lambda { |task| /\w+/.match(task[:state]) },
187
+ ':priority' => lambda { |task| task[:priority] },
188
+ ':note' => lambda { |task| task[:note] && !task[:note].empty? },
186
189
  ':today' => lambda { |task| due_dates_for_queries[0] == task[:due] },
187
190
  ':tomorrow' => lambda { |task| due_dates_for_queries[1] == task[:due] },
188
- ':next7days' => lambda { |task| /(#{due_dates_for_queries.join('|')})/.match(task[:due]) }
191
+ ':next7days' => lambda { |task| /(#{due_dates_for_queries.join('|')})/.match(task[:due]) },
192
+ ':overdue' => lambda { |task| task[:due] && task[:due] < due_dates_for_queries[0] },
193
+ ':due' => lambda { |task| task[:due] }
189
194
  }
190
195
  end
191
196
 
@@ -207,9 +212,7 @@ class Todo
207
212
 
208
213
  def write_tasks(tasks)
209
214
  File.open(TODO_FILE, 'w:UTF-8') do |file|
210
- tasks.keys.sort.each do |key|
211
- file.write(JSON.generate(tasks[key]) + "\n")
212
- end
215
+ tasks.keys.sort.each { |key| file.write(JSON.generate(tasks[key]) + "\n") }
213
216
  end
214
217
  end
215
218
 
@@ -223,15 +226,9 @@ class Todo
223
226
  end
224
227
 
225
228
  def add(text)
226
- task = {
227
- state: 'new',
228
- title: text,
229
- modified: @today.strftime(DATE_FORMAT)
230
- }
229
+ task = { state: 'new', title: text, modified: @today.strftime(DATE_FORMAT) }
231
230
  postprocess_tags(task)
232
- File.open(TODO_FILE, 'a:UTF-8') do |file|
233
- file.write(JSON.generate(task) + "\n")
234
- end
231
+ File.open(TODO_FILE, 'a:UTF-8') { |file| file.write(JSON.generate(task) + "\n") }
235
232
  list
236
233
  end
237
234
 
@@ -301,7 +298,12 @@ class Todo
301
298
  patterns ||= []
302
299
  patterns += [':active'] if (patterns & [':active', ':done', ':blocked', ':started', ':new', ':all']).empty?
303
300
  items = filter_tasks(tasks, patterns).sort_by do |num, task|
304
- [task[:priority] && task[:state] != 'done' ? 0 : 1, ORDER[task[:state] || 'default'], task[:due] || 'n/a', num]
301
+ [
302
+ task[:priority] && task[:state] != 'done' ? 0 : 1,
303
+ ORDER[task[:state] || 'default'],
304
+ task[:state] != 'done' ? task[:due] || 'n/a' : task[:modified],
305
+ num
306
+ ]
305
307
  end
306
308
  items.each do |num, task|
307
309
  state = task[:state] || 'default'
@@ -322,7 +324,7 @@ class Todo
322
324
  end
323
325
  due_date = ' ' + due_date
324
326
  end
325
- puts "#{num.to_s.rjust(task_indent, ' ')}:#{priority_flag}#{display_state} #{title}#{due_date}"
327
+ puts "#{num.to_s.rjust(task_indent)}:#{priority_flag}#{display_state} #{title}#{due_date}"
326
328
  end
327
329
  puts 'No todos found' if items.empty?
328
330
  end
@@ -334,17 +336,25 @@ class Todo
334
336
  end)
335
337
  end
336
338
 
337
- def delete_note(item)
339
+ def delete_note(item, num = nil)
338
340
  update_task(item, :show, lambda do |task|
339
- task.delete(:note)
341
+ if num.to_s.empty?
342
+ task.delete(:note)
343
+ else
344
+ raise "#{num.to_i}: Note does not exist" if num.to_i <= 0 || task[:note].to_a.size < num.to_i
345
+ task[:note].delete_at(num.to_i - 1)
346
+ task.delete(:note) if task[:note].empty?
347
+ end
340
348
  end)
341
349
  end
342
350
 
343
351
  def show(item, tasks = nil)
344
352
  tasks ||= load_tasks(item)
345
- tasks[item].each do |key, value|
346
- val = value.kind_of?(Array) ? "\n" + value.join("\n") : value
347
- puts "#{colorize(key.to_s.rjust(10, ' ') + ':', :cyan)} #{val}"
353
+ tasks[item].each do |k, v|
354
+ v = "\n" + v.each_with_index.
355
+ map { |n, i| v.size > 1 ? "#{(i + 1).to_s.rjust(v.size.to_s.size)}: #{n}" : n }.
356
+ join("\n") if v.is_a?(Array)
357
+ puts "#{colorize(k.to_s.rjust(10) + ':', :cyan)} #{v}"
348
358
  end
349
359
  end
350
360
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: todo-jsonl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gabor Bata
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-18 00:00:00.000000000 Z
11
+ date: 2021-03-24 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: