doing 2.1.38 → 2.1.39
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/CHANGELOG.md +21 -0
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/Rakefile +7 -1
- data/bin/commands/now.rb +2 -4
- data/bin/commands/on.rb +4 -2
- data/bin/commands/show.rb +3 -0
- data/bin/doing +33 -35
- data/docs/doc/Array.html +1 -1
- data/docs/doc/BooleanTermParser/Clause.html +1 -1
- data/docs/doc/BooleanTermParser/Operator.html +1 -1
- data/docs/doc/BooleanTermParser/Query.html +1 -1
- data/docs/doc/BooleanTermParser/QueryParser.html +1 -1
- data/docs/doc/BooleanTermParser/QueryTransformer.html +1 -1
- data/docs/doc/BooleanTermParser.html +1 -1
- data/docs/doc/Doing/Color.html +1 -1
- data/docs/doc/Doing/Completion.html +1 -1
- data/docs/doc/Doing/Configuration.html +1 -1
- data/docs/doc/Doing/Errors/DoingNoTraceError.html +1 -1
- data/docs/doc/Doing/Errors/DoingRuntimeError.html +1 -1
- data/docs/doc/Doing/Errors/DoingStandardError.html +1 -1
- data/docs/doc/Doing/Errors/EmptyInput.html +1 -1
- data/docs/doc/Doing/Errors/NoResults.html +1 -1
- data/docs/doc/Doing/Errors/PluginException.html +1 -1
- data/docs/doc/Doing/Errors/UserCancelled.html +1 -1
- data/docs/doc/Doing/Errors/WrongCommand.html +1 -1
- data/docs/doc/Doing/Errors.html +1 -1
- data/docs/doc/Doing/Hooks.html +1 -1
- data/docs/doc/Doing/Item.html +64 -1
- data/docs/doc/Doing/Items.html +1 -1
- data/docs/doc/Doing/Logger.html +1 -1
- data/docs/doc/Doing/Note.html +1 -1
- data/docs/doc/Doing/Pager.html +1 -1
- data/docs/doc/Doing/Plugins.html +1 -1
- data/docs/doc/Doing/Prompt.html +1 -1
- data/docs/doc/Doing/Section.html +1 -1
- data/docs/doc/Doing/TemplateString.html +1 -1
- data/docs/doc/Doing/Types.html +1 -1
- data/docs/doc/Doing/Util/Backup.html +1 -1
- data/docs/doc/Doing/Util.html +1 -1
- data/docs/doc/Doing/WWID.html +1 -1
- data/docs/doc/Doing.html +2 -2
- data/docs/doc/FalseClass.html +1 -1
- data/docs/doc/GLI/Commands/Help.html +1 -1
- data/docs/doc/GLI/Commands/MarkdownDocumentListener.html +1 -1
- data/docs/doc/GLI/Commands.html +1 -1
- data/docs/doc/GLI.html +1 -1
- data/docs/doc/Hash.html +1 -1
- data/docs/doc/Object.html +1 -1
- data/docs/doc/PhraseParser/Operator.html +1 -1
- data/docs/doc/PhraseParser/PhraseClause.html +1 -1
- data/docs/doc/PhraseParser/Query.html +1 -1
- data/docs/doc/PhraseParser/QueryParser.html +1 -1
- data/docs/doc/PhraseParser/QueryTransformer.html +1 -1
- data/docs/doc/PhraseParser/TermClause.html +1 -1
- data/docs/doc/PhraseParser.html +1 -1
- data/docs/doc/Status.html +1 -1
- data/docs/doc/String.html +1 -1
- data/docs/doc/Symbol.html +1 -1
- data/docs/doc/Time.html +1 -1
- data/docs/doc/TrueClass.html +1 -1
- data/docs/doc/_index.html +1 -1
- data/docs/doc/file.README.html +2 -2
- data/docs/doc/index.html +2 -2
- data/docs/doc/method_list.html +159 -151
- data/docs/doc/top-level-namespace.html +1 -1
- data/doing.rdoc +6 -1
- data/lib/completion/_doing.zsh +1 -1
- data/lib/completion/doing.bash +2 -2
- data/lib/completion/doing.fish +1 -0
- data/lib/doing/chronify/string.rb +3 -1
- data/lib/doing/item.rb +151 -53
- data/lib/doing/items.rb +1 -1
- data/lib/doing/prompt.rb +6 -8
- data/lib/doing/string/tags.rb +8 -2
- data/lib/doing/version.rb +1 -1
- data/lib/doing/wwid.rb +7 -2
- metadata +2 -2
|
@@ -206,7 +206,7 @@
|
|
|
206
206
|
</div>
|
|
207
207
|
|
|
208
208
|
<div id="footer">
|
|
209
|
-
Generated on
|
|
209
|
+
Generated on Sun Mar 13 05:08:08 2022 by
|
|
210
210
|
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
211
211
|
0.9.27 (ruby-3.0.1).
|
|
212
212
|
</div>
|
data/doing.rdoc
CHANGED
|
@@ -5,7 +5,7 @@ record of what you've been doing, complete with tag-based time tracking. The
|
|
|
5
5
|
command line tool allows you to add entries, annotate with tags and notes, and
|
|
6
6
|
view your entries with myriad options, with a focus on a "natural" language syntax.
|
|
7
7
|
|
|
8
|
-
v2.1.
|
|
8
|
+
v2.1.39
|
|
9
9
|
|
|
10
10
|
=== Global Options
|
|
11
11
|
=== --config_file arg
|
|
@@ -2283,6 +2283,11 @@ Show elapsed time on entries without @done tag
|
|
|
2283
2283
|
|
|
2284
2284
|
|
|
2285
2285
|
|
|
2286
|
+
===== -e|--editor
|
|
2287
|
+
Edit matching entries with vim
|
|
2288
|
+
|
|
2289
|
+
|
|
2290
|
+
|
|
2286
2291
|
===== -h|--[no-]hilite
|
|
2287
2292
|
Highlight search matches in output. Only affects command line output
|
|
2288
2293
|
|
data/lib/completion/_doing.zsh
CHANGED
|
@@ -174,7 +174,7 @@ function _doing() {
|
|
|
174
174
|
args=( {'(--archive)-a','(-a)--archive'}"[Archive selected items]" "--after[Select entries newer than date]:DATE_STRING:" "--resume[Copy selection as a new entry with current time and no @done tag]" "--before[Select entries older than date]:DATE_STRING:" {'(--cancel)-c','(-c)--cancel'}"[Cancel selected items]" "--case[Case sensitivity for search string matching ((c)ase-sensitive]:TYPE:" {'(--delete)-d','(-d)--delete'}"[Delete selected items]" {'(--editor)-e','(-e)--editor'}"[Edit selected item(s)]" {'(--finish)-f','(-f)--finish'}"[Add @done with current time to selected item(s)]" "--flag[Add flag to selected item(s)]" "--force[Perform action without confirmation]" "--from[Date range]:DATE_OR_RANGE:" {'(--move)-m','(-m)--move'}"[Move selected items to section]:SECTION:" "--menu[Use --no-menu to skip the interactive menu]" "--not[Select items that *dont* match search/tag filterst* match search/tag filters]" {'(--output)-o','(-o)--output'}"[Output entries to format]:FORMAT:" {'(--query)-q','(-q)--query'}"[Initial search query for filtering]:QUERY:" {'(--remove)-r','(-r)--remove'}"[Reverse -c]" {'(--section)-s','(-s)--section'}"[Select from a specific section]:SECTION:" "--save_to[Save selected entries to file using --output format]:FILE:" "--search[Filter entries using a search query]:QUERY:" {'(--tag)-t','(-t)--tag'}"[Tag selected entries]:TAG:" "--val[Perform a tag value query]:QUERY:" {'(--exact)-x','(-x)--exact'}"[Force exact search string matching]" )
|
|
175
175
|
;;
|
|
176
176
|
show)
|
|
177
|
-
args=( {'(--age)-a','(-a)--age'}"[Age]:AGE:" "--after[Show entries newer than date]:DATE_STRING:" "--before[Show entries older than date]:DATE_STRING:" "--bool[Boolean used to combine multiple tags]:BOOLEAN:" {'(--count)-c','(-c)--count'}"[Max count to show]:MAX:" "--case[Case sensitivity for search string matching ((c)ase-sensitive]:TYPE:" "--config_template[Output using a template from configuration]:TEMPLATE_KEY:" "--duration[Show elapsed time on entries without @done tag]" "--from[Date range]:DATE_OR_RANGE:" {'(--hilite)-h','(-h)--hilite'}"[Highlight search matches in output]" {'(--interactive)-i','(-i)--interactive'}"[Select from a menu of matching entries to perform additional operations]" {'(--menu)-m','(-m)--menu'}"[Select section or tag to display from a menu]" "--not[Show items that *dont* match search/tag filterst* match search/tag filters]" {'(--output)-o','(-o)--output'}"[Output to export format]:FORMAT:" "--only_timed[Only show items with recorded time intervals]" {'(--sort)-s','(-s)--sort'}"[Sort order]:ORDER:" "--search[Filter entries using a search query]:QUERY:" {'(--times)-t','(-t)--times'}"[Show time intervals on @done tasks]" "--tag[Filter entries by tag]:TAG:" "--tag_order[Tag sort direction]:DIRECTION:" "--tag_sort[Sort tags by]:KEY:" "--template[Override output format with a template string containing %placeholders]:TEMPLATE_STRING:" "--totals[Show time totals at the end of output]" "--val[Perform a tag value query]:QUERY:" {'(--exact)-x','(-x)--exact'}"[Force exact search string matching]" )
|
|
177
|
+
args=( {'(--age)-a','(-a)--age'}"[Age]:AGE:" "--after[Show entries newer than date]:DATE_STRING:" "--before[Show entries older than date]:DATE_STRING:" "--bool[Boolean used to combine multiple tags]:BOOLEAN:" {'(--count)-c','(-c)--count'}"[Max count to show]:MAX:" "--case[Case sensitivity for search string matching ((c)ase-sensitive]:TYPE:" "--config_template[Output using a template from configuration]:TEMPLATE_KEY:" "--duration[Show elapsed time on entries without @done tag]" {'(--editor)-e','(-e)--editor'}"[Edit matching entries with vim]" "--from[Date range]:DATE_OR_RANGE:" {'(--hilite)-h','(-h)--hilite'}"[Highlight search matches in output]" {'(--interactive)-i','(-i)--interactive'}"[Select from a menu of matching entries to perform additional operations]" {'(--menu)-m','(-m)--menu'}"[Select section or tag to display from a menu]" "--not[Show items that *dont* match search/tag filterst* match search/tag filters]" {'(--output)-o','(-o)--output'}"[Output to export format]:FORMAT:" "--only_timed[Only show items with recorded time intervals]" {'(--sort)-s','(-s)--sort'}"[Sort order]:ORDER:" "--search[Filter entries using a search query]:QUERY:" {'(--times)-t','(-t)--times'}"[Show time intervals on @done tasks]" "--tag[Filter entries by tag]:TAG:" "--tag_order[Tag sort direction]:DIRECTION:" "--tag_sort[Sort tags by]:KEY:" "--template[Override output format with a template string containing %placeholders]:TEMPLATE_STRING:" "--totals[Show time totals at the end of output]" "--val[Perform a tag value query]:QUERY:" {'(--exact)-x','(-x)--exact'}"[Force exact search string matching]" )
|
|
178
178
|
;;
|
|
179
179
|
since)
|
|
180
180
|
args=( "--bool[Boolean used to combine multiple tags]:BOOLEAN:" "--case[Case sensitivity for search string matching ((c)ase-sensitive]:TYPE:" "--config_template[Output using a template from configuration]:TEMPLATE_KEY:" "--duration[Show elapsed time on entries without @done tag]" "--not[Since items that *dont* match search/tag filterst* match search/tag filters]" {'(--output)-o','(-o)--output'}"[Output to export format]:FORMAT:" "--only_timed[Only show items with recorded time intervals]" {'(--section)-s','(-s)--section'}"[Section]:NAME:" "--search[Filter entries using a search query]:QUERY:" {'(--times)-t','(-t)--times'}"[Show time intervals on @done tasks]" "--tag[Filter entries by tag]:TAG:" "--tag_order[Tag sort direction]:DIRECTION:" "--tag_sort[Sort tags by]:KEY:" "--template[Override output format with a template string containing %placeholders]:TEMPLATE_STRING:" "--totals[Show time totals at the end of output]" "--val[Perform a tag value query]:QUERY:" {'(--exact)-x','(-x)--exact'}"[Force exact search string matching]" )
|
data/lib/completion/doing.bash
CHANGED
|
@@ -276,9 +276,9 @@ local words=$(doing sections)
|
|
|
276
276
|
IFS="$OLD_IFS"
|
|
277
277
|
|
|
278
278
|
if [[ "$token" == --* ]]; then
|
|
279
|
-
COMPREPLY=( $( compgen -W '--age --after --before --bool --count --case --config_template --duration --from --hilite --interactive --menu --not --output --only_timed --sort --search --times --tag --tag_order --tag_sort --template --totals --val --exact' -- $token ) )
|
|
279
|
+
COMPREPLY=( $( compgen -W '--age --after --before --bool --count --case --config_template --duration --editor --from --hilite --interactive --menu --not --output --only_timed --sort --search --times --tag --tag_order --tag_sort --template --totals --val --exact' -- $token ) )
|
|
280
280
|
elif [[ "$token" == -* ]]; then
|
|
281
|
-
COMPREPLY=( $( compgen -W '-a -c -h -i -m -o -s -t -x --age --after --before --bool --count --case --config_template --duration --from --hilite --interactive --menu --not --output --only_timed --sort --search --times --tag --tag_order --tag_sort --template --totals --val --exact' -- $token ) )
|
|
281
|
+
COMPREPLY=( $( compgen -W '-a -c -e -h -i -m -o -s -t -x --age --after --before --bool --count --case --config_template --duration --editor --from --hilite --interactive --menu --not --output --only_timed --sort --search --times --tag --tag_order --tag_sort --template --totals --val --exact' -- $token ) )
|
|
282
282
|
else
|
|
283
283
|
local nocasematchWasOff=0
|
|
284
284
|
shopt nocasematch >/dev/null || nocasematchWasOff=1
|
data/lib/completion/doing.fish
CHANGED
|
@@ -447,6 +447,7 @@ complete -c doing -l count -s c -f -r -n '__fish_doing_using_command show' -d Ma
|
|
|
447
447
|
complete -c doing -l case -f -r -n '__fish_doing_using_command show' -d Case\ sensitivity\ for\ search\ string\ matching\ \[\(c\)ase-sensitive
|
|
448
448
|
complete -c doing -l config_template -f -r -n '__fish_doing_using_command show' -d Output\ using\ a\ template\ from\ configuration
|
|
449
449
|
complete -c doing -l duration -f -n '__fish_doing_using_command show' -d Show\ elapsed\ time\ on\ entries\ without\ @done\ tag
|
|
450
|
+
complete -c doing -l editor -s e -f -n '__fish_doing_using_command show' -d Edit\ matching\ entries\ with\ vim
|
|
450
451
|
complete -c doing -l from -f -r -n '__fish_doing_using_command show' -d Date\ range
|
|
451
452
|
complete -c doing -l hilite -s h -f -n '__fish_doing_using_command show' -d Highlight\ search\ matches\ in\ output
|
|
452
453
|
complete -c doing -l interactive -s i -f -n '__fish_doing_using_command show' -d Select\ from\ a\ menu\ of\ matching\ entries\ to\ perform\ additional\ operations
|
|
@@ -196,7 +196,9 @@ module Doing
|
|
|
196
196
|
finish = dates[-1].chronify(guess: inclusive ? :end : :begin, future: true)
|
|
197
197
|
end
|
|
198
198
|
|
|
199
|
-
raise Errors::InvalidTimeExpression,
|
|
199
|
+
raise Errors::InvalidTimeExpression, "Unrecognized date string (#{dates[0]})" if start.nil?
|
|
200
|
+
|
|
201
|
+
raise Errors::InvalidTimeExpression, "Unrecognized date string (#{dates[-1]})" if finish.nil?
|
|
200
202
|
|
|
201
203
|
else
|
|
202
204
|
if date_string.strip =~ time_rx
|
data/lib/doing/item.rb
CHANGED
|
@@ -180,8 +180,14 @@ module Doing
|
|
|
180
180
|
|
|
181
181
|
remove = options.fetch(:remove, false)
|
|
182
182
|
tags.each do |tag|
|
|
183
|
+
if tag =~ /^(\S+)\((.*?)\)$/
|
|
184
|
+
m = Regexp.last_match
|
|
185
|
+
tag = m[1]
|
|
186
|
+
options[:value] ||= m[2]
|
|
187
|
+
end
|
|
188
|
+
|
|
183
189
|
bool = remove ? :and : :not
|
|
184
|
-
if tags?(tag, bool)
|
|
190
|
+
if tags?(tag, bool) || options[:value]
|
|
185
191
|
@title = @title.tag(tag, **options).strip
|
|
186
192
|
remove ? removed.push(tag) : added.push(tag)
|
|
187
193
|
end
|
|
@@ -201,6 +207,16 @@ module Doing
|
|
|
201
207
|
@title.scan(/(?<= |\A)@([^\s(]+)/).map { |tag| tag[0] }.sort.uniq
|
|
202
208
|
end
|
|
203
209
|
|
|
210
|
+
##
|
|
211
|
+
## Return all tags including parenthetical values
|
|
212
|
+
##
|
|
213
|
+
## @return [Array<Array>] Array of array pairs,
|
|
214
|
+
## [[tag1, value], [tag2, value]]
|
|
215
|
+
##
|
|
216
|
+
def tags_with_values
|
|
217
|
+
@title.scan(/(?<= |\A)@([^\s(]+)(?:\((.*?)\))?/).map { |tag| [tag[0], tag[1]] }.sort.uniq
|
|
218
|
+
end
|
|
219
|
+
|
|
204
220
|
##
|
|
205
221
|
## convert tags on item to an array with @ symbols removed
|
|
206
222
|
##
|
|
@@ -557,6 +573,12 @@ module Doing
|
|
|
557
573
|
false
|
|
558
574
|
end
|
|
559
575
|
|
|
576
|
+
def tag_pattern?(tags)
|
|
577
|
+
query = tags.to_query
|
|
578
|
+
|
|
579
|
+
no_tags?(query[:must_not]) && all_tags?(query[:must]) && any_tags?(query[:should])
|
|
580
|
+
end
|
|
581
|
+
|
|
560
582
|
def tag_value(tag)
|
|
561
583
|
res = @title.match(/@#{tag.sub(/^@/, '').wildcard_to_rx}\((.*?)\)/)
|
|
562
584
|
res ? res[1] : nil
|
|
@@ -592,6 +614,7 @@ module Doing
|
|
|
592
614
|
|
|
593
615
|
queries.each do |q|
|
|
594
616
|
parts = split_value_query(q)
|
|
617
|
+
|
|
595
618
|
return false unless tag_value_matches?(parts[2], parts[3], parts[4], parts[1])
|
|
596
619
|
end
|
|
597
620
|
true
|
|
@@ -607,78 +630,153 @@ module Doing
|
|
|
607
630
|
true
|
|
608
631
|
end
|
|
609
632
|
|
|
633
|
+
def duration_matches?(value, comp)
|
|
634
|
+
return false if interval.nil?
|
|
635
|
+
|
|
636
|
+
val = value.chronify_qty
|
|
637
|
+
case comp
|
|
638
|
+
when /^<$/
|
|
639
|
+
interval < val
|
|
640
|
+
when /^<=$/
|
|
641
|
+
interval <= val
|
|
642
|
+
when /^>$/
|
|
643
|
+
interval > val
|
|
644
|
+
when /^>=$/
|
|
645
|
+
interval >= val
|
|
646
|
+
when /^!=/
|
|
647
|
+
interval != val
|
|
648
|
+
when /^=/
|
|
649
|
+
interval == val
|
|
650
|
+
end
|
|
651
|
+
end
|
|
652
|
+
|
|
653
|
+
def date_matches?(value, comp)
|
|
654
|
+
time_rx = /^(\d{1,2}+(:\d{1,2}+)?( *(am|pm))?|midnight|noon)$/i
|
|
655
|
+
value = "#{@date.strftime('%Y-%m-%d')} #{value}" if value =~ time_rx
|
|
656
|
+
|
|
657
|
+
val = value.chronify(guess: :begin)
|
|
658
|
+
raise InvalidTimeExpression, "Unrecognized date/time expression (#{value})" if val.nil?
|
|
659
|
+
|
|
660
|
+
case comp
|
|
661
|
+
when /^<$/
|
|
662
|
+
@date < val
|
|
663
|
+
when /^<=$/
|
|
664
|
+
@date <= val
|
|
665
|
+
when /^>$/
|
|
666
|
+
@date > val
|
|
667
|
+
when /^>=$/
|
|
668
|
+
@date >= val
|
|
669
|
+
when /^!=/
|
|
670
|
+
@date != val
|
|
671
|
+
when /^=/
|
|
672
|
+
@date == val
|
|
673
|
+
end
|
|
674
|
+
end
|
|
675
|
+
|
|
676
|
+
def value_string_matches?(tag_val, comp, value)
|
|
677
|
+
case comp
|
|
678
|
+
when /\^=/
|
|
679
|
+
tag_val =~ /^#{value.wildcard_to_rx}/i
|
|
680
|
+
when /\$=/
|
|
681
|
+
tag_val =~ /#{value.wildcard_to_rx}$/i
|
|
682
|
+
when %r{==}
|
|
683
|
+
tag_val =~ /^#{value.wildcard_to_rx}$/i
|
|
684
|
+
else
|
|
685
|
+
tag_val =~ /#{value.wildcard_to_rx}/i
|
|
686
|
+
end
|
|
687
|
+
end
|
|
688
|
+
|
|
689
|
+
def value_number_matches?(tag_val, comp, value)
|
|
690
|
+
case comp
|
|
691
|
+
when /^<$/
|
|
692
|
+
tag_val < value
|
|
693
|
+
when /^<=$/
|
|
694
|
+
tag_val <= value
|
|
695
|
+
when /^>$/
|
|
696
|
+
tag_val > value
|
|
697
|
+
when /^>=$/
|
|
698
|
+
tag_val >= value
|
|
699
|
+
when /^!=/
|
|
700
|
+
tag_val != value
|
|
701
|
+
when /^=/
|
|
702
|
+
tag_val == value
|
|
703
|
+
end
|
|
704
|
+
end
|
|
705
|
+
|
|
706
|
+
##
|
|
707
|
+
## Test if a tag's value matches a given value. Value
|
|
708
|
+
## can be a date string, a text string, or a
|
|
709
|
+
## number/percentage. Type of comparison is determined
|
|
710
|
+
## by the comparitor and the objects being compared.
|
|
711
|
+
##
|
|
712
|
+
## @param tag [String] The tag name from which
|
|
713
|
+
## to get the value
|
|
714
|
+
## @param comp [String] The comparator (e.g. >=
|
|
715
|
+
## or *=)
|
|
716
|
+
## @param value [String] The value to test
|
|
717
|
+
## against
|
|
718
|
+
## @param negate [Boolean] Negate the response
|
|
719
|
+
##
|
|
720
|
+
## @return True if tag value matches, False otherwise.
|
|
721
|
+
##
|
|
610
722
|
def tag_value_matches?(tag, comp, value, negate)
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
return false if interval.nil?
|
|
614
|
-
|
|
615
|
-
val = value.chronify_qty
|
|
616
|
-
is_match = case comp
|
|
617
|
-
when /^<$/
|
|
618
|
-
interval < val
|
|
619
|
-
when /^<=$/
|
|
620
|
-
interval <= val
|
|
621
|
-
when /^>$/
|
|
622
|
-
interval > val
|
|
623
|
-
when /^>=$/
|
|
624
|
-
interval >= val
|
|
625
|
-
when /^!=/
|
|
626
|
-
interval != val
|
|
627
|
-
when /^=/
|
|
628
|
-
interval == val
|
|
629
|
-
end
|
|
630
|
-
comp =~ /!/ || negate ? !is_match : is_match
|
|
631
|
-
elsif all_tags?([tag])
|
|
723
|
+
# If tag matches existing tag
|
|
724
|
+
if tags?(tag, :and)
|
|
632
725
|
tag_val = tag_value(tag)
|
|
633
726
|
|
|
727
|
+
# If the tag value is not a date and contains alpha
|
|
728
|
+
# characters and comparison is ==, or comparison is
|
|
729
|
+
# a string comparitor (*= ^= $=)
|
|
634
730
|
if (value.chronify.nil? && value =~ /[a-z]/i && comp =~ /^!?==?$/) || comp =~ /[$*^]=/
|
|
635
|
-
is_match =
|
|
636
|
-
when /\^=/
|
|
637
|
-
tag_val =~ /^#{value.wildcard_to_rx}/i
|
|
638
|
-
when /\$=/
|
|
639
|
-
tag_val =~ /#{value.wildcard_to_rx}$/i
|
|
640
|
-
when %r{==}
|
|
641
|
-
tag_val =~ /^#{value.wildcard_to_rx}$/i
|
|
642
|
-
else
|
|
643
|
-
tag_val =~ /#{value.wildcard_to_rx}/i
|
|
644
|
-
end
|
|
731
|
+
is_match = value_string_matches?(tag_val, comp, value)
|
|
645
732
|
|
|
646
733
|
comp =~ /!/ || negate ? !is_match : is_match
|
|
647
734
|
else
|
|
735
|
+
# Convert values to either a number or a date
|
|
648
736
|
tag_val = number_or_date(tag_val)
|
|
649
737
|
val = number_or_date(value)
|
|
650
738
|
|
|
739
|
+
# Fail if either value is nil
|
|
651
740
|
return false if val.nil? || tag_val.nil?
|
|
652
741
|
|
|
742
|
+
# Fail unless both values are of the same class (float or date)
|
|
653
743
|
return false unless val.class == tag_val.class
|
|
654
744
|
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
when /^<=$/
|
|
659
|
-
tag_val <= val
|
|
660
|
-
when /^>$/
|
|
661
|
-
tag_val > val
|
|
662
|
-
when /^>=$/
|
|
663
|
-
tag_val >= val
|
|
664
|
-
when /^!=/
|
|
665
|
-
tag_val != val
|
|
666
|
-
when /^=/
|
|
667
|
-
tag_val == val
|
|
668
|
-
end
|
|
669
|
-
negate.nil? ? matches : !matches
|
|
745
|
+
is_match = value_number_matches?(tag_val, comp, val)
|
|
746
|
+
|
|
747
|
+
negate.nil? ? is_match : !is_match
|
|
670
748
|
end
|
|
749
|
+
# If tag name matches a trigger for elapsed time test
|
|
750
|
+
elsif tag =~ /^(elapsed|dur(ation)?|int(erval)?)$/i
|
|
751
|
+
is_match = duration_matches?(value, comp)
|
|
752
|
+
|
|
753
|
+
comp =~ /!/ || negate ? !is_match : is_match
|
|
754
|
+
# Else if tag name matches a trigger for start date
|
|
755
|
+
elsif tag =~ /^(d(ate)?|t(ime)?)$/i
|
|
756
|
+
is_match = date_matches?(value, comp)
|
|
757
|
+
|
|
758
|
+
comp =~ /!/ || negate ? !is_match : is_match
|
|
759
|
+
# Else if tag name matches a trigger for all text
|
|
760
|
+
elsif tag =~ /^text$/i
|
|
761
|
+
is_match = value_string_matches?([@title, @note.to_s(prefix: '')].join(' '), comp, value)
|
|
762
|
+
|
|
763
|
+
comp =~ /!/ || negate ? !is_match : is_match
|
|
764
|
+
# Else if tag name matches a trigger for title
|
|
765
|
+
elsif tag =~ /^title$/i
|
|
766
|
+
is_match = value_string_matches?(@title, comp, value)
|
|
767
|
+
|
|
768
|
+
comp =~ /!/ || negate ? !is_match : is_match
|
|
769
|
+
# Else if tag name matches a trigger for note
|
|
770
|
+
elsif tag =~ /^note$/i
|
|
771
|
+
is_match = value_string_matches?(@note.to_s(prefix: ''), comp, value)
|
|
772
|
+
|
|
773
|
+
comp =~ /!/ || negate ? !is_match : is_match
|
|
774
|
+
# Else if item contains tag being tested
|
|
671
775
|
else
|
|
672
776
|
false
|
|
673
777
|
end
|
|
674
778
|
end
|
|
675
779
|
|
|
676
|
-
def tag_pattern?(tags)
|
|
677
|
-
query = tags.to_query
|
|
678
|
-
|
|
679
|
-
no_tags?(query[:must_not]) && all_tags?(query[:must]) && any_tags?(query[:should])
|
|
680
|
-
end
|
|
681
|
-
|
|
682
780
|
def split_tags(tags)
|
|
683
781
|
tags.to_tags.tags_to_array
|
|
684
782
|
end
|
data/lib/doing/items.rb
CHANGED
|
@@ -179,7 +179,7 @@ module Doing
|
|
|
179
179
|
out = []
|
|
180
180
|
@sections.each do |section|
|
|
181
181
|
out.push(section.original)
|
|
182
|
-
items = in_section(section.title).sort_by
|
|
182
|
+
items = in_section(section.title).sort_by { |i| [i.date, i.title] }
|
|
183
183
|
items.reverse! if Doing.setting('doing_file_sort').normalize_order == :desc
|
|
184
184
|
items.each { |item| out.push(item.to_s) }
|
|
185
185
|
end
|
data/lib/doing/prompt.rb
CHANGED
|
@@ -58,14 +58,12 @@ module Doing
|
|
|
58
58
|
comp = proc { |s| completions.grep(/^#{Regexp.escape(s)}/) }
|
|
59
59
|
Readline.completion_append_character = ' '
|
|
60
60
|
Readline.completion_proc = comp
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
prompt_text << yellow(' to cancel')
|
|
68
|
-
puts prompt_text.join('')
|
|
61
|
+
puts format(['%<promptcolor>s%<prompt>s %<textcolor>sEnter a blank line',
|
|
62
|
+
'(%<keycolor>sreturn twice%<textcolor>s)',
|
|
63
|
+
'to end editing and save,',
|
|
64
|
+
'%<keycolor>sCTRL-C%<textcolor>s to cancel%<reset>s'].join(' '),
|
|
65
|
+
{ promptcolor: boldgreen, prompt: prompt.sub(/:?$/, ':'),
|
|
66
|
+
textcolor: yellow, keycolor: boldwhite, reset: reset })
|
|
69
67
|
|
|
70
68
|
res = []
|
|
71
69
|
|
data/lib/doing/string/tags.rb
CHANGED
|
@@ -117,14 +117,20 @@ module Doing
|
|
|
117
117
|
else
|
|
118
118
|
Doing.logger.debug('Skipped:', "not tagged #{"@#{tag}".cyan}")
|
|
119
119
|
end
|
|
120
|
-
elsif title =~ /@#{tag}(?=[ (]|$)/
|
|
120
|
+
elsif title =~ /@#{tag}(?=[ (]|$)/ && !value.good?
|
|
121
121
|
Doing.logger.debug('Skipped:', "already tagged #{"@#{tag}".cyan}")
|
|
122
122
|
return title
|
|
123
123
|
else
|
|
124
124
|
add = tag
|
|
125
125
|
add += "(#{value})" unless value.nil?
|
|
126
|
+
|
|
126
127
|
title.chomp!
|
|
127
|
-
|
|
128
|
+
|
|
129
|
+
if value && title =~ /@#{tag}(?=[ (]|$)/
|
|
130
|
+
title.sub!(/@#{tag}(\(.*?\))?/, "@#{add}")
|
|
131
|
+
else
|
|
132
|
+
title += " @#{add}"
|
|
133
|
+
end
|
|
128
134
|
|
|
129
135
|
title.dedup_tags!
|
|
130
136
|
title.chomp!
|
data/lib/doing/version.rb
CHANGED
data/lib/doing/wwid.rb
CHANGED
|
@@ -665,7 +665,7 @@ module Doing
|
|
|
665
665
|
##
|
|
666
666
|
def filter_items(items = Items.new, opt: {})
|
|
667
667
|
logger.benchmark(:filter_items, :start)
|
|
668
|
-
time_rx = /^(\d{1,2}+(:\d{1,2}+)?( *(am|pm))?|midnight|noon)$/
|
|
668
|
+
time_rx = /^(\d{1,2}+(:\d{1,2}+)?( *(am|pm))?|midnight|noon)$/i
|
|
669
669
|
|
|
670
670
|
if items.nil? || items.empty?
|
|
671
671
|
section = opt[:section] ? guess_section(opt[:section]) : 'All'
|
|
@@ -1292,9 +1292,14 @@ module Doing
|
|
|
1292
1292
|
next
|
|
1293
1293
|
end
|
|
1294
1294
|
|
|
1295
|
-
|
|
1296
1295
|
tag = tag.strip
|
|
1297
1296
|
|
|
1297
|
+
if tag =~ /^(\S+)\((.*?)\)$/
|
|
1298
|
+
m = Regexp.last_match
|
|
1299
|
+
tag = m[1]
|
|
1300
|
+
opt[:value] ||= m[2]
|
|
1301
|
+
end
|
|
1302
|
+
|
|
1298
1303
|
if tag =~ /^done$/ && opt[:date] && item.should_time?
|
|
1299
1304
|
max_elapsed = Doing.setting('interaction.confirm_longer_than', 0)
|
|
1300
1305
|
max_elapsed = max_elapsed.chronify_qty if max_elapsed.is_a?(String)
|
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: 2.1.
|
|
4
|
+
version: 2.1.39
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brett Terpstra
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-03-
|
|
11
|
+
date: 2022-03-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: github-markup
|