doing 2.1.39 → 2.1.40

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -0
  3. data/Gemfile.lock +1 -1
  4. data/README.md +1 -1
  5. data/bin/commands/config.rb +43 -34
  6. data/bin/commands/done.rb +1 -18
  7. data/bin/commands/finish.rb +30 -25
  8. data/bin/commands/grep.rb +3 -14
  9. data/bin/commands/last.rb +2 -8
  10. data/bin/commands/meanwhile.rb +13 -6
  11. data/bin/commands/on.rb +3 -16
  12. data/bin/commands/recent.rb +2 -8
  13. data/bin/commands/reset.rb +24 -1
  14. data/bin/commands/select.rb +1 -1
  15. data/bin/commands/show.rb +6 -17
  16. data/bin/commands/since.rb +1 -12
  17. data/bin/commands/today.rb +2 -13
  18. data/bin/commands/view.rb +1 -1
  19. data/bin/commands/yesterday.rb +2 -13
  20. data/bin/doing +15 -8
  21. data/docs/doc/Array.html +1 -1
  22. data/docs/doc/BooleanTermParser/Clause.html +1 -1
  23. data/docs/doc/BooleanTermParser/Operator.html +1 -1
  24. data/docs/doc/BooleanTermParser/Query.html +1 -1
  25. data/docs/doc/BooleanTermParser/QueryParser.html +1 -1
  26. data/docs/doc/BooleanTermParser/QueryTransformer.html +1 -1
  27. data/docs/doc/BooleanTermParser.html +1 -1
  28. data/docs/doc/Doing/Color.html +166 -20
  29. data/docs/doc/Doing/Completion.html +1 -1
  30. data/docs/doc/Doing/Configuration.html +1 -1
  31. data/docs/doc/Doing/Errors/DoingNoTraceError.html +7 -3
  32. data/docs/doc/Doing/Errors/DoingRuntimeError.html +7 -3
  33. data/docs/doc/Doing/Errors/DoingStandardError.html +1 -1
  34. data/docs/doc/Doing/Errors/EmptyInput.html +10 -2
  35. data/docs/doc/Doing/Errors/HistoryLimitError.html +194 -0
  36. data/docs/doc/Doing/Errors/InvalidPlugin.html +194 -0
  37. data/docs/doc/Doing/Errors/MissingBackupFile.html +194 -0
  38. data/docs/doc/Doing/Errors/NoResults.html +10 -2
  39. data/docs/doc/Doing/Errors/PluginException.html +1 -1
  40. data/docs/doc/Doing/Errors/UserCancelled.html +10 -2
  41. data/docs/doc/Doing/Errors/WrongCommand.html +10 -2
  42. data/docs/doc/Doing/Errors.html +9 -9
  43. data/docs/doc/Doing/Hooks.html +1 -1
  44. data/docs/doc/Doing/Item.html +90 -1615
  45. data/docs/doc/Doing/Items.html +121 -5
  46. data/docs/doc/Doing/Logger.html +1 -1
  47. data/docs/doc/Doing/Note.html +1 -1
  48. data/docs/doc/Doing/Pager.html +1 -1
  49. data/docs/doc/Doing/Plugins.html +1 -1
  50. data/docs/doc/Doing/Prompt.html +2 -2
  51. data/docs/doc/Doing/Section.html +1 -1
  52. data/docs/doc/Doing/TemplateString.html +2 -2
  53. data/docs/doc/Doing/Types.html +1 -1
  54. data/docs/doc/Doing/Util/Backup.html +5 -5
  55. data/docs/doc/Doing/Util.html +1 -1
  56. data/docs/doc/Doing/WWID.html +197 -4033
  57. data/docs/doc/Doing.html +2 -2
  58. data/docs/doc/FalseClass.html +1 -1
  59. data/docs/doc/GLI/Commands/Help.html +1 -1
  60. data/docs/doc/GLI/Commands/MarkdownDocumentListener.html +1 -1
  61. data/docs/doc/GLI/Commands.html +1 -1
  62. data/docs/doc/GLI.html +1 -1
  63. data/docs/doc/Hash.html +1 -1
  64. data/docs/doc/Object.html +1 -1
  65. data/docs/doc/PhraseParser/Operator.html +1 -1
  66. data/docs/doc/PhraseParser/PhraseClause.html +1 -1
  67. data/docs/doc/PhraseParser/Query.html +1 -1
  68. data/docs/doc/PhraseParser/QueryParser.html +1 -1
  69. data/docs/doc/PhraseParser/QueryTransformer.html +1 -1
  70. data/docs/doc/PhraseParser/TermClause.html +1 -1
  71. data/docs/doc/PhraseParser.html +1 -1
  72. data/docs/doc/Status.html +1 -1
  73. data/docs/doc/String.html +1 -1
  74. data/docs/doc/Symbol.html +1 -1
  75. data/docs/doc/Time.html +1 -1
  76. data/docs/doc/TrueClass.html +1 -1
  77. data/docs/doc/_index.html +26 -5
  78. data/docs/doc/class_list.html +1 -1
  79. data/docs/doc/file.README.html +2 -2
  80. data/docs/doc/index.html +2 -2
  81. data/docs/doc/method_list.html +293 -773
  82. data/docs/doc/top-level-namespace.html +3 -3
  83. data/docs/index.md +1 -1
  84. data/doing.rdoc +49 -7
  85. data/lib/completion/_doing.zsh +5 -5
  86. data/lib/completion/doing.bash +8 -8
  87. data/lib/completion/doing.fish +7 -2
  88. data/lib/doing/add_options.rb +31 -1
  89. data/lib/doing/chronify/array.rb +64 -22
  90. data/lib/doing/colors.rb +77 -30
  91. data/lib/doing/completion.rb +4 -5
  92. data/lib/doing/errors.rb +51 -35
  93. data/lib/doing/hooks.rb +3 -3
  94. data/lib/doing/item/dates.rb +112 -0
  95. data/lib/doing/item/query.rb +433 -0
  96. data/lib/doing/item/state.rb +59 -0
  97. data/lib/doing/item/tags.rb +87 -0
  98. data/lib/doing/item.rb +6 -667
  99. data/lib/doing/items.rb +38 -13
  100. data/lib/doing/plugin_manager.rb +3 -3
  101. data/lib/doing/plugins/export/template_export.rb +4 -4
  102. data/lib/doing/plugins/import/cal_to_json.scpt +0 -0
  103. data/lib/doing/util_backup.rb +6 -8
  104. data/lib/doing/version.rb +1 -1
  105. data/lib/doing/wwid/display.rb +399 -0
  106. data/lib/doing/wwid/editor.rb +214 -0
  107. data/lib/doing/wwid/filetools.rb +186 -0
  108. data/lib/doing/wwid/filter.rb +218 -0
  109. data/lib/doing/wwid/guess.rb +87 -0
  110. data/lib/doing/wwid/interactive.rb +385 -0
  111. data/lib/doing/wwid/modify.rb +618 -0
  112. data/lib/doing/wwid/tags.rb +54 -0
  113. data/lib/doing/wwid/timers.rb +345 -0
  114. data/lib/doing/wwid/wwidutil.rb +104 -0
  115. data/lib/doing/wwid.rb +31 -2317
  116. metadata +19 -2
@@ -108,7 +108,7 @@
108
108
  <li class="public ">
109
109
  <span class="summary_signature">
110
110
 
111
- <a href="top-level-namespace.html#add_options-instance_method" title="#add_options (instance method)">#<strong>add_options</strong>(type, cmd) &#x21d2; Object </a>
111
+ <a href="top-level-namespace.html#add_options-instance_method" title="#add_options (instance method)">#<strong>add_options</strong>(type, cmd, default_template: &#39;default&#39;) &#x21d2; Object </a>
112
112
 
113
113
 
114
114
 
@@ -140,7 +140,7 @@
140
140
  <div class="method_details first">
141
141
  <h3 class="signature first" id="add_options-instance_method">
142
142
 
143
- #<strong>add_options</strong>(type, cmd) &#x21d2; <tt><span class='object_link'><a href="Object.html" title="Object (class)">Object</a></span></tt>
143
+ #<strong>add_options</strong>(type, cmd, default_template: &#39;default&#39;) &#x21d2; <tt><span class='object_link'><a href="Object.html" title="Object (class)">Object</a></span></tt>
144
144
 
145
145
 
146
146
 
@@ -206,7 +206,7 @@
206
206
  </div>
207
207
 
208
208
  <div id="footer">
209
- Generated on Sun Mar 13 05:08:08 2022 by
209
+ Generated on Tue Mar 15 11:14:28 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/docs/index.md CHANGED
@@ -8,7 +8,7 @@ _If you're one of the rare people like me who find this useful, feel free to
8
8
 
9
9
 
10
10
 
11
- The current version of `doing` is 2.1.31.
11
+ The current version of `doing` is 2.1.39.
12
12
 
13
13
  Find all of the documentation in the [doing wiki][wiki].
14
14
 
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.39
8
+ v2.1.40
9
9
 
10
10
  === Global Options
11
11
  === --config_file arg
@@ -645,7 +645,7 @@ way to add entries in post and maintain accurate (albeit manual) time tracking.
645
645
  ===== --at|--finished DATE_STRING
646
646
 
647
647
  Set finish date to specific date/time (natural langauge parsed, e.g. --at=1:30pm).
648
- Used with --took, backdates start date
648
+ Used with --took, backdates start date
649
649
 
650
650
  [Default Value] None
651
651
 
@@ -660,7 +660,7 @@ Backdate start date for new entry to date string [4pm|20m|2h|yesterday noon]
660
660
  ===== --from TIME_RANGE
661
661
 
662
662
  Start and end times as a date/time range `doing done --from "1am to 8am"`.
663
- Overrides other date flags.
663
+ Overrides other date flags.
664
664
 
665
665
  [Default Value] None
666
666
  [Must Match] (?i-mx:^\S+.*? +(?:to|through|thru|(?:un)?til|-+) +\S+.*?$)
@@ -683,8 +683,8 @@ Section
683
683
  ===== -t|--took|--for INTERVAL
684
684
 
685
685
  Set completion date to start date plus interval (XX[mhd] or HH:MM).
686
- If used without the --back option, the start date will be moved back to allow
687
- the completion date to be the current time.
686
+ If used without the --back option, the start date will be moved back to allow
687
+ the completion date to be the current time.
688
688
 
689
689
  [Default Value] None
690
690
 
@@ -731,7 +731,8 @@ Marks the last X entries with a @done tag and current date. Does not alter alrea
731
731
  ===== Options
732
732
  ===== --at|--finished DATE_STRING
733
733
 
734
- Set finish date to specific date/time (natural langauge parsed, e.g. --at=1:30pm). If used, ignores --back.
734
+ Set finish date to specific date/time (natural langauge parsed, e.g. --at=1:30pm).
735
+ Used with --took, backdates start date
735
736
 
736
737
  [Default Value] None
737
738
 
@@ -759,6 +760,15 @@ Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart
759
760
  [Must Match] (?i-mx:^[cis].*?$)
760
761
 
761
762
 
763
+ ===== --from TIME_RANGE
764
+
765
+ Start and end times as a date/time range `doing done --from "1am to 8am"`.
766
+ Overrides other date flags.
767
+
768
+ [Default Value] None
769
+ [Must Match] (?i-mx:^\S+.*? +(?:to|through|thru|(?:un)?til|-+) +\S+.*?$)
770
+
771
+
762
772
  ===== -s|--section NAME
763
773
 
764
774
  Section
@@ -776,7 +786,9 @@ Filter entries using a search query, surround with slashes for regex (e.g. "/que
776
786
 
777
787
  ===== -t|--took|--for INTERVAL
778
788
 
779
- Set the completed date to the start date plus XX[hmd]
789
+ Set completion date to start date plus interval (XX[mhd] or HH:MM).
790
+ If used without the --back option, the start date will be moved back to allow
791
+ the completion date to be the current time.
780
792
 
781
793
  [Default Value] None
782
794
 
@@ -1144,6 +1156,13 @@ Output using a template from configuration
1144
1156
  [Default Value] last
1145
1157
 
1146
1158
 
1159
+ ===== -o|--output FORMAT
1160
+
1161
+ Output to export format (csv|dayone|dayone-days|dayone-entries|doing|html|json|markdown|say|taskpaper|template|timeline|wiki)
1162
+
1163
+ [Default Value] None
1164
+
1165
+
1147
1166
  ===== -s|--section NAME
1148
1167
 
1149
1168
  Specify a section
@@ -1706,6 +1725,13 @@ Output using a template from configuration
1706
1725
  [Default Value] recent
1707
1726
 
1708
1727
 
1728
+ ===== -o|--output FORMAT
1729
+
1730
+ Output to export format (csv|dayone|dayone-days|dayone-entries|doing|html|json|markdown|say|taskpaper|template|timeline|wiki)
1731
+
1732
+ [Default Value] None
1733
+
1734
+
1709
1735
  ===== -s|--section NAME
1710
1736
 
1711
1737
  Section
@@ -1801,6 +1827,15 @@ Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart
1801
1827
  [Must Match] (?i-mx:^[cis].*?$)
1802
1828
 
1803
1829
 
1830
+ ===== --from TIME_RANGE
1831
+
1832
+ Start and end times as a date/time range `doing done --from "1am to 8am"`.
1833
+ Overrides any date argument and disables --resume.
1834
+
1835
+ [Default Value] None
1836
+ [Must Match] (?i-mx:^\S+.*? +(?:to|through|thru|(?:un)?til|-+) +\S+.*?$)
1837
+
1838
+
1804
1839
  ===== -s|--section NAME
1805
1840
 
1806
1841
  Limit search to section
@@ -1816,6 +1851,13 @@ Filter entries using a search query, surround with slashes for regex (e.g. "/que
1816
1851
  [Default Value] None
1817
1852
 
1818
1853
 
1854
+ ===== -t|--took|--for INTERVAL
1855
+
1856
+ Set completion date to start date plus interval (XX[mhd] or HH:MM). Disables --resume
1857
+
1858
+ [Default Value] None
1859
+
1860
+
1819
1861
  ===== --tag TAG
1820
1862
 
1821
1863
  Filter entries by tag. Combine multiple tags with a comma. Wildcards allowed (*, ?)
@@ -108,7 +108,7 @@ function _doing() {
108
108
  args=( {'(--noauto)-X','(-X)--noauto'}"[Exclude auto tags and default tags]" {'(--archive)-a','(-a)--archive'}"[Immediately archive the entry]" "--ask[Prompt for note via multi-line input]" "--finished[Set finish date to specific date/time]:DATE_STRING:" "--started[Backdate start date for new entry to date string (4pm|20m|2h|yesterday noon)]:DATE_STRING:" "--date[Include date]" {'(--editor)-e','(-e)--editor'}"[Edit entry with vim]" "--from[Start and end times as a date/time range `doing done --from "1am to 8am"`]:TIME_RANGE:" {'(--note)-n','(-n)--note'}"[Include a note]:TEXT:" {'(--remove)-r','(-r)--remove'}"[Remove @done tag]" {'(--section)-s','(-s)--section'}"[Section]:NAME:" "--for[Set completion date to start date plus interval]:INTERVAL:" {'(--unfinished)-u','(-u)--unfinished'}"[Finish last entry not already marked @done]" )
109
109
  ;;
110
110
  finish)
111
- args=( {'(--archive)-a','(-a)--archive'}"[Archive entries]" "--finished[Set finish date to specific date/time]:DATE_STRING:" "--auto[Auto-generate finish dates from next entrys start times start time]" "--started[Backdate completed date to date string (4pm|20m|2h|yesterday noon)]:DATE_STRING:" "--bool[Boolean used to combine multiple tags]:BOOLEAN:" "--case[Case sensitivity for search string matching ((c)ase-sensitive]:TYPE:" "--date[Include date]" {'(--interactive)-i','(-i)--interactive'}"[Select item(s) to finish from a menu of matching entries]" "--not[Finish items that *dont* match search/tag filterst* match search/tag filters]" {'(--remove)-r','(-r)--remove'}"[Remove @done tag]" {'(--section)-s','(-s)--section'}"[Section]:NAME:" "--search[Filter entries using a search query]:QUERY:" "--for[Set the completed date to the start date plus XX(hmd)]:INTERVAL:" "--tag[Filter entries by tag]:TAG:" {'(--unfinished)-u','(-u)--unfinished'}"[Finish last entry]" "--update[Overwrite existing @done tag with new date]" "--val[Perform a tag value query]:QUERY:" {'(--exact)-x','(-x)--exact'}"[Force exact search string matching]" )
111
+ args=( {'(--archive)-a','(-a)--archive'}"[Archive entries]" "--finished[Set finish date to specific date/time]:DATE_STRING:" "--auto[Auto-generate finish dates from next entrys start times start time]" "--started[Backdate completed date to date string (4pm|20m|2h|yesterday noon)]:DATE_STRING:" "--bool[Boolean used to combine multiple tags]:BOOLEAN:" "--case[Case sensitivity for search string matching ((c)ase-sensitive]:TYPE:" "--date[Include date]" "--from[Start and end times as a date/time range `doing done --from "1am to 8am"`]:TIME_RANGE:" {'(--interactive)-i','(-i)--interactive'}"[Select item(s) to finish from a menu of matching entries]" "--not[Finish items that *dont* match search/tag filterst* match search/tag filters]" {'(--remove)-r','(-r)--remove'}"[Remove @done tag]" {'(--section)-s','(-s)--section'}"[Section]:NAME:" "--search[Filter entries using a search query]:QUERY:" "--for[Set completion date to start date plus interval]:INTERVAL:" "--tag[Filter entries by tag]:TAG:" {'(--unfinished)-u','(-u)--unfinished'}"[Finish last entry]" "--update[Overwrite existing @done tag with new date]" "--val[Perform a tag value query]:QUERY:" {'(--exact)-x','(-x)--exact'}"[Force exact search string matching]" )
112
112
  ;;
113
113
  grep)
114
114
  args=( "--after[Search entries newer than date]:DATE_STRING:" "--before[Search entries older than date]:DATE_STRING:" "--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:" {'(--delete)-d','(-d)--delete'}"[Delete matching entries]" "--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'}"[Display an interactive menu of results to perform further operations]" "--not[Search 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:" {'(--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 string matching]" )
@@ -123,7 +123,7 @@ function _doing() {
123
123
  args=( "--after[Import entries newer than date]:DATE_STRING:" "--autotag[Autotag entries]" "--before[Import entries older than date]:DATE_STRING:" "--case[Case sensitivity for search string matching ((c)ase-sensitive]:TYPE:" "--from[Date range]:DATE_OR_RANGE:" "--not[Import items that *dont* match search/tag/date filterst* match search/tag/date filters]" "--only_timed[Only import items with recorded time intervals]" "--overlap[Allow entries that overlap existing times]" "--prefix[Prefix entries with]:PREFIX:" {'(--section)-s','(-s)--section'}"[Target section]:NAME:" "--search[Filter entries using a search query]:QUERY:" {'(--tag)-t','(-t)--tag'}"[Tag all imported entries]:TAGS:" "--type[Import type]:TYPE:" {'(--exact)-x','(-x)--exact'}"[Force exact search string matching]" )
124
124
  ;;
125
125
  last)
126
- 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:" {'(--delete)-d','(-d)--delete'}"[Delete the last entry]" "--duration[Show elapsed time if entry is not tagged @done]" {'(--editor)-e','(-e)--editor'}"[Edit entry with vim]" {'(--hilite)-h','(-h)--hilite'}"[Highlight search matches in output]" "--not[Show items that *dont* match search/tag filterst* match search/tag filters]" {'(--section)-s','(-s)--section'}"[Specify a section]:NAME:" "--search[Filter entries using a search query]:QUERY:" "--tag[Filter entries by tag]:TAG:" "--template[Override output format with a template string containing %placeholders]:TEMPLATE_STRING:" "--val[Perform a tag value query]:QUERY:" {'(--exact)-x','(-x)--exact'}"[Force exact search string matching]" )
126
+ 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:" {'(--delete)-d','(-d)--delete'}"[Delete the last entry]" "--duration[Show elapsed time if entry is not tagged @done]" {'(--editor)-e','(-e)--editor'}"[Edit entry with vim]" {'(--hilite)-h','(-h)--hilite'}"[Highlight search matches in output]" "--not[Show items that *dont* match search/tag filterst* match search/tag filters]" {'(--output)-o','(-o)--output'}"[Output to export format]:FORMAT:" {'(--section)-s','(-s)--section'}"[Specify a section]:NAME:" "--search[Filter entries using a search query]:QUERY:" "--tag[Filter entries by tag]:TAG:" "--template[Override output format with a template string containing %placeholders]:TEMPLATE_STRING:" "--val[Perform a tag value query]:QUERY:" {'(--exact)-x','(-x)--exact'}"[Force exact search string matching]" )
127
127
  ;;
128
128
  mark)
129
129
  args=( "--bool[Boolean used to combine multiple tags]:BOOLEAN:" {'(--count)-c','(-c)--count'}"[How many recent entries to tag]:COUNT:" "--case[Case sensitivity for search string matching ((c)ase-sensitive]:TYPE:" {'(--date)-d','(-d)--date'}"[Include current date/time with tag]" "--force[Dont ask permission to flag all entries when count is 0t ask permission to flag all entries when count is 0]" {'(--interactive)-i','(-i)--interactive'}"[Select item(s) to flag from a menu of matching entries]" "--not[Flag items that *dont* match search/tag filterst* match search/tag filters]" {'(--remove)-r','(-r)--remove'}"[Remove flag]" {'(--section)-s','(-s)--section'}"[Section]:SECTION_NAME:" "--search[Filter entries using a search query]:QUERY:" "--tag[Filter entries by tag]:TAG:" {'(--unfinished)-u','(-u)--unfinished'}"[Flag last entry]" "--val[Perform a tag value query]:QUERY:" {'(--exact)-x','(-x)--exact'}"[Force exact search string matching]" )
@@ -153,16 +153,16 @@ function _doing() {
153
153
  args=( {'(--column)-c','(-c)--column'}"[List in single column for completion]" {'(--type)-t','(-t)--type'}"[List plugins of type]:TYPE:" )
154
154
  ;;
155
155
  recent)
156
- args=( "--config_template[Output using a template from configuration]:TEMPLATE_KEY:" "--duration[Show elapsed time on entries without @done tag]" {'(--interactive)-i','(-i)--interactive'}"[Select from a menu of matching entries to perform additional operations]" "--only_timed[Only show items with recorded time intervals]" {'(--section)-s','(-s)--section'}"[Section]:NAME:" {'(--times)-t','(-t)--times'}"[Show time intervals on @done tasks]" "--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]" )
156
+ args=( "--config_template[Output using a template from configuration]:TEMPLATE_KEY:" "--duration[Show elapsed time on entries without @done tag]" {'(--interactive)-i','(-i)--interactive'}"[Select from a menu of matching entries to perform additional operations]" {'(--output)-o','(-o)--output'}"[Output to export format]:FORMAT:" "--only_timed[Only show items with recorded time intervals]" {'(--section)-s','(-s)--section'}"[Section]:NAME:" {'(--times)-t','(-t)--times'}"[Show time intervals on @done tasks]" "--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]" )
157
157
  ;;
158
158
  redo)
159
159
  args=( {'(--file)-f','(-f)--file'}"[Specify alternate doing file]:PATH:" {'(--interactive)-i','(-i)--interactive'}"[Select from an interactive menu]" )
160
160
  ;;
161
161
  reset)
162
- args=( "--bool[Boolean used to combine multiple tags]:BOOLEAN:" "--case[Case sensitivity for search string matching ((c)ase-sensitive]:TYPE:" {'(--interactive)-i','(-i)--interactive'}"[Select from a menu of matching entries]" "--not[Reset items that *dont* match search/tag filterst* match search/tag filters]" {'(--resume)-r','(-r)--resume'}"[Resume entry]" {'(--section)-s','(-s)--section'}"[Limit search to section]:NAME:" "--search[Filter entries using a search query]:QUERY:" "--tag[Filter entries by tag]:TAG:" "--val[Perform a tag value query]:QUERY:" {'(--exact)-x','(-x)--exact'}"[Force exact search string matching]" )
162
+ args=( "--bool[Boolean used to combine multiple tags]:BOOLEAN:" "--case[Case sensitivity for search string matching ((c)ase-sensitive]:TYPE:" "--from[Start and end times as a date/time range `doing done --from "1am to 8am"`]:TIME_RANGE:" {'(--interactive)-i','(-i)--interactive'}"[Select from a menu of matching entries]" "--not[Reset items that *dont* match search/tag filterst* match search/tag filters]" {'(--resume)-r','(-r)--resume'}"[Resume entry]" {'(--section)-s','(-s)--section'}"[Limit search to section]:NAME:" "--search[Filter entries using a search query]:QUERY:" "--for[Set completion date to start date plus interval]:INTERVAL:" "--tag[Filter entries by tag]:TAG:" "--val[Perform a tag value query]:QUERY:" {'(--exact)-x','(-x)--exact'}"[Force exact search string matching]" )
163
163
  ;;
164
164
  begin)
165
- args=( "--bool[Boolean used to combine multiple tags]:BOOLEAN:" "--case[Case sensitivity for search string matching ((c)ase-sensitive]:TYPE:" {'(--interactive)-i','(-i)--interactive'}"[Select from a menu of matching entries]" "--not[Reset items that *dont* match search/tag filterst* match search/tag filters]" {'(--resume)-r','(-r)--resume'}"[Resume entry]" {'(--section)-s','(-s)--section'}"[Limit search to section]:NAME:" "--search[Filter entries using a search query]:QUERY:" "--tag[Filter entries by tag]:TAG:" "--val[Perform a tag value query]:QUERY:" {'(--exact)-x','(-x)--exact'}"[Force exact search string matching]" )
165
+ args=( "--bool[Boolean used to combine multiple tags]:BOOLEAN:" "--case[Case sensitivity for search string matching ((c)ase-sensitive]:TYPE:" "--from[Start and end times as a date/time range `doing done --from "1am to 8am"`]:TIME_RANGE:" {'(--interactive)-i','(-i)--interactive'}"[Select from a menu of matching entries]" "--not[Reset items that *dont* match search/tag filterst* match search/tag filters]" {'(--resume)-r','(-r)--resume'}"[Resume entry]" {'(--section)-s','(-s)--section'}"[Limit search to section]:NAME:" "--search[Filter entries using a search query]:QUERY:" "--for[Set completion date to start date plus interval]:INTERVAL:" "--tag[Filter entries by tag]:TAG:" "--val[Perform a tag value query]:QUERY:" {'(--exact)-x','(-x)--exact'}"[Force exact search string matching]" )
166
166
  ;;
167
167
  rotate)
168
168
  args=( "--before[Rotate entries older than date]:DATE_STRING:" "--bool[Boolean used to combine multiple tags]:BOOLEAN:" "--case[Case sensitivity for search string matching ((c)ase-sensitive]:TYPE:" {'(--keep)-k','(-k)--keep'}"[How many items to keep in each section]:X:" "--not[Rotate items that *dont* match search/tag filterst* match search/tag filters]" {'(--section)-s','(-s)--section'}"[Section to rotate]:SECTION_NAME:" "--search[Filter entries using a search query]:QUERY:" "--tag[Filter entries by tag]:TAG:" "--val[Perform a tag value query]:QUERY:" {'(--exact)-x','(-x)--exact'}"[Force exact search string matching]" )
@@ -101,9 +101,9 @@ _doing_done() {
101
101
  _doing_finish() {
102
102
 
103
103
  if [[ "$token" == --* ]]; then
104
- COMPREPLY=( $( compgen -W '--archive --finished --auto --started --bool --case --date --interactive --not --remove --section --search --for --tag --unfinished --update --val --exact' -- $token ) )
104
+ COMPREPLY=( $( compgen -W '--archive --finished --auto --started --bool --case --date --from --interactive --not --remove --section --search --for --tag --unfinished --update --val --exact' -- $token ) )
105
105
  elif [[ "$token" == -* ]]; then
106
- COMPREPLY=( $( compgen -W '-a -i -r -s -u -x --archive --finished --auto --started --bool --case --date --interactive --not --remove --section --search --for --tag --unfinished --update --val --exact' -- $token ) )
106
+ COMPREPLY=( $( compgen -W '-a -i -r -s -u -x --archive --finished --auto --started --bool --case --date --from --interactive --not --remove --section --search --for --tag --unfinished --update --val --exact' -- $token ) )
107
107
 
108
108
  fi
109
109
  }
@@ -141,9 +141,9 @@ _doing_import() {
141
141
  _doing_last() {
142
142
 
143
143
  if [[ "$token" == --* ]]; then
144
- COMPREPLY=( $( compgen -W '--bool --case --config_template --delete --duration --editor --hilite --not --section --search --tag --template --val --exact' -- $token ) )
144
+ COMPREPLY=( $( compgen -W '--bool --case --config_template --delete --duration --editor --hilite --not --output --section --search --tag --template --val --exact' -- $token ) )
145
145
  elif [[ "$token" == -* ]]; then
146
- COMPREPLY=( $( compgen -W '-d -e -h -s -x --bool --case --config_template --delete --duration --editor --hilite --not --section --search --tag --template --val --exact' -- $token ) )
146
+ COMPREPLY=( $( compgen -W '-d -e -h -o -s -x --bool --case --config_template --delete --duration --editor --hilite --not --output --section --search --tag --template --val --exact' -- $token ) )
147
147
 
148
148
  fi
149
149
  }
@@ -221,9 +221,9 @@ _doing_plugins() {
221
221
  _doing_recent() {
222
222
 
223
223
  if [[ "$token" == --* ]]; then
224
- COMPREPLY=( $( compgen -W '--config_template --duration --interactive --only_timed --section --times --tag_order --tag_sort --template --totals' -- $token ) )
224
+ COMPREPLY=( $( compgen -W '--config_template --duration --interactive --output --only_timed --section --times --tag_order --tag_sort --template --totals' -- $token ) )
225
225
  elif [[ "$token" == -* ]]; then
226
- COMPREPLY=( $( compgen -W '-i -s -t --config_template --duration --interactive --only_timed --section --times --tag_order --tag_sort --template --totals' -- $token ) )
226
+ COMPREPLY=( $( compgen -W '-i -o -s -t --config_template --duration --interactive --output --only_timed --section --times --tag_order --tag_sort --template --totals' -- $token ) )
227
227
 
228
228
  fi
229
229
  }
@@ -241,9 +241,9 @@ _doing_redo() {
241
241
  _doing_reset() {
242
242
 
243
243
  if [[ "$token" == --* ]]; then
244
- COMPREPLY=( $( compgen -W '--bool --case --interactive --not --resume --section --search --tag --val --exact' -- $token ) )
244
+ COMPREPLY=( $( compgen -W '--bool --case --from --interactive --not --resume --section --search --for --tag --val --exact' -- $token ) )
245
245
  elif [[ "$token" == -* ]]; then
246
- COMPREPLY=( $( compgen -W '-i -r -s -x --bool --case --interactive --not --resume --section --search --tag --val --exact' -- $token ) )
246
+ COMPREPLY=( $( compgen -W '-i -r -s -x --bool --case --from --interactive --not --resume --section --search --for --tag --val --exact' -- $token ) )
247
247
 
248
248
  fi
249
249
  }
@@ -254,12 +254,13 @@ complete -c doing -l started -f -r -n '__fish_doing_using_command finish' -d Ba
254
254
  complete -c doing -l bool -f -r -n '__fish_doing_using_command finish' -d Boolean\ used\ to\ combine\ multiple\ tags
255
255
  complete -c doing -l case -f -r -n '__fish_doing_using_command finish' -d Case\ sensitivity\ for\ search\ string\ matching\ \[\(c\)ase-sensitive
256
256
  complete -c doing -l date -f -n '__fish_doing_using_command finish' -d Include\ date
257
+ complete -c doing -l from -f -r -n '__fish_doing_using_command finish' -d Start\ and\ end\ times\ as\ a\ date/time\ range\ \`doing\ done\ --from\ \"1am\ to\ 8am\"\`
257
258
  complete -c doing -l interactive -s i -f -n '__fish_doing_using_command finish' -d Select\ item\(s\)\ to\ finish\ from\ a\ menu\ of\ matching\ entries
258
259
  complete -c doing -l not -f -n '__fish_doing_using_command finish' -d Finish\ items\ that\ \*don\'t\*\ match\ search/tag\ filters
259
260
  complete -c doing -l remove -s r -f -n '__fish_doing_using_command finish' -d Remove\ @done\ tag
260
261
  complete -c doing -l section -s s -f -r -n '__fish_doing_using_command finish' -d Section
261
262
  complete -c doing -l search -f -r -n '__fish_doing_using_command finish' -d Filter\ entries\ using\ a\ search\ query
262
- complete -c doing -l for -f -r -n '__fish_doing_using_command finish' -d Set\ the\ completed\ date\ to\ the\ start\ date\ plus\ XX\[hmd\]
263
+ complete -c doing -l for -f -r -n '__fish_doing_using_command finish' -d Set\ completion\ date\ to\ start\ date\ plus\ interval
263
264
  complete -c doing -l tag -f -r -n '__fish_doing_using_command finish' -d Filter\ entries\ by\ tag
264
265
  complete -c doing -l unfinished -s u -f -n '__fish_doing_using_command finish' -d Finish\ last\ entry
265
266
  complete -c doing -l update -f -n '__fish_doing_using_command finish' -d Overwrite\ existing\ @done\ tag\ with\ new\ date
@@ -311,6 +312,7 @@ complete -c doing -l duration -f -n '__fish_doing_using_command last' -d Show\
311
312
  complete -c doing -l editor -s e -f -n '__fish_doing_using_command last' -d Edit\ entry\ with\ vim
312
313
  complete -c doing -l hilite -s h -f -n '__fish_doing_using_command last' -d Highlight\ search\ matches\ in\ output
313
314
  complete -c doing -l not -f -n '__fish_doing_using_command last' -d Show\ items\ that\ \*don\'t\*\ match\ search/tag\ filters
315
+ complete -c doing -l output -s o -f -r -n '__fish_doing_using_command last' -d Output\ to\ export\ format
314
316
  complete -c doing -l section -s s -f -r -n '__fish_doing_using_command last' -d Specify\ a\ section
315
317
  complete -c doing -l search -f -r -n '__fish_doing_using_command last' -d Filter\ entries\ using\ a\ search\ query
316
318
  complete -c doing -l tag -f -r -n '__fish_doing_using_command last' -d Filter\ entries\ by\ tag
@@ -386,6 +388,7 @@ complete -c doing -l type -s t -f -r -n '__fish_doing_using_command plugins' -d
386
388
  complete -c doing -l config_template -f -r -n '__fish_doing_using_command recent' -d Output\ using\ a\ template\ from\ configuration
387
389
  complete -c doing -l duration -f -n '__fish_doing_using_command recent' -d Show\ elapsed\ time\ on\ entries\ without\ @done\ tag
388
390
  complete -c doing -l interactive -s i -f -n '__fish_doing_using_command recent' -d Select\ from\ a\ menu\ of\ matching\ entries\ to\ perform\ additional\ operations
391
+ complete -c doing -l output -s o -f -r -n '__fish_doing_using_command recent' -d Output\ to\ export\ format
389
392
  complete -c doing -l only_timed -f -n '__fish_doing_using_command recent' -d Only\ show\ items\ with\ recorded\ time\ intervals
390
393
  complete -c doing -l section -s s -f -r -n '__fish_doing_using_command recent' -d Section
391
394
  complete -c doing -l times -s t -f -n '__fish_doing_using_command recent' -d Show\ time\ intervals\ on\ @done\ tasks
@@ -397,11 +400,13 @@ complete -c doing -l file -s f -f -r -n '__fish_doing_using_command redo' -d Spe
397
400
  complete -c doing -l interactive -s i -f -n '__fish_doing_using_command redo' -d Select\ from\ an\ interactive\ menu
398
401
  complete -c doing -l bool -f -r -n '__fish_doing_using_command reset begin' -d Boolean\ used\ to\ combine\ multiple\ tags
399
402
  complete -c doing -l case -f -r -n '__fish_doing_using_command reset begin' -d Case\ sensitivity\ for\ search\ string\ matching\ \[\(c\)ase-sensitive
403
+ complete -c doing -l from -f -r -n '__fish_doing_using_command reset begin' -d Start\ and\ end\ times\ as\ a\ date/time\ range\ \`doing\ done\ --from\ \"1am\ to\ 8am\"\`
400
404
  complete -c doing -l interactive -s i -f -n '__fish_doing_using_command reset begin' -d Select\ from\ a\ menu\ of\ matching\ entries
401
405
  complete -c doing -l not -f -n '__fish_doing_using_command reset begin' -d Reset\ items\ that\ \*don\'t\*\ match\ search/tag\ filters
402
406
  complete -c doing -l resume -s r -f -n '__fish_doing_using_command reset begin' -d Resume\ entry
403
407
  complete -c doing -l section -s s -f -r -n '__fish_doing_using_command reset begin' -d Limit\ search\ to\ section
404
408
  complete -c doing -l search -f -r -n '__fish_doing_using_command reset begin' -d Filter\ entries\ using\ a\ search\ query
409
+ complete -c doing -l for -f -r -n '__fish_doing_using_command reset begin' -d Set\ completion\ date\ to\ start\ date\ plus\ interval
405
410
  complete -c doing -l tag -f -r -n '__fish_doing_using_command reset begin' -d Filter\ entries\ by\ tag
406
411
  complete -c doing -l val -f -r -n '__fish_doing_using_command reset begin' -d Perform\ a\ tag\ value\ query
407
412
  complete -c doing -l exact -s x -f -n '__fish_doing_using_command reset begin' -d Force\ exact\ search\ string\ matching
@@ -580,7 +585,7 @@ complete -c doing -l tag_order -f -r -n '__fish_doing_using_command yesterday'
580
585
  complete -c doing -l tag_sort -f -r -n '__fish_doing_using_command yesterday' -d Sort\ tags\ by
581
586
  complete -c doing -l template -f -r -n '__fish_doing_using_command yesterday' -d Override\ output\ format\ with\ a\ template\ string\ containing\ \%placeholders
582
587
  complete -c doing -l totals -f -n '__fish_doing_using_command yesterday' -d Show\ time\ totals\ at\ the\ end\ of\ output
583
- complete -f -c doing -s o -l output -x -n '__fish_doing_using_command grep search on select show since today view yesterday' -a '(__fish_doing_export_plugin)'
588
+ complete -f -c doing -s o -l output -x -n '__fish_doing_using_command grep search last on recent select show since today view yesterday' -a '(__fish_doing_export_plugin)'
584
589
  complete -f -c doing -s b -l bool -x -n '__fish_doing_using_command again resume archive move autotag cancel finish grep search last mark flag note on reset begin rotate show since tag tags view wiki' -a 'and or not pattern'
585
590
  complete -f -c doing -l case -x -n '__fish_doing_using_command again resume archive move cancel finish grep search import last mark flag note on reset begin rotate select show since tag tags view' -a 'case-sensitive ignore smart'
586
591
  complete -f -c doing -l sort -x -n '__fish_doing_using_command changes changelog show tags' -a 'asc desc'
@@ -14,7 +14,7 @@
14
14
  ## @param type [Symbol] The type
15
15
  ## @param cmd The GLI command to which the options will be added
16
16
  ##
17
- def add_options(type, cmd)
17
+ def add_options(type, cmd, default_template: 'default')
18
18
  cmd_name = cmd.name.to_s
19
19
  action = case cmd_name
20
20
  when /again/
@@ -30,6 +30,18 @@ def add_options(type, cmd)
30
30
  end
31
31
 
32
32
  case type
33
+ when :output_template
34
+ cmd.desc "Output to export format (#{Doing::Plugins.plugin_names(type: :export)})"
35
+ cmd.arg_name 'FORMAT'
36
+ cmd.flag %i[o output]
37
+
38
+ cmd.desc "Output using a template from configuration"
39
+ cmd.arg_name 'TEMPLATE_KEY'
40
+ cmd.flag [:config_template], type: TemplateName, default_value: default_template
41
+
42
+ cmd.desc 'Override output format with a template string containing %placeholders'
43
+ cmd.arg_name 'TEMPLATE_STRING'
44
+ cmd.flag [:template]
33
45
  when :add_entry
34
46
  cmd.desc 'Exclude auto tags and default tags'
35
47
  cmd.switch %i[X noauto], default_value: false, negatable: false
@@ -47,6 +59,24 @@ def add_options(type, cmd)
47
59
  cmd.desc 'Backdate start date for new entry to date string [4pm|20m|2h|yesterday noon]'
48
60
  cmd.arg_name 'DATE_STRING'
49
61
  cmd.flag %i[b back started], type: DateBeginString
62
+ when :finish_entry
63
+ cmd.desc %(Set finish date to specific date/time (natural langauge parsed, e.g. --at=1:30pm).
64
+ Used with --took, backdates start date)
65
+ cmd.arg_name 'DATE_STRING'
66
+ cmd.flag %i[at finished], type: DateEndString
67
+
68
+ cmd.desc %(
69
+ Start and end times as a date/time range `doing done --from "1am to 8am"`.
70
+ Overrides other date flags.
71
+ )
72
+ cmd.arg_name 'TIME_RANGE'
73
+ cmd.flag [:from], must_match: REGEX_RANGE
74
+
75
+ cmd.desc %(Set completion date to start date plus interval (XX[mhd] or HH:MM).
76
+ If used without the --back option, the start date will be moved back to allow
77
+ the completion date to be the current time.)
78
+ cmd.arg_name 'INTERVAL'
79
+ cmd.flag %i[t took for], type: DateIntervalString
50
80
  when :search
51
81
  cmd.desc 'Filter entries using a search query, surround with slashes for regex (e.g. "/query.*/"),
52
82
  start with single quote for exact match ("\'query")'
@@ -3,6 +3,56 @@
3
3
  module Doing
4
4
  # Chronify array helpers
5
5
  class ::Array
6
+ # Convert [d, h, m] to [y, d, h, m]
7
+ def to_years
8
+ d, h, m = self
9
+
10
+ if d.zero? && h > 24
11
+ d = (h / 24).floor
12
+ h = h % 24
13
+ end
14
+
15
+ if d > 365
16
+ y = (d / 365).floor
17
+ d = d % 365
18
+ else
19
+ y = 0
20
+ end
21
+
22
+ [y, d, h, m]
23
+ end
24
+
25
+ def to_natural
26
+ y, d, h, m = to_years
27
+ human = []
28
+ human.push(format('%<y>d %<s>s', y: y, s: 'year'.to_p(y))) if y.positive?
29
+ human.push(format('%<d>d %<s>s', d: d, s: 'day'.to_p(d))) if d.positive?
30
+ human.push(format('%<h>d %<s>s', h: h, s: 'hour'.to_p(h))) if h.positive?
31
+ human.push(format('%<m>d %<s>s', m: m, s: 'minute'.to_p(m))) if m.positive?
32
+ human
33
+ end
34
+
35
+ def to_abbr(years: false, separator: '')
36
+ if years
37
+ y, d, h, m = to_years
38
+ else
39
+ y = 0
40
+ d, h, m = self
41
+
42
+ if d.zero? && h > 24
43
+ d = (h / 24).floor
44
+ h = h % 24
45
+ end
46
+ end
47
+
48
+ output = []
49
+ output.push(format('%<y>dy', y: y)) if y.positive?
50
+ output.push(format('%<d>dd', d: d)) if d.positive?
51
+ output.push(format('%<h>dh', h: h)) if h.positive?
52
+ output.push(format('%<m>dm', m: m)) if m.positive?
53
+ output.join(separator)
54
+ end
55
+
6
56
  ##
7
57
  ## Format [d, h, m] as string
8
58
  ##
@@ -23,16 +73,13 @@ module Doing
23
73
  h = h % 24
24
74
  end
25
75
  format('%<d>02d:%<h>02d:%<m>02d', d: d, h: h, m: m)
76
+ when :hmclock
77
+ h += d * 24 if d.positive?
78
+ format('%<h>02d:%<m>02d', h: h, m: m)
79
+ when :ydhm
80
+ to_abbr(years: true, separator: ' ')
26
81
  when :dhm
27
- if d.zero? && h > 24
28
- d = (h / 24).floor
29
- h = h % 24
30
- end
31
- output = []
32
- output.push(format('%<d>dd', d: d)) if d.positive?
33
- output.push(format('%<h>dh', h: h)) if h.positive?
34
- output.push(format('%<m>dm', m: m)) if m.positive?
35
- output.join(' ')
82
+ to_abbr(years: false, separator: ' ')
36
83
  when :hm
37
84
  h += d * 24 if d.positive?
38
85
  format('%<h> 4dh %<m>02dm', h: h, m: m)
@@ -40,25 +87,20 @@ module Doing
40
87
  h += d * 24 if d.positive?
41
88
  m += h * 60 if h.positive?
42
89
  format('%<m> 4dm', m: m)
90
+ when :tight
91
+ to_abbr(years: true, separator: '')
43
92
  when :natural
44
- human = []
45
- human.push(format('%<d>d %<s>s', d: d, s: 'day'.to_p(d))) if d.positive?
46
- human.push(format('%<h>d %<s>s', h: h, s: 'hour'.to_p(h))) if h.positive?
47
- human.push(format('%<m>d %<s>s', m: m, s: 'minute'.to_p(m))) if m.positive?
48
- human.join(', ')
93
+ to_natural.join(', ')
49
94
  when :speech
50
- human = []
51
- human.push(format('%<d>d %<s>s', d: d, s: 'day'.to_p(d))) if d.positive?
52
- human.push(format('%<h>d %<s>s', h: h, s: 'hour'.to_p(h))) if h.positive?
53
- human.push(format('%<m>d %<s>s', m: m, s: 'minute'.to_p(m))) if m.positive?
95
+ human = to_natural
54
96
  last = human.pop
55
97
  case human.count
56
- when 2
57
- human.join(', ') + ", and #{last}"
58
- when 1
59
- "#{human[0]} and #{last}"
60
98
  when 0
61
99
  last
100
+ when 1
101
+ "#{human[0]} and #{last}"
102
+ else
103
+ human.join(', ') + ", and #{last}"
62
104
  end
63
105
  end
64
106
  end