doing 1.0.66 → 1.0.70
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 +2 -3
- data/bin/doing +26 -6
- data/lib/doing/helpers.rb +121 -0
- data/lib/doing/version.rb +1 -1
- data/lib/doing/wwid.rb +9 -7
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 10dc5d92f3e7079a9525d39c47fe0f69ef22f64ae5400cd9da1925f9b0fc1964
|
4
|
+
data.tar.gz: ec08df722ce07bbfcee808bfd4bd9eabe5470ef173f5d11e47fc52356b2c2c95
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c56a9a328d2ed31e70633333be5f7666d9586154fba7cc59f34116f1a972156fb4dd7d087e59452bf860167e618dad815da8a113fe0e4cf9f12faafa98d68d72
|
7
|
+
data.tar.gz: 3152021d8017af18e4046736f1f994bd1821f95bece924ca9ad78de997ad3473cbfd411389ede1dfe6313a1c4fde3debdc9907f3f2da899b1bab823a02a932e7
|
data/README.md
CHANGED
@@ -25,11 +25,9 @@ While I'm working, I have hourly reminders to record what I'm working on, and I
|
|
25
25
|
|
26
26
|
If there's something I want to look at later but doesn't need to be added to a task list or tracker, I can type `doing later check out the pinboard bookmarks from macdrifter`. When I get back to my computer --- or just need a refresher after a distraction --- I can type `doing last` to see what the last thing on my plate was. I can also type `doing recent` (or just `doing`) to get a list of the last few entries. `doing today` gives me everything since midnight for the current day, making it easy to see what I've accomplished over a sleepless night.
|
27
27
|
|
28
|
-
_Side note:_ I actually use the library behind this utility as part of another script that mirrors entries in [Day One](http://dayoneapp.com) that have the tag `wwid`. I can use the hourly writing reminders and enter my stuff in the quick entry popup. Someday I'll get around to cleaning that up and putting it out there.
|
29
|
-
|
30
28
|
## Installation
|
31
29
|
|
32
|
-
The current version of `doing` is <!--VER-->1.0.
|
30
|
+
The current version of `doing` is <!--VER-->1.0.69<!--END VER-->.
|
33
31
|
|
34
32
|
$ [sudo] gem install doing
|
35
33
|
|
@@ -464,6 +462,7 @@ You can also include a `--no-date` switch to add `@done` without a finish date,
|
|
464
462
|
|
465
463
|
By default `doing finish` works on a single entry, the last entry or the most recent entry matching a `--tag` or `--search` query. Specifying `doing finish 10` would finish any unfinished entries within the last 10 entries. In the case of `--tag` or `--search` queries, the count serves as the maximum number of matches doing will act on, sorted in reverse date order (most recent first). A count of 0 will disable the limit entirely, acting on all matching entries.
|
466
464
|
|
465
|
+
Both `finish` and `cancel` accept `--unfinished` as an argument. This causes them to act on the last entry not already marked @done, no matter how far back it's dated or how many @done entries come after it. You can use `doing finish --unfinished X -s SECTION` to finish the last X unfinished entries in SECTION.
|
467
466
|
|
468
467
|
##### Tagging and Autotagging
|
469
468
|
|
data/bin/doing
CHANGED
@@ -368,7 +368,7 @@ command %i[done did] do |c|
|
|
368
368
|
|
369
369
|
date = options[:took] ? finish_date - took : finish_date
|
370
370
|
elsif options[:took]
|
371
|
-
finish_date =
|
371
|
+
finish_date = date + took
|
372
372
|
elsif options[:back]
|
373
373
|
finish_date = date
|
374
374
|
else
|
@@ -446,6 +446,9 @@ command :cancel do |c|
|
|
446
446
|
c.arg_name 'BOOLEAN'
|
447
447
|
c.flag [:bool], must_match: /(?:and|all|any|or|not|none)/i, default_value: 'AND'
|
448
448
|
|
449
|
+
c.desc 'Cancel last entry (or entries) not already marked @done'
|
450
|
+
c.switch %i[u unfinished], negatable: false, default_value: false
|
451
|
+
|
449
452
|
c.action do |_global_options, options, args|
|
450
453
|
section = wwid.guess_section(options[:s]) || options[:s].cap_first
|
451
454
|
|
@@ -478,7 +481,8 @@ command :cancel do |c|
|
|
478
481
|
sequential: false,
|
479
482
|
tag: tags,
|
480
483
|
tag_bool: options[:bool],
|
481
|
-
tags: ['done']
|
484
|
+
tags: ['done'],
|
485
|
+
unfinished: options[:unfinished]
|
482
486
|
}
|
483
487
|
wwid.tag_last(opts)
|
484
488
|
end
|
@@ -512,6 +516,9 @@ command :finish do |c|
|
|
512
516
|
c.arg_name 'BOOLEAN'
|
513
517
|
c.flag [:bool], must_match: /(?:and|all|any|or|not|none)/i, default_value: 'AND'
|
514
518
|
|
519
|
+
c.desc 'Finish last entry (or entries) not already marked @done'
|
520
|
+
c.switch %i[u unfinished], negatable: false, default_value: false
|
521
|
+
|
515
522
|
c.desc %(Auto-generate finish dates from next entry's start time.
|
516
523
|
Automatically generate completion dates 1 minute before next start date.
|
517
524
|
--auto overrides the --date and --back parameters.)
|
@@ -574,7 +581,8 @@ command :finish do |c|
|
|
574
581
|
sequential: options[:auto],
|
575
582
|
tag: tags,
|
576
583
|
tag_bool: options[:bool],
|
577
|
-
tags: ['done']
|
584
|
+
tags: ['done'],
|
585
|
+
unfinished: options[:unfinished]
|
578
586
|
}
|
579
587
|
wwid.tag_last(opts)
|
580
588
|
end
|
@@ -648,6 +656,9 @@ command :tag do |c|
|
|
648
656
|
c.desc 'Remove given tag(s)'
|
649
657
|
c.switch %i[r remove], negatable: false, default_value: false
|
650
658
|
|
659
|
+
c.desc 'Tag last entry (or entries) not marked @done'
|
660
|
+
c.switch %i[u unfinished], negatable: false, default_value: false
|
661
|
+
|
651
662
|
c.desc 'Autotag entries based on autotag configuration in ~/.doingrc'
|
652
663
|
c.switch %i[a autotag], negatable: false, default_value: false
|
653
664
|
|
@@ -691,7 +702,8 @@ command :tag do |c|
|
|
691
702
|
date: options[:date],
|
692
703
|
remove: options[:r],
|
693
704
|
section: section,
|
694
|
-
tags: tags
|
705
|
+
tags: tags,
|
706
|
+
unfinished: options[:unfinished]
|
695
707
|
}
|
696
708
|
wwid.tag_last(opts)
|
697
709
|
end
|
@@ -706,9 +718,17 @@ command [:mark, :flag] do |c|
|
|
706
718
|
c.desc 'Remove mark'
|
707
719
|
c.switch %i[r remove], negatable: false, default_value: false
|
708
720
|
|
721
|
+
c.desc 'Mark last entry not marked @done'
|
722
|
+
c.switch %i[u unfinished], negatable: false, default_value: false
|
723
|
+
|
709
724
|
c.action do |_global_options, options, _args|
|
710
725
|
mark = wwid.config['marker_tag'] || 'flagged'
|
711
|
-
wwid.tag_last({
|
726
|
+
wwid.tag_last({
|
727
|
+
remove: options[:r],
|
728
|
+
section: options[:s],
|
729
|
+
tags: [mark],
|
730
|
+
unfinished: options[:unfinished]
|
731
|
+
})
|
712
732
|
end
|
713
733
|
end
|
714
734
|
|
@@ -737,7 +757,7 @@ command :show do |c|
|
|
737
757
|
|
738
758
|
c.desc 'Sort order (asc/desc)'
|
739
759
|
c.arg_name 'ORDER'
|
740
|
-
c.flag %i[s sort], must_match: /^
|
760
|
+
c.flag %i[s sort], must_match: /^[ad].*/i, default_value: 'ASC'
|
741
761
|
|
742
762
|
c.desc %(
|
743
763
|
Date range to show, or a single day to filter date on.
|
@@ -0,0 +1,121 @@
|
|
1
|
+
##
|
2
|
+
## @brief Hash helpers
|
3
|
+
##
|
4
|
+
class ::Hash
|
5
|
+
def has_tags?(tags, bool = :and)
|
6
|
+
tags = tags.split(/ *, */) if tags.is_a? String
|
7
|
+
bool = bool.normalize_bool if bool.is_a? String
|
8
|
+
item = self
|
9
|
+
tags.map! {|t| t.strip.sub(/^@/, '')}
|
10
|
+
case bool
|
11
|
+
when :and
|
12
|
+
result = true
|
13
|
+
tags.each do |tag|
|
14
|
+
unless item['title'] =~ /@#{tag}/
|
15
|
+
result = false
|
16
|
+
break
|
17
|
+
end
|
18
|
+
end
|
19
|
+
result
|
20
|
+
when :not
|
21
|
+
result = true
|
22
|
+
tags.each do |tag|
|
23
|
+
if item['title'] =~ /@#{tag}/
|
24
|
+
result = false
|
25
|
+
break
|
26
|
+
end
|
27
|
+
end
|
28
|
+
result
|
29
|
+
else
|
30
|
+
result = false
|
31
|
+
tags.each do |tag|
|
32
|
+
if item['title'] =~ /@#{tag}/
|
33
|
+
result = true
|
34
|
+
break
|
35
|
+
end
|
36
|
+
end
|
37
|
+
result
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def matches_search?(search)
|
42
|
+
item = self
|
43
|
+
text = item['note'] ? item['title'] + item['note'].join(' ') : item['title']
|
44
|
+
pattern = if search.strip =~ %r{^/.*?/$}
|
45
|
+
search.sub(%r{/(.*?)/}, '\1')
|
46
|
+
else
|
47
|
+
search.split('').join('.{0,3}')
|
48
|
+
end
|
49
|
+
text =~ /#{pattern}/i ? true : false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
## @brief String helpers
|
55
|
+
##
|
56
|
+
class ::String
|
57
|
+
def cap_first
|
58
|
+
sub(/^\w/) do |m|
|
59
|
+
m.upcase
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
##
|
65
|
+
## @brief Convert a boolean string to a symbol
|
66
|
+
##
|
67
|
+
## @return Symbol :and, :or, or :not
|
68
|
+
##
|
69
|
+
def normalize_bool!
|
70
|
+
replace normalize_bool
|
71
|
+
end
|
72
|
+
|
73
|
+
def normalize_bool(default = :and)
|
74
|
+
case self
|
75
|
+
when /(and|all)/i
|
76
|
+
:and
|
77
|
+
when /(any|or)/i
|
78
|
+
:or
|
79
|
+
when /(not|none)/i
|
80
|
+
:not
|
81
|
+
else
|
82
|
+
default.is_a?(Symbol) ? default : default.normalize_bool
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
##
|
88
|
+
## @brief Turn raw urls into HTML links
|
89
|
+
##
|
90
|
+
## @param opt (Hash) Additional Options
|
91
|
+
##
|
92
|
+
def link_urls(opt = {})
|
93
|
+
opt[:format] ||= :html
|
94
|
+
if opt[:format] == :html
|
95
|
+
gsub(%r{(?mi)((http|https)://)?([\w\-_]+(\.[\w\-_]+)+)([\w\-.,@?^=%&:/~+#]*[\w\-@^=%&/~+#])?}) do |_match|
|
96
|
+
m = Regexp.last_match
|
97
|
+
proto = m[1].nil? ? 'http://' : ''
|
98
|
+
%(<a href="#{proto}#{m[0]}" title="Link to #{m[0]}">[#{m[3]}]</a>)
|
99
|
+
end.gsub(/<(\w+:.*?)>/) do |match|
|
100
|
+
m = Regexp.last_match
|
101
|
+
if m[1] =~ /<a href/
|
102
|
+
match
|
103
|
+
else
|
104
|
+
%(<a href="#{m[1]}" title="Link to #{m[1]}">[link]</a>)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
else
|
108
|
+
self
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
class ::Symbol
|
114
|
+
def normalize_bool!
|
115
|
+
replace normalize_bool
|
116
|
+
end
|
117
|
+
|
118
|
+
def normalize_bool
|
119
|
+
to_s.normalize_bool
|
120
|
+
end
|
121
|
+
end
|
data/lib/doing/version.rb
CHANGED
data/lib/doing/wwid.rb
CHANGED
@@ -781,6 +781,7 @@ class WWID
|
|
781
781
|
opt[:autotag] ||= false
|
782
782
|
opt[:back] ||= false
|
783
783
|
opt[:took] ||= nil
|
784
|
+
opt[:unfinished] ||= false
|
784
785
|
|
785
786
|
sec_arr = []
|
786
787
|
|
@@ -816,10 +817,11 @@ class WWID
|
|
816
817
|
items.map! do |item|
|
817
818
|
break if idx == count
|
818
819
|
|
820
|
+
finished = opt[:unfinished] && item.has_tags?('done', :and)
|
819
821
|
tag_match = opt[:tag].nil? || opt[:tag].empty? ? true : item.has_tags?(opt[:tag], opt[:tag_bool])
|
820
822
|
search_match = opt[:search].nil? || opt[:search].empty? ? true : item.matches_search?(opt[:search])
|
821
823
|
|
822
|
-
if tag_match && search_match
|
824
|
+
if tag_match && search_match && !finished
|
823
825
|
if opt[:autotag]
|
824
826
|
new_title = autotag(item['title']) if @auto_tag
|
825
827
|
if new_title == item['title']
|
@@ -832,12 +834,6 @@ class WWID
|
|
832
834
|
if opt[:sequential]
|
833
835
|
done_date = next_start - 1
|
834
836
|
next_start = item['date']
|
835
|
-
elsif opt[:back]
|
836
|
-
if opt[:back].is_a? Integer
|
837
|
-
done_date = item['date'] + opt[:back]
|
838
|
-
else
|
839
|
-
done_date = item['date'] + (opt[:back] - item['date'])
|
840
|
-
end
|
841
837
|
elsif opt[:took]
|
842
838
|
if item['date'] + opt[:took] > Time.now
|
843
839
|
item['date'] = Time.now - opt[:took]
|
@@ -845,6 +841,12 @@ class WWID
|
|
845
841
|
else
|
846
842
|
done_date = item['date'] + opt[:took]
|
847
843
|
end
|
844
|
+
elsif opt[:back]
|
845
|
+
if opt[:back].is_a? Integer
|
846
|
+
done_date = item['date'] + opt[:back]
|
847
|
+
else
|
848
|
+
done_date = item['date'] + (opt[:back] - item['date'])
|
849
|
+
end
|
848
850
|
else
|
849
851
|
done_date = Time.now
|
850
852
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: doing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.70
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Terpstra
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -165,6 +165,7 @@ files:
|
|
165
165
|
- README.md
|
166
166
|
- bin/doing
|
167
167
|
- lib/doing.rb
|
168
|
+
- lib/doing/helpers.rb
|
168
169
|
- lib/doing/version.rb
|
169
170
|
- lib/doing/wwid.rb
|
170
171
|
- lib/templates/doing.css
|