doing 1.0.52 → 1.0.53
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.
- checksums.yaml +4 -4
- data/README.md +8 -3
- data/bin/doing +146 -114
- data/lib/doing/version.rb +1 -1
- data/lib/doing/wwid.rb +47 -34
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f55781d1fff1b59e4f2b495bc93235006e9b72aaa5ad51b0faeb55e332006570
|
4
|
+
data.tar.gz: b113d0e0ddf72bd2b56de7121414ec4cdc2ad5dfc9ced9f45d3f1ccb82381639
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf665e041da4ac7ef3d6ce676620db8e055df2d72e963e84635b8af28267c36e90882409df824aa041df11177ff96b67f721512b0ce32931bcef6c36b54dc7e7
|
7
|
+
data.tar.gz: 4450964dfdda9b69d1a0f41429e7780a6726bb81875773b090a2de346fd751e777a52f890228ac100e9d0d82354b682f74c391971f3e6785386e80d911d18759
|
data/README.md
CHANGED
@@ -17,6 +17,7 @@ _If you're one of the rare people like me who find this useful, feel free to [bu
|
|
17
17
|
- [Changelog](#changelog)
|
18
18
|
|
19
19
|
<!-- end toc -->
|
20
|
+
<!--README-->
|
20
21
|
|
21
22
|
## What and why
|
22
23
|
|
@@ -413,6 +414,8 @@ When used with `doing done`, `--back` and `--took` allow time intervals to be ac
|
|
413
414
|
|
414
415
|
All of these commands accept a `-e` argument. This opens your command line editor (as defined in the environment variable `$EDITOR`). Add your entry, save the temp file, and close it. The new entry is added. Anything after the first line is included as a note on the entry.
|
415
416
|
|
417
|
+
`doing again` (or `doing resume`) will duplicate the last @done entry (most recently completed) with a new start date (and without the @done tag). To resume the last entry matching specific tags, use `--tag=TAG`. You can specify multiple tags by separating with a comma. Multiple tags are combined with 'AND' by default (all tags must exist on the entry to match), but you can use `--bool=` to set it to 'OR' or 'NOT'. By default the new entry will be added to the same section as the matching entry, but you can specify a section with `--in=SECTION`.
|
418
|
+
|
416
419
|
`doing meanwhile` is a special command for creating and finishing tasks that may have other entries come before they're complete. When you create an entry with `doing meanwhile [entry text]`, it will automatically complete the last _@meanwhile_ item (dated _@done_ tag) and add the _@meanwhile_ tag to the new item. This allows time tracking on a more general basis, and still lets you keep track of the smaller things you do while working on an overarching project. The `meanwhile` command accepts `--back [time]` and will backdate the _@done_ tag and start date of the new task at the same time. Running `meanwhile` with no arguments will simply complete the last _@meanwhile_ task.
|
417
420
|
|
418
421
|
See `doing help meanwhile` for more options.
|
@@ -438,9 +441,9 @@ You can finish the last entry containing a specific tag or combination of tags u
|
|
438
441
|
|
439
442
|
doing finish --tag=work,project1
|
440
443
|
|
441
|
-
You can change the boolean using `--
|
444
|
+
You can change the boolean using `--bool=OR` (last entry containing any of the specified tags) or `--bool=NOT` (last entry containing none of the tags).
|
442
445
|
|
443
|
-
You can also include a `--no-date` switch to add `@done` without a finish date, meaning no time is tracked for the task. `doing cancel` is an alias for this. Like `finish`, `cancel` accepts a count to act on the last X entries, as well as `--archive` and `--section` options.
|
446
|
+
You can also include a `--no-date` switch to add `@done` without a finish date, meaning no time is tracked for the task. `doing cancel` is an alias for this. Like `finish`, `cancel` accepts a count to act on the last X entries, as well as `--archive` and `--section` options. `cancel` also accepts the `--tag` and `--bool` flags for tag filtering.
|
444
447
|
|
445
448
|
|
446
449
|
##### Tagging and Autotagging
|
@@ -621,7 +624,9 @@ Please try not to email me directly about GitHub projects.
|
|
621
624
|
|
622
625
|
Feel free to [poke around](http://github.com/ttscoff/doing/), I'll try to add more comments in the future (and retroactively).
|
623
626
|
|
624
|
-
|
627
|
+
<!--END README-->
|
628
|
+
|
629
|
+
PayPal link: [paypal.me/ttscoff](https://paypal.me/ttscoff)
|
625
630
|
|
626
631
|
## Changelog
|
627
632
|
|
data/bin/doing
CHANGED
@@ -36,23 +36,20 @@ default_command :recent
|
|
36
36
|
# sort_help :manually
|
37
37
|
|
38
38
|
desc 'Output notes if included in the template'
|
39
|
-
default_value true
|
40
|
-
switch [:notes], :default_value => true, :negatable => true
|
39
|
+
switch [:notes], default_value: true, negatable: true
|
41
40
|
|
42
41
|
desc 'Send results report to STDOUT instead of STDERR'
|
43
|
-
default_value false
|
44
|
-
switch [:stdout], :default_value => false, :negatable => false
|
42
|
+
switch [:stdout], default_value: false, negatable: false
|
45
43
|
|
46
44
|
desc 'Exclude auto tags and default tags'
|
47
|
-
switch [:x, :noauto], :
|
45
|
+
switch [:x, :noauto], default_value: false
|
48
46
|
|
49
47
|
desc 'Use a specific configuration file'
|
50
|
-
default_value false
|
51
48
|
flag [:config_file]
|
52
49
|
|
53
50
|
|
54
51
|
# desc 'Wrap notes at X chars (0 for no wrap)'
|
55
|
-
# flag [:w, :wrapwidth], :
|
52
|
+
# flag [:w, :wrapwidth], must_match: /^\d+$/, type: Integer
|
56
53
|
|
57
54
|
desc 'Specify a different doing_file'
|
58
55
|
flag [:f, :doing_file]
|
@@ -62,7 +59,7 @@ arg_name 'entry'
|
|
62
59
|
command [:now, :next] do |c|
|
63
60
|
c.desc 'Section'
|
64
61
|
c.arg_name 'section_name'
|
65
|
-
c.flag [:s, :section], :
|
62
|
+
c.flag [:s, :section], default_value: wwid.current_section
|
66
63
|
|
67
64
|
c.desc "Edit entry with #{ENV['EDITOR']}"
|
68
65
|
c.switch [:e, :editor]
|
@@ -71,7 +68,7 @@ command [:now, :next] do |c|
|
|
71
68
|
c.flag [:b, :back]
|
72
69
|
|
73
70
|
c.desc 'Timed entry, marks last entry in section as @done'
|
74
|
-
c.switch [:f, :finish_last], :
|
71
|
+
c.switch [:f, :finish_last], negatable: false, default_value: false
|
75
72
|
|
76
73
|
c.desc 'Note'
|
77
74
|
c.arg_name 'note_text'
|
@@ -100,7 +97,7 @@ command [:now, :next] do |c|
|
|
100
97
|
if input
|
101
98
|
title, note = wwid.format_input(input)
|
102
99
|
note.push(options[:n]) if options[:n]
|
103
|
-
wwid.add_item(title.cap_first, section, {:
|
100
|
+
wwid.add_item(title.cap_first, section, {note: note, back: date, timed: options[:f]})
|
104
101
|
wwid.write(wwid.doing_file)
|
105
102
|
else
|
106
103
|
raise "No content"
|
@@ -109,12 +106,12 @@ command [:now, :next] do |c|
|
|
109
106
|
if args.length > 0
|
110
107
|
title, note = wwid.format_input(args.join(" "))
|
111
108
|
note.push(options[:n]) if options[:n]
|
112
|
-
wwid.add_item(title.cap_first, section, {:
|
109
|
+
wwid.add_item(title.cap_first, section, {note: note, back: date, timed: options[:f]})
|
113
110
|
wwid.write(wwid.doing_file)
|
114
111
|
elsif STDIN.stat.size > 0
|
115
112
|
title, note = wwid.format_input(STDIN.read)
|
116
113
|
note.push(options[:n]) if options[:n]
|
117
|
-
wwid.add_item(title.cap_first, section, {:
|
114
|
+
wwid.add_item(title.cap_first, section, {note: note, back: date, timed: options[:f]})
|
118
115
|
wwid.write(wwid.doing_file)
|
119
116
|
else
|
120
117
|
raise "You must provide content when creating a new entry"
|
@@ -133,13 +130,13 @@ arg_name 'note_text'
|
|
133
130
|
command :note do |c|
|
134
131
|
c.desc 'Section'
|
135
132
|
c.arg_name 'section_name'
|
136
|
-
c.flag [:s, :section], :
|
133
|
+
c.flag [:s, :section], default_value: "All"
|
137
134
|
|
138
135
|
c.desc "Edit entry with #{ENV['EDITOR']}"
|
139
|
-
c.switch [:e, :editor], :
|
136
|
+
c.switch [:e, :editor], negatable: false, default_value: false
|
140
137
|
|
141
138
|
c.desc "Replace/Remove last entry's note (default append)"
|
142
|
-
c.switch [:r, :remove], :
|
139
|
+
c.switch [:r, :remove], negatable: false, default_value: false
|
143
140
|
|
144
141
|
c.action do |global_options,options,args|
|
145
142
|
section = wwid.guess_section(options[:s]) || options[:s].cap_first
|
@@ -192,13 +189,13 @@ arg_name 'entry'
|
|
192
189
|
command :meanwhile do |c|
|
193
190
|
c.desc 'Section'
|
194
191
|
c.arg_name 'section_name'
|
195
|
-
c.flag [:s, :section], :
|
192
|
+
c.flag [:s, :section], default_value: wwid.current_section
|
196
193
|
|
197
194
|
c.desc "Edit entry with #{ENV['EDITOR']}"
|
198
195
|
c.switch [:e, :editor]
|
199
196
|
|
200
197
|
c.desc "Archive previous @meanwhile entry"
|
201
|
-
c.switch [:a, :archive], :
|
198
|
+
c.switch [:a, :archive], default_value: false
|
202
199
|
|
203
200
|
c.desc 'Backdate start date for new entry to date string [4pm|20m|2h|yesterday noon]'
|
204
201
|
c.flag [:b, :back]
|
@@ -233,7 +230,7 @@ command :meanwhile do |c|
|
|
233
230
|
input = false unless input && input.length > 0
|
234
231
|
|
235
232
|
note = options[:n] ? options[:n] : false
|
236
|
-
wwid.stop_start('meanwhile', {:
|
233
|
+
wwid.stop_start('meanwhile', {new_item: input, back: date, section: section, archive: options[:a], note: note})
|
237
234
|
wwid.write(wwid.doing_file)
|
238
235
|
end
|
239
236
|
end
|
@@ -296,7 +293,7 @@ command :later do |c|
|
|
296
293
|
if input
|
297
294
|
title, note = wwid.format_input(input)
|
298
295
|
note.push(options[:n]) if options[:n]
|
299
|
-
wwid.add_item(title.cap_first, "Later", {:
|
296
|
+
wwid.add_item(title.cap_first, "Later", {note: note, back: date})
|
300
297
|
wwid.write(wwid.doing_file)
|
301
298
|
else
|
302
299
|
raise "No content"
|
@@ -305,12 +302,12 @@ command :later do |c|
|
|
305
302
|
if args.length > 0
|
306
303
|
title, note = wwid.format_input(args.join(" "))
|
307
304
|
note.push(options[:n]) if options[:n]
|
308
|
-
wwid.add_item(title.cap_first, "Later", {:
|
305
|
+
wwid.add_item(title.cap_first, "Later", {note: note, back: date})
|
309
306
|
wwid.write(wwid.doing_file)
|
310
307
|
elsif STDIN.stat.size > 0
|
311
308
|
title, note = wwid.format_input(STDIN.read)
|
312
309
|
note.push(options[:n]) if options[:n]
|
313
|
-
wwid.add_item(title.cap_first, "Later", {:
|
310
|
+
wwid.add_item(title.cap_first, "Later", {note: note, back: date})
|
314
311
|
wwid.write(wwid.doing_file)
|
315
312
|
else
|
316
313
|
raise "You must provide content when creating a new entry"
|
@@ -323,13 +320,13 @@ desc 'Add a completed item with @done(date). No argument finishes last entry.'
|
|
323
320
|
arg_name 'entry'
|
324
321
|
command [:done, :did] do |c|
|
325
322
|
c.desc 'Remove @done tag'
|
326
|
-
c.switch [:r, :remove], :
|
323
|
+
c.switch [:r, :remove], negatable: false, default_value: false
|
327
324
|
|
328
325
|
c.desc 'Include date'
|
329
|
-
c.switch [:date], :
|
326
|
+
c.switch [:date], negatable: true, default_value: true
|
330
327
|
|
331
328
|
c.desc 'Immediately archive the entry'
|
332
|
-
c.switch [:a, :archive], :
|
329
|
+
c.switch [:a, :archive], negatable: false, default_value: false
|
333
330
|
|
334
331
|
c.desc 'Set finish date to specific date/time (natural langauge parsed, e.g. --at=1:30pm). If used, ignores --back. Used with --took, backdates start date'
|
335
332
|
c.flag [:at]
|
@@ -341,7 +338,7 @@ command [:done, :did] do |c|
|
|
341
338
|
c.flag [:t, :took]
|
342
339
|
|
343
340
|
c.desc 'Section'
|
344
|
-
c.flag [:s, :section], :
|
341
|
+
c.flag [:s, :section], default_value: wwid.current_section
|
345
342
|
|
346
343
|
c.desc "Edit entry with #{ENV['EDITOR']}"
|
347
344
|
c.switch [:e, :editor]
|
@@ -390,16 +387,16 @@ command [:done, :did] do |c|
|
|
390
387
|
title, note = wwid.format_input(input)
|
391
388
|
title += " @done#{donedate}"
|
392
389
|
section = "Archive" if options[:a]
|
393
|
-
wwid.add_item(title.cap_first, section.cap_first, {:
|
390
|
+
wwid.add_item(title.cap_first, section.cap_first, {note: note, back: date})
|
394
391
|
wwid.write(wwid.doing_file)
|
395
392
|
else
|
396
393
|
raise "No content"
|
397
394
|
end
|
398
395
|
elsif args.length == 0 && STDIN.stat.size == 0
|
399
396
|
if options[:r]
|
400
|
-
wwid.tag_last({:
|
397
|
+
wwid.tag_last({tags: ["done"], count: 1, section: section, remove: true })
|
401
398
|
else
|
402
|
-
wwid.tag_last({:
|
399
|
+
wwid.tag_last({tags: ["done"], count: 1, section: section, archive: options[:a], back: finish_date, date: options[:date]})
|
403
400
|
end
|
404
401
|
else
|
405
402
|
if args.length > 0
|
@@ -407,13 +404,13 @@ command [:done, :did] do |c|
|
|
407
404
|
title.chomp!
|
408
405
|
title += " @done#{donedate}"
|
409
406
|
section = "Archive" if options[:a]
|
410
|
-
wwid.add_item(title.cap_first, section.cap_first, {:
|
407
|
+
wwid.add_item(title.cap_first, section.cap_first, {note: note, back: date})
|
411
408
|
wwid.write(wwid.doing_file)
|
412
409
|
elsif STDIN.stat.size > 0
|
413
410
|
title, note = wwid.format_input(STDIN.read)
|
414
411
|
title += " @done#{donedate}"
|
415
412
|
section = options[:a] ? "Archive" : section
|
416
|
-
wwid.add_item(title.cap_first, section.cap_first, {:
|
413
|
+
wwid.add_item(title.cap_first, section.cap_first, {note: note, back: date})
|
417
414
|
wwid.write(wwid.doing_file)
|
418
415
|
else
|
419
416
|
raise "You must provide content when creating a new entry"
|
@@ -427,20 +424,34 @@ long_desc 'Adds @done tag without datestamp so no elapsed time is recorded. Alia
|
|
427
424
|
arg_name 'count'
|
428
425
|
command :cancel do |c|
|
429
426
|
c.desc 'Archive entries'
|
430
|
-
c.switch [:a, :archive], :
|
427
|
+
c.switch [:a, :archive], negatable: false, default_value: false
|
431
428
|
|
432
429
|
c.desc 'Section'
|
433
|
-
c.flag [:s, :section], :
|
430
|
+
c.flag [:s, :section], default_value: wwid.current_section
|
431
|
+
|
432
|
+
c.desc 'Cancel the last X entries containing TAG. Separate multiple tags with comma (--tag=tag2,tag2)'
|
433
|
+
c.flag [:tag]
|
434
|
+
|
435
|
+
c.desc 'Boolean (AND|OR|NOT) with which to combine multiple tag filters'
|
436
|
+
c.flag [:bool], must_match: /^(and|or|not)$/i, default_value: 'AND'
|
437
|
+
|
434
438
|
|
435
439
|
c.action do |global_options,options,args|
|
436
440
|
|
437
441
|
section = wwid.guess_section(options[:s]) || options[:s].cap_first
|
438
442
|
|
443
|
+
if options[:tag].nil?
|
444
|
+
tags = []
|
445
|
+
else
|
446
|
+
tags = options[:tag].split(/ *, */).map {|t| t.strip.sub(/^@/, '') }
|
447
|
+
options[:bool] = options[:bool] =~ /^(and|or|not)$/i ? options[:bool].upcase : 'AND'
|
448
|
+
end
|
449
|
+
|
439
450
|
if args.length > 1
|
440
451
|
raise "Only one argument allowed"
|
441
452
|
elsif args.length == 0 || args[0] =~ /\d+/
|
442
453
|
count = args[0] ? args[0].to_i : 1
|
443
|
-
wwid.tag_last({:
|
454
|
+
wwid.tag_last({tags: ["done"], count: count, section: section, archive: options[:a], sequential: false, date: false, tag: tags, tag_bool: options[:bool] })
|
444
455
|
else
|
445
456
|
raise "Invalid argument (specify number of recent items to mark @done)"
|
446
457
|
end
|
@@ -452,7 +463,7 @@ long_desc 'Marks the last X entries with a @done tag and current date. Does not
|
|
452
463
|
arg_name 'count'
|
453
464
|
command :finish do |c|
|
454
465
|
c.desc 'Include date'
|
455
|
-
c.switch [:date], :
|
466
|
+
c.switch [:date], negatable: true, default_value: true
|
456
467
|
|
457
468
|
c.desc 'Backdate completed date to date string [4pm|20m|2h|yesterday noon]'
|
458
469
|
c.flag [:b, :back]
|
@@ -464,16 +475,16 @@ command :finish do |c|
|
|
464
475
|
c.flag [:tag]
|
465
476
|
|
466
477
|
c.desc 'Boolean (AND|OR|NOT) with which to combine multiple tag filters'
|
467
|
-
c.flag [:
|
478
|
+
c.flag [:bool], must_match: /^(and|or|not)$/i, default_value: 'AND'
|
468
479
|
|
469
480
|
c.desc 'Auto-generate finish dates from next entry\'s start time. Automatically generate completion dates 1 minute before next start date. --auto overrides the --date and --back parameters.'
|
470
|
-
c.switch [:auto], :
|
481
|
+
c.switch [:auto], negatable: false, default_value: false
|
471
482
|
|
472
483
|
c.desc 'Archive entries'
|
473
|
-
c.switch [:a, :archive], :
|
484
|
+
c.switch [:a, :archive], negatable: false, default_value: false
|
474
485
|
|
475
486
|
c.desc 'Section'
|
476
|
-
c.flag [:s, :section], :
|
487
|
+
c.flag [:s, :section], default_value: wwid.current_section
|
477
488
|
|
478
489
|
c.action do |global_options,options,args|
|
479
490
|
|
@@ -494,21 +505,17 @@ command :finish do |c|
|
|
494
505
|
end
|
495
506
|
|
496
507
|
if options[:tag].nil?
|
497
|
-
|
508
|
+
tags = []
|
498
509
|
else
|
499
|
-
|
500
|
-
|
501
|
-
options[:tag_bool] = options[:tag_bool].upcase
|
502
|
-
else
|
503
|
-
options[:tag_bool] = 'AND'
|
504
|
-
end
|
510
|
+
tags = options[:tag].split(/ *, */).map {|t| t.strip.sub(/^@/, '') }
|
511
|
+
options[:bool] = options[:bool] =~ /^(and|or|not)$/i ? options[:bool].upcase : 'AND'
|
505
512
|
end
|
506
513
|
|
507
514
|
if args.length > 1
|
508
515
|
raise "Only one argument allowed"
|
509
516
|
elsif args.length == 0 || args[0] =~ /\d+/
|
510
517
|
count = args[0] ? args[0].to_i : 1
|
511
|
-
wwid.tag_last({ tags: ["done"],count: count,section: section,archive: options[:a],sequential: options[:auto],date: options[:date], back: date, tag: options[:tag], tag_bool: options[:
|
518
|
+
wwid.tag_last({ tags: ["done"],count: count,section: section,archive: options[:a],sequential: options[:auto],date: options[:date], back: date, tag: options[:tag], tag_bool: options[:bool] })
|
512
519
|
else
|
513
520
|
raise "Invalid argument (specify number of recent items to mark @done)"
|
514
521
|
end
|
@@ -519,14 +526,24 @@ desc 'Repeat last entry as new entry'
|
|
519
526
|
arg_name 'section'
|
520
527
|
command [:again, :resume] do |c|
|
521
528
|
c.desc 'Section'
|
522
|
-
c.flag [:s, :section], :
|
529
|
+
c.flag [:s, :section], default_value: "All"
|
530
|
+
|
531
|
+
c.desc 'Add new entry to section (default: same section as repeated entry)'
|
532
|
+
c.flag [:in]
|
533
|
+
|
534
|
+
c.desc 'Repeat last entry matching tags. Combine multiple tags with a comma.'
|
535
|
+
c.flag [:tag]
|
536
|
+
|
537
|
+
c.desc 'Boolean used to combine multiple tags'
|
538
|
+
c.flag [:bool], must_match: /^(and|or|not)$/i, default_value: 'ALL'
|
523
539
|
|
524
540
|
c.desc 'Note'
|
525
541
|
c.arg_name 'note_text'
|
526
542
|
c.flag [:n, :note]
|
527
543
|
|
528
544
|
c.action do |global_options, options, args|
|
529
|
-
|
545
|
+
tags = options[:tag].nil? ? [] : options[:tag].split(/ *, */).map {|t| t.sub(/^@/, '').strip }
|
546
|
+
wwid.restart_last({ section: options[:s], note: options[:n], tag: tags, tag_bool: options[:bool], in: options[:in] })
|
530
547
|
end
|
531
548
|
end
|
532
549
|
|
@@ -534,19 +551,19 @@ desc 'Tag last entry'
|
|
534
551
|
arg_name 'tag1 [tag2...]'
|
535
552
|
command :tag do |c|
|
536
553
|
c.desc 'Section'
|
537
|
-
c.flag [:s, :section], :
|
554
|
+
c.flag [:s, :section], default_value: 'All'
|
538
555
|
|
539
556
|
c.desc 'How many recent entries to tag (0 for all)'
|
540
|
-
c.flag [:c, :count], :
|
557
|
+
c.flag [:c, :count], default_value: 1
|
541
558
|
|
542
559
|
c.desc 'Include current date/time with tag'
|
543
|
-
c.switch [:d, :date], :
|
560
|
+
c.switch [:d, :date], negatable: false, default_value: false
|
544
561
|
|
545
562
|
c.desc 'Remove given tag(s)'
|
546
|
-
c.switch [:r, :remove], :
|
563
|
+
c.switch [:r, :remove], negatable: false, default_value: false
|
547
564
|
|
548
565
|
c.desc 'Autotag entries based on autotag configuration in ~/.doingrc'
|
549
|
-
c.switch [:a, :autotag], :
|
566
|
+
c.switch [:a, :autotag], negatable: false, default_value: false
|
550
567
|
|
551
568
|
c.action do |global_options,options,args|
|
552
569
|
if args.length == 0 && !options[:a]
|
@@ -587,7 +604,7 @@ command :tag do |c|
|
|
587
604
|
end
|
588
605
|
end
|
589
606
|
|
590
|
-
wwid.tag_last({:
|
607
|
+
wwid.tag_last({tags: tags, count: count, section: section, date: options[:date], remove: options[:r], autotag: options[:a]})
|
591
608
|
end
|
592
609
|
end
|
593
610
|
end
|
@@ -595,15 +612,15 @@ end
|
|
595
612
|
desc 'Mark last entry as highlighted'
|
596
613
|
command [:mark, :flag] do |c|
|
597
614
|
c.desc 'Section'
|
598
|
-
c.flag [:s, :section], :
|
615
|
+
c.flag [:s, :section], default_value: wwid.current_section
|
599
616
|
|
600
617
|
c.desc 'Remove mark'
|
601
|
-
c.switch [:r, :remove], :
|
618
|
+
c.switch [:r, :remove], negatable: false, default_value: false
|
602
619
|
|
603
620
|
|
604
621
|
c.action do |global_options,options,args|
|
605
622
|
mark = wwid.config['marker_tag'] || "flagged"
|
606
|
-
wwid.tag_last({:
|
623
|
+
wwid.tag_last({tags: [mark], section: options[:s], remove: options[:r]})
|
607
624
|
end
|
608
625
|
end
|
609
626
|
|
@@ -611,17 +628,20 @@ desc 'List all entries'
|
|
611
628
|
long_desc 'The argument can be a section name, @tag(s) or both. "pick" or "choose" as an argument will offer a section menu.'
|
612
629
|
arg_name '[section|@tags]'
|
613
630
|
command :show do |c|
|
631
|
+
c.desc 'Tag filter, combine multiple tags with a comma. Added for compatibility with other commands.'
|
632
|
+
c.flag [:tag]
|
633
|
+
|
614
634
|
c.desc 'Tag boolean (AND,OR,NONE)'
|
615
|
-
c.flag [:b, :bool], :default_value
|
635
|
+
c.flag [:b, :bool], must_match: /^(and|or|not)$/i, default_value: 'OR'
|
616
636
|
|
617
637
|
c.desc 'Max count to show'
|
618
|
-
c.flag [:c, :count], :
|
638
|
+
c.flag [:c, :count], default_value: 0
|
619
639
|
|
620
640
|
c.desc 'Age (oldest/newest)'
|
621
|
-
c.flag [:a, :age], :
|
641
|
+
c.flag [:a, :age], default_value: 'newest'
|
622
642
|
|
623
643
|
c.desc 'Sort order (asc/desc)'
|
624
|
-
c.flag [:s, :sort], :
|
644
|
+
c.flag [:s, :sort], default_value: 'asc'
|
625
645
|
|
626
646
|
c.desc %{
|
627
647
|
Date range to show, or a single day to filter date on.
|
@@ -631,20 +651,20 @@ command :show do |c|
|
|
631
651
|
c.flag [:f, :from]
|
632
652
|
|
633
653
|
c.desc 'Show time intervals on @done tasks'
|
634
|
-
c.switch [:t, :times], :
|
654
|
+
c.switch [:t, :times], default_value: true
|
635
655
|
|
636
656
|
c.desc 'Show intervals with totals at the end of output'
|
637
|
-
c.switch [:totals], :
|
657
|
+
c.switch [:totals], default_value: false, negatable: true
|
638
658
|
|
639
659
|
c.desc 'Sort tags by (name|time)'
|
640
660
|
default = 'time'
|
641
661
|
if wwid.config.has_key?('tag_sort')
|
642
662
|
default = wwid.config['tag_sort']
|
643
663
|
end
|
644
|
-
c.flag [:tag_sort], :
|
664
|
+
c.flag [:tag_sort], default_value: default
|
645
665
|
|
646
666
|
c.desc 'Only show items with recorded time intervals'
|
647
|
-
c.switch [:only_timed], :
|
667
|
+
c.switch [:only_timed], default_value: false, negatable: false
|
648
668
|
|
649
669
|
c.desc 'Output to export format (csv|html|json)'
|
650
670
|
c.flag [:o, :output]
|
@@ -681,6 +701,8 @@ command :show do |c|
|
|
681
701
|
section = wwid.current_section
|
682
702
|
end
|
683
703
|
|
704
|
+
tags.concat(options[:tag].split(/ *, */).map {|t| t.sub(/^@/, '').strip }) if options[:tag]
|
705
|
+
|
684
706
|
unless tags.empty?
|
685
707
|
tag_filter = {
|
686
708
|
'tags' => tags,
|
@@ -699,14 +721,14 @@ command :show do |c|
|
|
699
721
|
finish = false
|
700
722
|
end
|
701
723
|
exit_now! "Unrecognized date string" unless start
|
702
|
-
dates = [start,finish]
|
724
|
+
dates = [start, finish]
|
703
725
|
end
|
704
726
|
|
705
727
|
options[:t] = true if options[:totals]
|
706
728
|
|
707
729
|
options[:sort_tags] = options[:tag_sort] =~ /^n/i
|
708
730
|
|
709
|
-
puts wwid.list_section({:
|
731
|
+
puts wwid.list_section({section: section, date_filter: dates, count: options[:c].to_i, tag_filter: tag_filter, age: options[:a], order: options[:s], output: options[:output], times: options[:t], totals: options[:totals], sort_tags: options[:sort_tags], highlight: true, only_timed: options[:only_timed]})
|
710
732
|
|
711
733
|
end
|
712
734
|
end
|
@@ -721,26 +743,26 @@ EODESC
|
|
721
743
|
arg_name 'search_pattern'
|
722
744
|
command [:grep, :search] do |c|
|
723
745
|
c.desc 'Section'
|
724
|
-
c.flag [:s, :section], :
|
746
|
+
c.flag [:s, :section], default_value: "All"
|
725
747
|
|
726
748
|
c.desc 'Output to export format (csv|html|json)'
|
727
749
|
c.flag [:o, :output]
|
728
750
|
|
729
751
|
c.desc 'Show time intervals on @done tasks'
|
730
|
-
c.switch [:t, :times], :
|
752
|
+
c.switch [:t, :times], default_value: true
|
731
753
|
|
732
754
|
c.desc 'Show intervals with totals at the end of output'
|
733
|
-
c.switch [:totals], :
|
755
|
+
c.switch [:totals], default_value: false, negatable: true
|
734
756
|
|
735
757
|
c.desc 'Sort tags by (name|time)'
|
736
758
|
default = 'time'
|
737
759
|
if wwid.config.has_key?('tag_sort')
|
738
760
|
default = wwid.config['tag_sort']
|
739
761
|
end
|
740
|
-
c.flag [:tag_sort], :
|
762
|
+
c.flag [:tag_sort], default_value: default
|
741
763
|
|
742
764
|
c.desc 'Only show items with recorded time intervals'
|
743
|
-
c.switch [:only_timed], :
|
765
|
+
c.switch [:only_timed], default_value: false, negatable: false
|
744
766
|
|
745
767
|
c.action do |global_options,options,args|
|
746
768
|
|
@@ -749,7 +771,7 @@ command [:grep, :search] do |c|
|
|
749
771
|
options[:t] = true if options[:totals]
|
750
772
|
options[:sort_tags] = options[:tag_sort] =~ /^n/i
|
751
773
|
|
752
|
-
puts wwid.list_section({:
|
774
|
+
puts wwid.list_section({search: args.join(' '), section: section, output: options[:output], times: options[:t], highlight: true, totals: options[:totals], only_timed: options[:only_timed], sort_tags: options[:sort_tags]})
|
753
775
|
|
754
776
|
end
|
755
777
|
end
|
@@ -759,20 +781,20 @@ default_value 10
|
|
759
781
|
arg_name 'count'
|
760
782
|
command :recent do |c|
|
761
783
|
c.desc 'Section'
|
762
|
-
c.flag [:s, :section], :
|
784
|
+
c.flag [:s, :section], default_value: "All"
|
763
785
|
|
764
786
|
c.desc 'Show time intervals on @done tasks'
|
765
|
-
c.switch [:t, :times], :
|
787
|
+
c.switch [:t, :times], default_value: true
|
766
788
|
|
767
789
|
c.desc 'Show intervals with totals at the end of output'
|
768
|
-
c.switch [:totals], :
|
790
|
+
c.switch [:totals], default_value: false, negatable: true
|
769
791
|
|
770
792
|
c.desc 'Sort tags by (name|time)'
|
771
793
|
default = 'time'
|
772
794
|
if wwid.config.has_key?('tag_sort')
|
773
795
|
default = wwid.config['tag_sort']
|
774
796
|
end
|
775
|
-
c.flag [:tag_sort], :
|
797
|
+
c.flag [:tag_sort], default_value: default
|
776
798
|
|
777
799
|
c.action do |global_options,options,args|
|
778
800
|
|
@@ -787,7 +809,7 @@ command :recent do |c|
|
|
787
809
|
options[:t] = true if options[:totals]
|
788
810
|
options[:sort_tags] = options[:tag_sort] =~ /^n/i
|
789
811
|
|
790
|
-
puts wwid.recent(count,section.cap_first,{ :
|
812
|
+
puts wwid.recent(count,section.cap_first,{ times: options[:t], totals: options[:totals], sort_tags: options[:sort_tags] })
|
791
813
|
|
792
814
|
end
|
793
815
|
end
|
@@ -797,20 +819,20 @@ desc 'List entries from today'
|
|
797
819
|
command :today do |c|
|
798
820
|
c.desc 'Specify a section'
|
799
821
|
c.arg_name 'section_name'
|
800
|
-
c.flag [:s, :section], :
|
822
|
+
c.flag [:s, :section], default_value: 'All'
|
801
823
|
|
802
824
|
c.desc 'Show time intervals on @done tasks'
|
803
|
-
c.switch [:t, :times], :
|
825
|
+
c.switch [:t, :times], default_value: true
|
804
826
|
|
805
827
|
c.desc 'Show time totals at the end of output'
|
806
|
-
c.switch [:totals], :
|
828
|
+
c.switch [:totals], default_value: false, negatable: true
|
807
829
|
|
808
830
|
c.desc 'Sort tags by (name|time)'
|
809
831
|
default = 'time'
|
810
832
|
if wwid.config.has_key?('tag_sort')
|
811
833
|
default = wwid.config['tag_sort']
|
812
834
|
end
|
813
|
-
c.flag [:tag_sort], :
|
835
|
+
c.flag [:tag_sort], default_value: default
|
814
836
|
|
815
837
|
c.desc 'Output to export format (csv|html|json)'
|
816
838
|
c.flag [:o, :output]
|
@@ -820,7 +842,7 @@ command :today do |c|
|
|
820
842
|
options[:t] = true if options[:totals]
|
821
843
|
options[:sort_tags] = options[:tag_sort] =~ /^n/i
|
822
844
|
|
823
|
-
puts wwid.today(options[:t],options[:output],{:
|
845
|
+
puts wwid.today(options[:t], options[:output], {totals: options[:totals], section: options[:s], sort_tags: options[:sort_tags]}).chomp
|
824
846
|
|
825
847
|
end
|
826
848
|
end
|
@@ -831,25 +853,26 @@ arg_name 'date_string'
|
|
831
853
|
command :on do |c|
|
832
854
|
c.desc 'Section'
|
833
855
|
c.arg_name 'section_name'
|
834
|
-
c.flag [:s, :section], :
|
856
|
+
c.flag [:s, :section], default_value: 'All'
|
835
857
|
|
836
858
|
c.desc 'Show time intervals on @done tasks'
|
837
|
-
c.switch [:t, :times], :
|
859
|
+
c.switch [:t, :times], default_value: true
|
838
860
|
|
839
861
|
c.desc 'Show time totals at the end of output'
|
840
|
-
c.switch [:totals], :
|
862
|
+
c.switch [:totals], default_value: false, negatable: true
|
841
863
|
|
842
864
|
c.desc 'Sort tags by (name|time)'
|
843
865
|
default = 'time'
|
844
866
|
if wwid.config.has_key?('tag_sort')
|
845
867
|
default = wwid.config['tag_sort']
|
846
868
|
end
|
847
|
-
c.flag [:tag_sort], :
|
869
|
+
c.flag [:tag_sort], default_value: default
|
848
870
|
|
849
871
|
c.desc 'Output to export format (csv|html|json)'
|
850
872
|
c.flag [:o, :output]
|
851
873
|
|
852
874
|
c.action do |global_options,options,args|
|
875
|
+
exit_now! "Missing date argument" if args.empty?
|
853
876
|
|
854
877
|
date_string = args.join(" ")
|
855
878
|
|
@@ -871,7 +894,7 @@ command :on do |c|
|
|
871
894
|
options[:t] = true if options[:totals]
|
872
895
|
options[:sort_tags] = options[:tag_sort] =~ /^n/i
|
873
896
|
|
874
|
-
puts wwid.list_date([start, finish], options[:s], options[:t], options[:output], {:
|
897
|
+
puts wwid.list_date([start, finish], options[:s], options[:t], options[:output], {totals: options[:totals], sort_tags: options[:sort_tags]}).chomp
|
875
898
|
|
876
899
|
end
|
877
900
|
end
|
@@ -880,27 +903,27 @@ desc 'List entries from yesterday'
|
|
880
903
|
command :yesterday do |c|
|
881
904
|
c.desc 'Specify a section'
|
882
905
|
c.arg_name 'section_name'
|
883
|
-
c.flag [:s, :section], :
|
906
|
+
c.flag [:s, :section], default_value: 'All'
|
884
907
|
|
885
908
|
c.desc 'Output to export format (csv|html|json)'
|
886
909
|
c.flag [:o, :output]
|
887
910
|
|
888
911
|
c.desc 'Show time intervals on @done tasks'
|
889
|
-
c.switch [:t, :times], :
|
912
|
+
c.switch [:t, :times], default_value: true
|
890
913
|
|
891
914
|
c.desc 'Show time totals at the end of output'
|
892
|
-
c.switch [:totals], :
|
915
|
+
c.switch [:totals], default_value: false, negatable: true
|
893
916
|
|
894
917
|
c.desc 'Sort tags by (name|time)'
|
895
918
|
default = 'time'
|
896
919
|
if wwid.config.has_key?('tag_sort')
|
897
920
|
default = wwid.config['tag_sort']
|
898
921
|
end
|
899
|
-
c.flag [:tag_sort], :
|
922
|
+
c.flag [:tag_sort], default_value: default
|
900
923
|
|
901
924
|
c.action do |global_options, options,args|
|
902
925
|
options[:sort_tags] = options[:tag_sort] =~ /^n/i
|
903
|
-
puts wwid.yesterday(options[:s],options[:t],options[:o],{:
|
926
|
+
puts wwid.yesterday(options[:s], options[:t], options[:o],{ totals: options[:totals], sort_tags: options[:sort_tags] }).chomp
|
904
927
|
|
905
928
|
end
|
906
929
|
end
|
@@ -918,7 +941,7 @@ end
|
|
918
941
|
desc 'List sections'
|
919
942
|
command :sections do |c|
|
920
943
|
c.desc 'List in single column'
|
921
|
-
c.switch [:c, :column], :
|
944
|
+
c.switch [:c, :column], default_value: false
|
922
945
|
|
923
946
|
c.action do |global_options,options,args|
|
924
947
|
joiner = options[:c] ? "\n" : "\t"
|
@@ -930,7 +953,7 @@ desc 'Select a section to display from a menu'
|
|
930
953
|
command :choose do |c|
|
931
954
|
c.action do |global_options,options,args|
|
932
955
|
section = wwid.choose_section
|
933
|
-
puts wwid.list_section({:
|
956
|
+
puts wwid.list_section({ section: section.cap_first, count: 0 })
|
934
957
|
end
|
935
958
|
end
|
936
959
|
|
@@ -972,26 +995,29 @@ command :view do |c|
|
|
972
995
|
c.flag [:s, :section]
|
973
996
|
|
974
997
|
c.desc 'Count to display (override view settings)'
|
975
|
-
c.flag [:c, :count], :
|
998
|
+
c.flag [:c, :count], must_match: /^\d+$/, type: Integer
|
976
999
|
|
977
1000
|
c.desc 'Output to export format (csv|html|json)'
|
978
1001
|
c.flag [:o, :output]
|
979
1002
|
|
980
1003
|
c.desc 'Show time intervals on @done tasks'
|
981
|
-
c.switch [:t, :times], :
|
1004
|
+
c.switch [:t, :times], default_value: true
|
982
1005
|
|
983
1006
|
c.desc 'Show intervals with totals at the end of output'
|
984
|
-
c.switch [:totals], :
|
1007
|
+
c.switch [:totals], default_value: false, negatable: true
|
1008
|
+
|
1009
|
+
c.desc 'Include colors in output'
|
1010
|
+
c.switch [:color], default_value: true, negatable: true
|
985
1011
|
|
986
1012
|
c.desc 'Sort tags by (name|time)'
|
987
1013
|
default = 'time'
|
988
1014
|
if wwid.config.has_key?('tag_sort')
|
989
1015
|
default = wwid.config['tag_sort']
|
990
1016
|
end
|
991
|
-
c.flag [:tag_sort], :
|
1017
|
+
c.flag [:tag_sort], default_value: default
|
992
1018
|
|
993
1019
|
c.desc 'Only show items with recorded time intervals'
|
994
|
-
c.switch [:only_timed], :
|
1020
|
+
c.switch [:only_timed], default_value: false, negatable: true
|
995
1021
|
|
996
1022
|
c.action do |global_options,options,args|
|
997
1023
|
if args.empty?
|
@@ -1018,7 +1044,7 @@ command :view do |c|
|
|
1018
1044
|
tag_filter = false
|
1019
1045
|
if view.has_key?('tags')
|
1020
1046
|
unless view['tags'].nil? || view['tags'].empty?
|
1021
|
-
tag_filter = {'tags' => [], 'bool' =>
|
1047
|
+
tag_filter = {'tags' => [], 'bool' => 'OR'}
|
1022
1048
|
if view['tags'].class == Array
|
1023
1049
|
tag_filter['tags'] = view['tags'].map{|tag| tag.strip }
|
1024
1050
|
else
|
@@ -1039,7 +1065,7 @@ command :view do |c|
|
|
1039
1065
|
options[:output].downcase! if options[:output]
|
1040
1066
|
options[:sort_tags] = options[:tag_sort] =~ /^n/i
|
1041
1067
|
|
1042
|
-
puts wwid.list_section({:
|
1068
|
+
puts wwid.list_section({section: section, count: count, template: template, format: format, order: order, tag_filter: tag_filter, output: options[:o], tags_color: tags_color, times: options[:t], highlight: options[:color], totals: options[:totals], only_timed: only_timed, sort_tags: options[:sort_tags] })
|
1043
1069
|
else
|
1044
1070
|
if title.class == FalseClass
|
1045
1071
|
exit_now! "Cancelled"
|
@@ -1053,7 +1079,7 @@ end
|
|
1053
1079
|
desc 'List available custom views'
|
1054
1080
|
command :views do |c|
|
1055
1081
|
c.desc 'List in single column'
|
1056
|
-
c.switch [:c, :column], :
|
1082
|
+
c.switch [:c, :column], default_value: false
|
1057
1083
|
|
1058
1084
|
c.action do |global_options,options,args|
|
1059
1085
|
joiner = options[:c] ? "\n" : "\t"
|
@@ -1061,18 +1087,21 @@ command :views do |c|
|
|
1061
1087
|
end
|
1062
1088
|
end
|
1063
1089
|
|
1064
|
-
desc 'Move entries
|
1090
|
+
desc 'Move entries between sections'
|
1065
1091
|
arg_name 'section'
|
1066
1092
|
default_value wwid.current_section
|
1067
1093
|
command :archive do |c|
|
1068
1094
|
c.desc 'Count to keep (ignored if archiving by tag)'
|
1069
|
-
c.flag [:k, :keep], :
|
1095
|
+
c.flag [:k, :keep], default_value: 5, must_match: /^\d+$/, type: Integer
|
1070
1096
|
|
1071
1097
|
c.desc 'Move entries to'
|
1072
|
-
c.flag [:t, :to], :
|
1098
|
+
c.flag [:t, :to], default_value: 'Archive'
|
1099
|
+
|
1100
|
+
c.desc 'Tag filter, combine multiple tags with a comma. Added for compatibility with other commands.'
|
1101
|
+
c.flag [:tag]
|
1073
1102
|
|
1074
1103
|
c.desc 'Tag boolean'
|
1075
|
-
c.flag [:b, :bool], :default_value
|
1104
|
+
c.flag [:b, :bool], must_match: /(and|or|not)/i, default_value: 'AND'
|
1076
1105
|
|
1077
1106
|
c.action do |global_options,options,args|
|
1078
1107
|
if args.length > 0
|
@@ -1081,13 +1110,16 @@ command :archive do |c|
|
|
1081
1110
|
tags = args.map {|t| t.sub(/^@/,'').strip }
|
1082
1111
|
else
|
1083
1112
|
section = args[0].cap_first
|
1084
|
-
tags = args.length > 1 ? args[1..-1].map {|t| t.sub(/^@/,'').strip } : nil
|
1113
|
+
tags = args.length > 1 ? args[1..-1].map {|t| t.sub(/^@/, '').strip } : nil
|
1085
1114
|
end
|
1086
1115
|
else
|
1087
1116
|
section = wwid.current_section
|
1088
|
-
tags =
|
1117
|
+
tags = []
|
1089
1118
|
end
|
1090
|
-
|
1119
|
+
|
1120
|
+
tags.concat(options[:tag].split(/ *, */).map {|t| t.sub(/^@/, '').strip }) if options[:tag]
|
1121
|
+
|
1122
|
+
wwid.archive(section, options[:k], options[:t], tags, options[:b])
|
1091
1123
|
end
|
1092
1124
|
end
|
1093
1125
|
|
@@ -1103,7 +1135,7 @@ if `uname` =~ /Darwin/
|
|
1103
1135
|
c.flag [:b]
|
1104
1136
|
end
|
1105
1137
|
c.desc 'open with $EDITOR'
|
1106
|
-
c.switch [:e], :
|
1138
|
+
c.switch [:e], negatable: false
|
1107
1139
|
|
1108
1140
|
c.action do |global_options,options,args|
|
1109
1141
|
params = options.dup
|
@@ -1140,7 +1172,7 @@ end
|
|
1140
1172
|
desc 'Edit the configuration file'
|
1141
1173
|
command :config do |c|
|
1142
1174
|
c.desc 'Editor to use'
|
1143
|
-
c.flag [:e, :editor], :
|
1175
|
+
c.flag [:e, :editor], default_value: nil
|
1144
1176
|
|
1145
1177
|
if `uname` =~ /Darwins/
|
1146
1178
|
c.desc 'Application to use'
|
@@ -1178,7 +1210,7 @@ end
|
|
1178
1210
|
desc 'Undo the last change to the doing_file'
|
1179
1211
|
command :undo do |c|
|
1180
1212
|
c.desc 'Specify alternate doing file'
|
1181
|
-
c.flag [:f, :file], :
|
1213
|
+
c.flag [:f, :file], default_value: wwid.doing_file
|
1182
1214
|
|
1183
1215
|
c.action do |global_options,options,args|
|
1184
1216
|
file = options[:f] || wwid.doing_file
|
@@ -1190,7 +1222,7 @@ end
|
|
1190
1222
|
pre do |global,command,options,args|
|
1191
1223
|
if global[:config_file]
|
1192
1224
|
wwid.config_file = global[:config_file]
|
1193
|
-
wwid.configure({:
|
1225
|
+
wwid.configure({ignore_local: true})
|
1194
1226
|
# wwid.results.push("Override config file #{wwid.config_file}")
|
1195
1227
|
end
|
1196
1228
|
|
data/lib/doing/version.rb
CHANGED
data/lib/doing/wwid.rb
CHANGED
@@ -3,6 +3,44 @@
|
|
3
3
|
require 'deep_merge'
|
4
4
|
require 'open3'
|
5
5
|
|
6
|
+
##
|
7
|
+
## @brief Hash helpers
|
8
|
+
##
|
9
|
+
class Hash
|
10
|
+
def has_tags?(tags, bool = 'AND')
|
11
|
+
item = self
|
12
|
+
case bool
|
13
|
+
when 'AND'
|
14
|
+
result = true
|
15
|
+
tags.each do |tag|
|
16
|
+
unless item['title'] =~ /@#{tag}/
|
17
|
+
result = false
|
18
|
+
break
|
19
|
+
end
|
20
|
+
end
|
21
|
+
result
|
22
|
+
when 'NOT'
|
23
|
+
result = true
|
24
|
+
tags.each do |tag|
|
25
|
+
if item['title'] =~ /@#{tag}/
|
26
|
+
result = false
|
27
|
+
break
|
28
|
+
end
|
29
|
+
end
|
30
|
+
result
|
31
|
+
else
|
32
|
+
result = false
|
33
|
+
tags.each do |tag|
|
34
|
+
if item['title'] =~ /@#{tag}/
|
35
|
+
result = true
|
36
|
+
break
|
37
|
+
end
|
38
|
+
end
|
39
|
+
result
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
6
44
|
##
|
7
45
|
## @brief String helpers
|
8
46
|
##
|
@@ -637,6 +675,8 @@ class WWID
|
|
637
675
|
def restart_last(opt = {})
|
638
676
|
opt[:section] ||= 'all'
|
639
677
|
opt[:note] ||= []
|
678
|
+
opt[:tag] ||= []
|
679
|
+
opt[:tag_bool] ||= 'AND'
|
640
680
|
|
641
681
|
last = last_entry(opt)
|
642
682
|
if last.nil?
|
@@ -645,8 +685,9 @@ class WWID
|
|
645
685
|
end
|
646
686
|
# Remove @done tag
|
647
687
|
title = last['title'].sub(/\s*@done(\(.*?\))?/, '').chomp
|
688
|
+
section = opt[:in].nil? ? last['section'] : guess_section(opt[:in])
|
648
689
|
@auto_tag = false
|
649
|
-
add_item(title,
|
690
|
+
add_item(title, section, { note: opt[:note], back: opt[:date], timed: true })
|
650
691
|
write(@doing_file)
|
651
692
|
end
|
652
693
|
|
@@ -656,6 +697,8 @@ class WWID
|
|
656
697
|
## @param opt (Hash) Additional Options
|
657
698
|
##
|
658
699
|
def last_entry(opt = {})
|
700
|
+
opt[:tag] ||= []
|
701
|
+
opt[:tag_bool] ||= 'AND'
|
659
702
|
opt[:section] ||= @current_section
|
660
703
|
|
661
704
|
sec_arr = []
|
@@ -682,6 +725,8 @@ class WWID
|
|
682
725
|
all_items.concat(@content[section]['items'].dup) if @content.key?(section)
|
683
726
|
end
|
684
727
|
|
728
|
+
all_items.select! { |item| item.has_tags?(opt[:tag], opt[:tag_bool]) } if !opt[:tag].nil? && opt[:tag].length.positive?
|
729
|
+
|
685
730
|
all_items.max_by { |item| item['date'] }
|
686
731
|
end
|
687
732
|
|
@@ -735,39 +780,7 @@ class WWID
|
|
735
780
|
items.map! do |item|
|
736
781
|
break if index == count
|
737
782
|
|
738
|
-
tag_match =
|
739
|
-
case opt[:tag_bool]
|
740
|
-
when 'AND'
|
741
|
-
result = true
|
742
|
-
opt[:tag].each do |tag|
|
743
|
-
unless item['title'] =~ /@#{tag}/
|
744
|
-
result = false
|
745
|
-
break
|
746
|
-
end
|
747
|
-
end
|
748
|
-
result
|
749
|
-
when 'NOT'
|
750
|
-
result = true
|
751
|
-
opt[:tag].each do |tag|
|
752
|
-
if item['title'] =~ /@#{tag}/
|
753
|
-
result = false
|
754
|
-
break
|
755
|
-
end
|
756
|
-
end
|
757
|
-
result
|
758
|
-
else
|
759
|
-
result = false
|
760
|
-
opt[:tag].each do |tag|
|
761
|
-
if item['title'] =~ /@#{tag}/
|
762
|
-
result = true
|
763
|
-
break
|
764
|
-
end
|
765
|
-
end
|
766
|
-
result
|
767
|
-
end
|
768
|
-
else
|
769
|
-
true
|
770
|
-
end
|
783
|
+
tag_match = !opt[:tag].nil? && opt[:tag].length.positive? ? item.has_tags?(opt[:tag], opt[:tag_bool]) : true
|
771
784
|
|
772
785
|
if tag_match
|
773
786
|
if opt[:autotag]
|