doing 2.1.12 → 2.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/.irbrc +1 -0
  3. data/.yardoc/checksums +16 -14
  4. data/.yardoc/object_types +0 -0
  5. data/.yardoc/objects/root.dat +0 -0
  6. data/CHANGELOG.md +67 -0
  7. data/Gemfile.lock +9 -2
  8. data/README.md +56 -19
  9. data/bin/doing +317 -113
  10. data/docs/doc/Array.html +117 -3
  11. data/docs/doc/BooleanTermParser/Clause.html +1 -1
  12. data/docs/doc/BooleanTermParser/Operator.html +1 -1
  13. data/docs/doc/BooleanTermParser/Query.html +1 -1
  14. data/docs/doc/BooleanTermParser/QueryParser.html +1 -1
  15. data/docs/doc/BooleanTermParser/QueryTransformer.html +1 -1
  16. data/docs/doc/BooleanTermParser.html +1 -1
  17. data/docs/doc/Doing/Color.html +1 -1
  18. data/docs/doc/Doing/Completion.html +1 -1
  19. data/docs/doc/Doing/Configuration.html +7 -4
  20. data/docs/doc/Doing/Errors/DoingNoTraceError.html +1 -1
  21. data/docs/doc/Doing/Errors/DoingRuntimeError.html +1 -1
  22. data/docs/doc/Doing/Errors/DoingStandardError.html +1 -1
  23. data/docs/doc/Doing/Errors/EmptyInput.html +1 -1
  24. data/docs/doc/Doing/Errors/NoResults.html +1 -1
  25. data/docs/doc/Doing/Errors/PluginException.html +1 -1
  26. data/docs/doc/Doing/Errors/UserCancelled.html +1 -1
  27. data/docs/doc/Doing/Errors/WrongCommand.html +1 -1
  28. data/docs/doc/Doing/Errors.html +1 -1
  29. data/docs/doc/Doing/Hooks.html +1 -1
  30. data/docs/doc/Doing/Item.html +337 -14
  31. data/docs/doc/Doing/Items.html +66 -2
  32. data/docs/doc/Doing/LogAdapter.html +1 -1
  33. data/docs/doc/Doing/Note.html +2 -2
  34. data/docs/doc/Doing/Pager.html +1 -1
  35. data/docs/doc/Doing/Plugins.html +1 -1
  36. data/docs/doc/Doing/Prompt.html +103 -1
  37. data/docs/doc/Doing/Section.html +1 -1
  38. data/docs/doc/Doing/TemplateString.html +2 -2
  39. data/docs/doc/Doing/Util/Backup.html +84 -1
  40. data/docs/doc/Doing/Util.html +1 -1
  41. data/docs/doc/Doing/WWID.html +214 -35
  42. data/docs/doc/Doing.html +3 -3
  43. data/docs/doc/GLI/Commands/MarkdownDocumentListener.html +1 -1
  44. data/docs/doc/GLI/Commands.html +1 -1
  45. data/docs/doc/GLI.html +1 -1
  46. data/docs/doc/Hash.html +1 -1
  47. data/docs/doc/Numeric.html +279 -0
  48. data/docs/doc/PhraseParser/Operator.html +1 -1
  49. data/docs/doc/PhraseParser/PhraseClause.html +1 -1
  50. data/docs/doc/PhraseParser/Query.html +1 -1
  51. data/docs/doc/PhraseParser/QueryParser.html +1 -1
  52. data/docs/doc/PhraseParser/QueryTransformer.html +1 -1
  53. data/docs/doc/PhraseParser/TermClause.html +1 -1
  54. data/docs/doc/PhraseParser.html +1 -1
  55. data/docs/doc/Status.html +1 -1
  56. data/docs/doc/String.html +881 -138
  57. data/docs/doc/Symbol.html +1 -1
  58. data/docs/doc/Time.html +1 -1
  59. data/docs/doc/_index.html +14 -9
  60. data/docs/doc/class_list.html +1 -1
  61. data/docs/doc/file.README.html +41 -15
  62. data/docs/doc/index.html +41 -15
  63. data/docs/doc/method_list.html +408 -256
  64. data/docs/doc/top-level-namespace.html +2 -2
  65. data/docs/index.md +56 -19
  66. data/doing.gemspec +2 -0
  67. data/doing.rdoc +257 -48
  68. data/example_plugin.rb +2 -4
  69. data/lib/completion/_doing.zsh +31 -27
  70. data/lib/completion/doing.bash +50 -39
  71. data/lib/completion/doing.fish +37 -7
  72. data/lib/doing/array_chronify.rb +57 -0
  73. data/lib/doing/configuration.rb +4 -1
  74. data/lib/doing/item.rb +176 -0
  75. data/lib/doing/log_adapter.rb +1 -1
  76. data/lib/doing/numeric_chronify.rb +40 -0
  77. data/lib/doing/plugins/export/dayone_export.rb +1 -1
  78. data/lib/doing/plugins/export/json_export.rb +2 -2
  79. data/lib/doing/plugins/export/template_export.rb +47 -90
  80. data/lib/doing/plugins/import/calendar_import.rb +13 -1
  81. data/lib/doing/plugins/import/doing_import.rb +12 -1
  82. data/lib/doing/plugins/import/timing_import.rb +13 -1
  83. data/lib/doing/prompt.rb +54 -1
  84. data/lib/doing/string.rb +97 -33
  85. data/lib/doing/string_chronify.rb +112 -14
  86. data/lib/doing/template_string.rb +1 -1
  87. data/lib/doing/time.rb +6 -6
  88. data/lib/doing/util_backup.rb +1 -1
  89. data/lib/doing/version.rb +1 -1
  90. data/lib/doing/wwid.rb +128 -103
  91. data/lib/doing.rb +36 -31
  92. data/lib/examples/plugins/say_export.rb +1 -4
  93. metadata +46 -2
@@ -89,6 +89,7 @@ complete -xc doing -n '__fish_doing_needs_command' -a 'select' -d Display\ an\ i
89
89
  complete -xc doing -n '__fish_doing_needs_command' -a 'show' -d List\ all\ entries
90
90
  complete -xc doing -n '__fish_doing_needs_command' -a 'since' -d List\ entries\ since\ a\ date
91
91
  complete -xc doing -n '__fish_doing_needs_command' -a 'tag' -d Add\ tag\(s\)\ to\ last\ entry
92
+ complete -xc doing -n '__fish_doing_needs_command' -a 'tag_dir' -d Set\ the\ default\ tags\ for\ the\ current\ directory
92
93
  complete -xc doing -n '__fish_doing_needs_command' -a 'tags' -d List\ all\ tags\ in\ the\ current\ Doing\ file
93
94
  complete -xc doing -n '__fish_doing_needs_command' -a 'template' -d Output\ HTML
94
95
  complete -xc doing -n '__fish_doing_needs_command' -a 'test' -d Test\ Stuff
@@ -98,16 +99,18 @@ complete -xc doing -n '__fish_doing_needs_command' -a 'view' -d Display\ a\ user
98
99
  complete -xc doing -n '__fish_doing_needs_command' -a 'views' -d List\ available\ custom\ views
99
100
  complete -xc doing -n '__fish_doing_needs_command' -a 'wiki' -d Output\ a\ tag\ wiki
100
101
  complete -xc doing -n '__fish_doing_needs_command' -a 'yesterday' -d List\ entries\ from\ yesterday
102
+ complete -c doing -l ask -f -n '__fish_doing_using_command again resume' -d Prompt\ for\ note\ via\ multi-line\ input
101
103
  complete -c doing -l bool -f -r -n '__fish_doing_using_command again resume' -d Boolean\ used\ to\ combine\ multiple\ tags
102
104
  complete -c doing -l case -f -r -n '__fish_doing_using_command again resume' -d Case\ sensitivity\ for\ search\ string\ matching\ \[\(c\)ase-sensitive
103
105
  complete -c doing -l editor -s e -f -n '__fish_doing_using_command again resume' -d Edit\ duplicated\ entry\ with\ vim\ before\ adding
104
106
  complete -c doing -l interactive -s i -f -n '__fish_doing_using_command again resume' -d Select\ item\ to\ resume\ from\ a\ menu\ of\ matching\ entries
105
107
  complete -c doing -l in -f -r -n '__fish_doing_using_command again resume' -d Add\ new\ entry\ to\ section
106
- complete -c doing -l note -s n -f -r -n '__fish_doing_using_command again resume' -d Note
108
+ complete -c doing -l note -s n -f -r -n '__fish_doing_using_command again resume' -d Add\ a\ note
107
109
  complete -c doing -l not -f -n '__fish_doing_using_command again resume' -d Resume\ items\ that\ \*don\'t\*\ match\ search/tag\ filters
108
110
  complete -c doing -l section -s s -f -r -n '__fish_doing_using_command again resume' -d Get\ last\ entry\ from\ a\ specific\ section
109
111
  complete -c doing -l search -f -r -n '__fish_doing_using_command again resume' -d Repeat\ last\ entry\ matching\ search
110
112
  complete -c doing -l tag -f -r -n '__fish_doing_using_command again resume' -d Repeat\ last\ entry\ matching\ tags
113
+ complete -c doing -l val -f -r -n '__fish_doing_using_command again resume' -d Perform\ a\ tag\ value\ query
111
114
  complete -c doing -l exact -s x -f -n '__fish_doing_using_command again resume' -d Force\ exact\ search\ string\ matching
112
115
  complete -c doing -l before -f -r -n '__fish_doing_using_command archive move' -d Archive\ entries\ older\ than\ date
113
116
  complete -c doing -l bool -f -r -n '__fish_doing_using_command archive move' -d Tag\ boolean
@@ -118,6 +121,7 @@ complete -c doing -l not -f -n '__fish_doing_using_command archive move' -d Sh
118
121
  complete -c doing -l search -f -r -n '__fish_doing_using_command archive move' -d Search\ filter
119
122
  complete -c doing -l to -s t -f -r -n '__fish_doing_using_command archive move' -d Move\ entries\ to
120
123
  complete -c doing -l tag -f -r -n '__fish_doing_using_command archive move' -d Tag\ filter
124
+ complete -c doing -l val -f -r -n '__fish_doing_using_command archive move' -d Perform\ a\ tag\ value\ query
121
125
  complete -c doing -l exact -s x -f -n '__fish_doing_using_command archive move' -d Force\ exact\ search\ string\ matching
122
126
  complete -c doing -l bool -f -r -n '__fish_doing_using_command autotag' -d Boolean
123
127
  complete -c doing -l count -s c -f -r -n '__fish_doing_using_command autotag' -d How\ many\ recent\ entries\ to\ autotag
@@ -136,20 +140,23 @@ complete -c doing -l section -s s -f -r -n '__fish_doing_using_command cancel' -
136
140
  complete -c doing -l search -f -r -n '__fish_doing_using_command cancel' -d Cancel\ the\ last\ X\ entries\ matching\ search\ filter
137
141
  complete -c doing -l tag -f -r -n '__fish_doing_using_command cancel' -d Cancel\ the\ last\ X\ entries\ containing\ TAG
138
142
  complete -c doing -l unfinished -s u -f -n '__fish_doing_using_command cancel' -d Cancel\ last\ entry
143
+ complete -c doing -l val -f -r -n '__fish_doing_using_command cancel' -d Perform\ a\ tag\ value\ query
139
144
  complete -c doing -l exact -s x -f -n '__fish_doing_using_command cancel' -d Force\ exact\ search\ string\ matching
140
145
  complete -c doing -l file -s f -f -r -n '__fish_doing_using_command completion' -d File\ to\ write\ output\ to
141
146
  complete -c doing -l type -s t -f -r -n '__fish_doing_using_command completion' -d Shell\ to\ generate\ for
142
147
  complete -c doing -l dump -s d -f -n '__fish_doing_using_command config' -d DEPRECATED
143
148
  complete -c doing -l update -s u -f -n '__fish_doing_using_command config' -d DEPRECATED
144
149
  complete -c doing -l archive -s a -f -n '__fish_doing_using_command done did' -d Immediately\ archive\ the\ entry
145
- complete -c doing -l at -f -r -n '__fish_doing_using_command done did' -d Set\ finish\ date\ to\ specific\ date/time
150
+ complete -c doing -l ask -f -n '__fish_doing_using_command done did' -d Prompt\ for\ note\ via\ multi-line\ input
151
+ complete -c doing -l finished -f -r -n '__fish_doing_using_command done did' -d Set\ finish\ date\ to\ specific\ date/time
146
152
  complete -c doing -l started -f -r -n '__fish_doing_using_command done did' -d Backdate\ start\ date\ by\ interval\ or\ set\ to\ time\ \[4pm\|20m\|2h\|\"yesterday\ noon\"\]
147
153
  complete -c doing -l date -f -n '__fish_doing_using_command done did' -d Include\ date
148
154
  complete -c doing -l editor -s e -f -n '__fish_doing_using_command done did' -d Edit\ entry\ with\ vim
155
+ complete -c doing -l from -f -r -n '__fish_doing_using_command done did' -d Start\ and\ end\ times\ as\ a\ date/time\ range\ \`doing\ done\ --from\ \"1am\ to\ 8am\"\`
149
156
  complete -c doing -l note -s n -f -r -n '__fish_doing_using_command done did' -d Include\ a\ note
150
157
  complete -c doing -l remove -s r -f -n '__fish_doing_using_command done did' -d Remove\ @done\ tag
151
158
  complete -c doing -l section -s s -f -r -n '__fish_doing_using_command done did' -d Section
152
- complete -c doing -l took -s t -f -r -n '__fish_doing_using_command done did' -d Set\ completion\ date\ to\ start\ date\ plus\ interval
159
+ complete -c doing -l for -f -r -n '__fish_doing_using_command done did' -d Set\ completion\ date\ to\ start\ date\ plus\ interval
153
160
  complete -c doing -l unfinished -s u -f -n '__fish_doing_using_command done did' -d Finish\ last\ entry\ not\ already\ marked\ @done
154
161
  complete -c doing -l archive -s a -f -n '__fish_doing_using_command finish' -d Archive\ entries
155
162
  complete -c doing -l at -f -r -n '__fish_doing_using_command finish' -d Set\ finish\ date\ to\ specific\ date/time
@@ -163,14 +170,18 @@ complete -c doing -l not -f -n '__fish_doing_using_command finish' -d Finish\
163
170
  complete -c doing -l remove -s r -f -n '__fish_doing_using_command finish' -d Remove\ done\ tag
164
171
  complete -c doing -l section -s s -f -r -n '__fish_doing_using_command finish' -d Section
165
172
  complete -c doing -l search -f -r -n '__fish_doing_using_command finish' -d Finish\ the\ last\ X\ entries\ matching\ search\ filter
166
- complete -c doing -l took -s t -f -r -n '__fish_doing_using_command finish' -d Set\ the\ completed\ date\ to\ the\ start\ date\ plus\ XX\[hmd\]
173
+ 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\]
167
174
  complete -c doing -l tag -f -r -n '__fish_doing_using_command finish' -d Finish\ the\ last\ X\ entries\ containing\ TAG
168
175
  complete -c doing -l unfinished -s u -f -n '__fish_doing_using_command finish' -d Finish\ last\ entry
176
+ complete -c doing -l val -f -r -n '__fish_doing_using_command finish' -d Perform\ a\ tag\ value\ query
169
177
  complete -c doing -l exact -s x -f -n '__fish_doing_using_command finish' -d Force\ exact\ search\ string\ matching
170
178
  complete -c doing -l after -f -r -n '__fish_doing_using_command grep search' -d Search\ entries\ newer\ than\ date
171
179
  complete -c doing -l before -f -r -n '__fish_doing_using_command grep search' -d Search\ entries\ older\ than\ date
180
+ complete -c doing -l bool -f -r -n '__fish_doing_using_command grep search' -d Combine\ multiple\ tags\ or\ value\ queries\ using\ AND
172
181
  complete -c doing -l case -f -r -n '__fish_doing_using_command grep search' -d Case\ sensitivity\ for\ search\ string\ matching\ \[\(c\)ase-sensitive
182
+ complete -c doing -l delete -s d -f -n '__fish_doing_using_command grep search' -d Delete\ matching\ entries
173
183
  complete -c doing -l duration -f -n '__fish_doing_using_command grep search' -d Show\ elapsed\ time\ on\ entries\ without\ @done\ tag
184
+ complete -c doing -l editor -s e -f -n '__fish_doing_using_command grep search' -d Edit\ matching\ entries\ with\ vim
174
185
  complete -c doing -l from -f -r -n '__fish_doing_using_command grep search' -d Date\ range\ to\ show
175
186
  complete -c doing -l interactive -s i -f -n '__fish_doing_using_command grep search' -d Display\ an\ interactive\ menu\ of\ results\ to\ perform\ further\ operations
176
187
  complete -c doing -l not -f -n '__fish_doing_using_command grep search' -d Show\ items\ that\ \*don\'t\*\ match\ search\ string
@@ -180,6 +191,7 @@ complete -c doing -l section -s s -f -r -n '__fish_doing_using_command grep sear
180
191
  complete -c doing -l times -s t -f -n '__fish_doing_using_command grep search' -d Show\ time\ intervals\ on\ @done\ tasks
181
192
  complete -c doing -l tag_sort -f -r -n '__fish_doing_using_command grep search' -d Sort\ tags\ by
182
193
  complete -c doing -l totals -f -n '__fish_doing_using_command grep search' -d Show\ intervals\ with\ totals\ at\ the\ end\ of\ output
194
+ complete -c doing -l val -f -r -n '__fish_doing_using_command grep search' -d Perform\ a\ tag\ value\ query
183
195
  complete -c doing -l exact -s x -f -n '__fish_doing_using_command grep search' -d Force\ exact\ string\ matching
184
196
  complete -c doing -F -n '__fish_doing_using_command import'
185
197
  complete -c doing -l after -f -r -n '__fish_doing_using_command import' -d Import\ entries\ newer\ than\ date
@@ -193,18 +205,21 @@ complete -c doing -l overlap -f -n '__fish_doing_using_command import' -d Allo
193
205
  complete -c doing -l prefix -f -r -n '__fish_doing_using_command import' -d Prefix\ entries\ with
194
206
  complete -c doing -l section -s s -f -r -n '__fish_doing_using_command import' -d Target\ section
195
207
  complete -c doing -l search -f -r -n '__fish_doing_using_command import' -d Only\ import\ items\ matching\ search
196
- complete -c doing -l tag -f -r -n '__fish_doing_using_command import' -d Tag\ all\ imported\ entries
208
+ complete -c doing -l tag -s t -f -r -n '__fish_doing_using_command import' -d Tag\ all\ imported\ entries
197
209
  complete -c doing -l type -f -r -n '__fish_doing_using_command import' -d Import\ type
198
210
  complete -c doing -l exact -s x -f -n '__fish_doing_using_command import' -d Force\ exact\ search\ string\ matching
199
211
  complete -c doing -l bool -f -r -n '__fish_doing_using_command last' -d Tag\ boolean
200
212
  complete -c doing -l case -f -r -n '__fish_doing_using_command last' -d Case\ sensitivity\ for\ search\ string\ matching\ \[\(c\)ase-sensitive
213
+ complete -c doing -l delete -s d -f -n '__fish_doing_using_command last' -d Delete\ the\ last\ entry
201
214
  complete -c doing -l duration -f -n '__fish_doing_using_command last' -d Show\ elapsed\ time\ if\ entry\ is\ not\ tagged\ @done
202
215
  complete -c doing -l editor -s e -f -n '__fish_doing_using_command last' -d Edit\ entry\ with\ vim
203
216
  complete -c doing -l not -f -n '__fish_doing_using_command last' -d Show\ items\ that\ \*don\'t\*\ match\ search\ string\ or\ tag\ filter
204
217
  complete -c doing -l section -s s -f -r -n '__fish_doing_using_command last' -d Specify\ a\ section
205
218
  complete -c doing -l search -f -r -n '__fish_doing_using_command last' -d Search\ filter
206
219
  complete -c doing -l tag -f -r -n '__fish_doing_using_command last' -d Tag\ filter
220
+ complete -c doing -l val -f -r -n '__fish_doing_using_command last' -d Perform\ a\ tag\ value\ query
207
221
  complete -c doing -l exact -s x -f -n '__fish_doing_using_command last' -d Force\ exact\ search\ string\ matching
222
+ complete -c doing -l ask -f -n '__fish_doing_using_command later' -d Prompt\ for\ note\ via\ multi-line\ input
208
223
  complete -c doing -l back -s b -f -r -n '__fish_doing_using_command later' -d Backdate\ start\ time\ to\ date\ string\ \[4pm\|20m\|2h\|yesterday\ noon\]
209
224
  complete -c doing -l editor -s e -f -n '__fish_doing_using_command later' -d Edit\ entry\ with\ vim
210
225
  complete -c doing -l note -s n -f -r -n '__fish_doing_using_command later' -d Note
@@ -220,12 +235,15 @@ complete -c doing -l section -s s -f -r -n '__fish_doing_using_command mark flag
220
235
  complete -c doing -l search -f -r -n '__fish_doing_using_command mark flag' -d Flag\ the\ last\ entry\ matching\ search\ filter
221
236
  complete -c doing -l tag -f -r -n '__fish_doing_using_command mark flag' -d Flag\ the\ last\ entry\ containing\ TAG
222
237
  complete -c doing -l unfinished -s u -f -n '__fish_doing_using_command mark flag' -d Flag\ last\ entry
238
+ complete -c doing -l val -f -r -n '__fish_doing_using_command mark flag' -d Perform\ a\ tag\ value\ query
223
239
  complete -c doing -l exact -s x -f -n '__fish_doing_using_command mark flag' -d Force\ exact\ search\ string\ matching
224
240
  complete -c doing -l archive -s a -f -n '__fish_doing_using_command meanwhile' -d Archive\ previous\ @meanwhile\ entry
241
+ complete -c doing -l ask -f -n '__fish_doing_using_command meanwhile' -d Prompt\ for\ note\ via\ multi-line\ input
225
242
  complete -c doing -l back -s b -f -r -n '__fish_doing_using_command meanwhile' -d Backdate\ start\ date\ for\ new\ entry\ to\ date\ string\ \[4pm\|20m\|2h\|yesterday\ noon\]
226
243
  complete -c doing -l editor -s e -f -n '__fish_doing_using_command meanwhile' -d Edit\ entry\ with\ vim
227
244
  complete -c doing -l note -s n -f -r -n '__fish_doing_using_command meanwhile' -d Note
228
245
  complete -c doing -l section -s s -f -r -n '__fish_doing_using_command meanwhile' -d Section
246
+ complete -c doing -l ask -f -n '__fish_doing_using_command note' -d Prompt\ for\ note\ via\ multi-line\ input
229
247
  complete -c doing -l bool -f -r -n '__fish_doing_using_command note' -d Boolean
230
248
  complete -c doing -l case -f -r -n '__fish_doing_using_command note' -d Case\ sensitivity\ for\ search\ string\ matching\ \[\(c\)ase-sensitive
231
249
  complete -c doing -l editor -s e -f -n '__fish_doing_using_command note' -d Edit\ entry\ with\ vim
@@ -235,7 +253,9 @@ complete -c doing -l remove -s r -f -n '__fish_doing_using_command note' -d Rep
235
253
  complete -c doing -l section -s s -f -r -n '__fish_doing_using_command note' -d Section
236
254
  complete -c doing -l search -f -r -n '__fish_doing_using_command note' -d Add/remove\ note\ from\ last\ entry\ matching\ search\ filter
237
255
  complete -c doing -l tag -f -r -n '__fish_doing_using_command note' -d Add/remove\ note\ from\ last\ entry\ matching\ tag
256
+ complete -c doing -l val -f -r -n '__fish_doing_using_command note' -d Perform\ a\ tag\ value\ query
238
257
  complete -c doing -l exact -s x -f -n '__fish_doing_using_command note' -d Force\ exact\ search\ string\ matching
258
+ complete -c doing -l ask -f -n '__fish_doing_using_command now next' -d Prompt\ for\ note\ via\ multi-line\ input
239
259
  complete -c doing -l started -f -r -n '__fish_doing_using_command now next' -d Backdate\ start\ time\ \[4pm\|20m\|2h\|\"yesterday\ noon\"\]
240
260
  complete -c doing -l editor -s e -f -n '__fish_doing_using_command now next' -d Edit\ entry\ with\ vim
241
261
  complete -c doing -l finish_last -s f -f -n '__fish_doing_using_command now next' -d Timed\ entry
@@ -266,6 +286,7 @@ complete -c doing -l resume -s r -f -n '__fish_doing_using_command reset begin'
266
286
  complete -c doing -l section -s s -f -r -n '__fish_doing_using_command reset begin' -d Limit\ search\ to\ section
267
287
  complete -c doing -l search -f -r -n '__fish_doing_using_command reset begin' -d Reset\ last\ entry\ matching\ search\ filter
268
288
  complete -c doing -l tag -f -r -n '__fish_doing_using_command reset begin' -d Reset\ last\ entry\ matching\ tag
289
+ complete -c doing -l val -f -r -n '__fish_doing_using_command reset begin' -d Perform\ a\ tag\ value\ query
269
290
  complete -c doing -l exact -s x -f -n '__fish_doing_using_command reset begin' -d Force\ exact\ search\ string\ matching
270
291
  complete -c doing -l before -f -r -n '__fish_doing_using_command rotate' -d Rotate\ entries\ older\ than\ date
271
292
  complete -c doing -l bool -f -r -n '__fish_doing_using_command rotate' -d Tag\ boolean
@@ -275,6 +296,7 @@ complete -c doing -l not -f -n '__fish_doing_using_command rotate' -d Rotate\
275
296
  complete -c doing -l section -s s -f -r -n '__fish_doing_using_command rotate' -d Section\ to\ rotate
276
297
  complete -c doing -l search -f -r -n '__fish_doing_using_command rotate' -d Search\ filter
277
298
  complete -c doing -l tag -f -r -n '__fish_doing_using_command rotate' -d Tag\ filter
299
+ complete -c doing -l val -f -r -n '__fish_doing_using_command rotate' -d Perform\ a\ tag\ value\ query
278
300
  complete -c doing -l exact -s x -f -n '__fish_doing_using_command rotate' -d Force\ exact\ search\ string\ matching
279
301
  complete -c doing -l column -s c -f -n '__fish_doing_using_command sections' -d List\ in\ single\ column
280
302
  complete -c doing -l archive -s a -f -n '__fish_doing_using_command select' -d Archive\ selected\ items
@@ -293,11 +315,13 @@ complete -c doing -l move -s m -f -r -n '__fish_doing_using_command select' -d M
293
315
  complete -c doing -l menu -f -n '__fish_doing_using_command select' -d Use\ --no-menu\ to\ skip\ the\ interactive\ menu
294
316
  complete -c doing -l not -f -n '__fish_doing_using_command select' -d Select\ items\ that\ \*don\'t\*\ match\ search/tag\ filters
295
317
  complete -c doing -l output -s o -f -r -n '__fish_doing_using_command select' -d Output\ entries\ to\ format
296
- complete -c doing -l search -f -r -n '__fish_doing_using_command select' -d Initial\ search\ query\ for\ filtering
318
+ complete -c doing -l query -s q -f -r -n '__fish_doing_using_command select' -d Initial\ search\ query\ for\ filtering
297
319
  complete -c doing -l remove -s r -f -n '__fish_doing_using_command select' -d Reverse\ -c
298
320
  complete -c doing -l section -s s -f -r -n '__fish_doing_using_command select' -d Select\ from\ a\ specific\ section
299
321
  complete -c doing -l save_to -f -r -n '__fish_doing_using_command select' -d Save\ selected\ entries\ to\ file\ using\ --output\ format
322
+ complete -c doing -l search -f -r -n '__fish_doing_using_command select' -d Select\ from\ entries\ matching\ search\ filter
300
323
  complete -c doing -l tag -s t -f -r -n '__fish_doing_using_command select' -d Tag\ selected\ entries
324
+ complete -c doing -l val -f -r -n '__fish_doing_using_command select' -d Perform\ a\ tag\ value\ query
301
325
  complete -c doing -l exact -s x -f -n '__fish_doing_using_command select' -d Force\ exact\ search\ string\ matching
302
326
  complete -c doing -l age -s a -f -r -n '__fish_doing_using_command show' -d Age
303
327
  complete -c doing -l after -f -r -n '__fish_doing_using_command show' -d Show\ entries\ newer\ than\ date
@@ -319,6 +343,7 @@ complete -c doing -l tag -f -r -n '__fish_doing_using_command show' -d Tag\ fil
319
343
  complete -c doing -l tag_order -f -r -n '__fish_doing_using_command show' -d Tag\ sort\ direction
320
344
  complete -c doing -l tag_sort -f -r -n '__fish_doing_using_command show' -d Sort\ tags\ by
321
345
  complete -c doing -l totals -f -n '__fish_doing_using_command show' -d Show\ intervals\ with\ totals\ at\ the\ end\ of\ output
346
+ complete -c doing -l val -f -r -n '__fish_doing_using_command show' -d Perform\ a\ tag\ value\ query
322
347
  complete -c doing -l exact -s x -f -n '__fish_doing_using_command show' -d Force\ exact\ search\ string\ matching
323
348
  complete -c doing -l duration -f -n '__fish_doing_using_command since' -d Show\ elapsed\ time\ on\ entries\ without\ @done\ tag
324
349
  complete -c doing -l output -s o -f -r -n '__fish_doing_using_command since' -d Output\ to\ export\ format
@@ -341,7 +366,10 @@ complete -c doing -l section -s s -f -r -n '__fish_doing_using_command tag' -d S
341
366
  complete -c doing -l search -f -r -n '__fish_doing_using_command tag' -d Tag\ entries\ matching\ search\ filter
342
367
  complete -c doing -l tag -f -r -n '__fish_doing_using_command tag' -d Tag\ the\ last\ X\ entries\ containing\ TAG
343
368
  complete -c doing -l unfinished -s u -f -n '__fish_doing_using_command tag' -d Tag\ last\ entry
369
+ complete -c doing -l value -s v -f -r -n '__fish_doing_using_command tag' -d Include\ a\ value
370
+ complete -c doing -l val -f -r -n '__fish_doing_using_command tag' -d Perform\ a\ tag\ value\ query
344
371
  complete -c doing -l exact -s x -f -n '__fish_doing_using_command tag' -d Force\ exact\ search\ string\ matching
372
+ complete -c doing -l remove -s r -f -n '__fish_doing_using_command tag_dir' -d Remove\ all\ default_tags\ from\ the\ local
345
373
  complete -c doing -l bool -f -r -n '__fish_doing_using_command tags' -d Boolean\ used\ to\ combine\ multiple\ tags
346
374
  complete -c doing -l counts -s c -f -n '__fish_doing_using_command tags' -d Show\ count\ of\ occurrences
347
375
  complete -c doing -l case -f -r -n '__fish_doing_using_command tags' -d Case\ sensitivity\ for\ search\ string\ matching\ \[\(c\)ase-sensitive
@@ -352,6 +380,7 @@ complete -c doing -l section -s s -f -r -n '__fish_doing_using_command tags' -d
352
380
  complete -c doing -l search -f -r -n '__fish_doing_using_command tags' -d Get\ tags\ for\ items\ matching\ search
353
381
  complete -c doing -l sort -f -r -n '__fish_doing_using_command tags' -d Sort\ by\ name\ or\ count
354
382
  complete -c doing -l tag -f -r -n '__fish_doing_using_command tags' -d Get\ tags\ for\ entries\ matching\ tags
383
+ complete -c doing -l val -f -r -n '__fish_doing_using_command tags' -d Perform\ a\ tag\ value\ query
355
384
  complete -c doing -l exact -s x -f -n '__fish_doing_using_command tags' -d Force\ exact\ search\ string\ matching
356
385
  complete -c doing -l column -s c -f -n '__fish_doing_using_command template' -d List\ in\ single\ column\ for\ completion
357
386
  complete -c doing -l list -s l -f -n '__fish_doing_using_command template' -d List\ all\ available\ templates
@@ -390,6 +419,7 @@ complete -c doing -l tag -f -r -n '__fish_doing_using_command view' -d Tag\ fil
390
419
  complete -c doing -l tag_order -f -r -n '__fish_doing_using_command view' -d Tag\ sort\ direction
391
420
  complete -c doing -l tag_sort -f -r -n '__fish_doing_using_command view' -d Sort\ tags\ by
392
421
  complete -c doing -l totals -f -n '__fish_doing_using_command view' -d Show\ intervals\ with\ totals\ at\ the\ end\ of\ output
422
+ complete -c doing -l val -f -r -n '__fish_doing_using_command view' -d Perform\ a\ tag\ value\ query
393
423
  complete -c doing -l exact -s x -f -n '__fish_doing_using_command view' -d Force\ exact\ search\ string\ matching
394
424
  complete -c doing -l column -s c -f -n '__fish_doing_using_command views' -d List\ in\ single\ column
395
425
  complete -c doing -l after -f -r -n '__fish_doing_using_command wiki' -d Include\ entries\ newer\ than\ date
@@ -411,7 +441,7 @@ complete -c doing -l tag_order -f -r -n '__fish_doing_using_command yesterday'
411
441
  complete -c doing -l tag_sort -f -r -n '__fish_doing_using_command yesterday' -d Sort\ tags\ by
412
442
  complete -c doing -l totals -f -n '__fish_doing_using_command yesterday' -d Show\ time\ totals\ at\ the\ end\ of\ output
413
443
  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_plugins)'
414
- complete -f -c doing -s b -l bool -x -n '__fish_doing_using_command again resume archive move autotag cancel finish last mark flag note reset begin rotate show tag tags view wiki' -a 'and or not pattern'
444
+ 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 reset begin rotate show tag tags view wiki' -a 'and or not pattern'
415
445
  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 reset begin rotate select show show tag tags tags view' -a 'case-sensitive ignore smart'
416
446
  complete -f -c doing -l tag_sort -x -n '__fish_doing_using_command grep search on recent show since today view yesterday' -a 'name time'
417
447
  complete -f -c doing -l tag_order -x -n '__fish_doing_using_command show view yesterday' -a 'asc desc'
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doing
4
+ # Chronify array helpers
5
+ class ::Array
6
+ ##
7
+ ## Format [d, h, m] as string
8
+ ##
9
+ ## @param time [Array] Array of [days, hours,
10
+ ## minutes]
11
+ ## @param format [Symbol] The format, :dhm, :hm, :m, :clock, :natural
12
+ ## @return [String] formatted string
13
+ ##
14
+ def time_string(format: :dhm)
15
+ raise InvalidArgument, 'Invalid array, must be [d,h,m]' unless count == 3
16
+
17
+ d, h, m = self
18
+ case format
19
+ when :clock
20
+ format('%<d>02d:%<h>02d:%<m>02d', d: d, h: h, m: m)
21
+ when :dhm
22
+ output = []
23
+ output.push(format('%<d>dd', d: d)) if d.positive?
24
+ output.push(format('%<h>dh', h: h)) if h.positive?
25
+ output.push(format('%<m>dm', m: m)) if m.positive?
26
+ output.join(' ')
27
+ when :hm
28
+ h += d * 24 if d.positive?
29
+ format('%<h> 4dh %<m>02dm', h: h, m: m)
30
+ when :m
31
+ h += d * 24 if d.positive?
32
+ m += h * 60 if h.positive?
33
+ format('%<m> 4dm', m: m)
34
+ when :natural
35
+ human = []
36
+ human.push(format('%<d>d %<s>s', d: d, s: 'day'.to_p(d))) if d.positive?
37
+ human.push(format('%<h>d %<s>s', h: h, s: 'hour'.to_p(h))) if h.positive?
38
+ human.push(format('%<m>d %<s>s', m: m, s: 'minute'.to_p(m))) if m.positive?
39
+ human.join(', ')
40
+ when :speech
41
+ human = []
42
+ human.push(format('%<d>d %<s>s', d: d, s: 'day'.to_p(d))) if d.positive?
43
+ human.push(format('%<h>d %<s>s', h: h, s: 'hour'.to_p(h))) if h.positive?
44
+ human.push(format('%<m>d %<s>s', m: m, s: 'minute'.to_p(m))) if m.positive?
45
+ last = human.pop
46
+ case human.count
47
+ when 2
48
+ human.join(', ') + ", and #{last}"
49
+ when 1
50
+ "#{human[0]} and #{last}"
51
+ when 0
52
+ last
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -101,7 +101,10 @@ module Doing
101
101
  'distance' => 3,
102
102
  'case' => 'smart' # sensitive, ignore, smart
103
103
  },
104
- 'include_notes' => true
104
+ 'include_notes' => true,
105
+ 'interaction' => {
106
+ 'confirm_longer_than' => '5h'
107
+ }
105
108
  }
106
109
 
107
110
  def initialize(file = nil, options: {})
data/lib/doing/item.rb CHANGED
@@ -57,6 +57,25 @@ module Doing
57
57
  @end_date ||= Time.parse(Regexp.last_match(1)) if @title =~ /@done\((\d{4}-\d\d-\d\d \d\d:\d\d.*?)\)/
58
58
  end
59
59
 
60
+ def calculate_end_date(opt)
61
+ if opt[:took]
62
+ if @date + opt[:took] > Time.now
63
+ @date = Time.now - opt[:took]
64
+ Time.now
65
+ else
66
+ @date + opt[:took]
67
+ end
68
+ elsif opt[:back]
69
+ if opt[:back].is_a? Integer
70
+ @date + opt[:back]
71
+ else
72
+ @date + (opt[:back] - @date)
73
+ end
74
+ else
75
+ Time.now
76
+ end
77
+ end
78
+
60
79
  # Generate a hash that represents the entry
61
80
  #
62
81
  # @return [String] entry hash
@@ -112,6 +131,19 @@ module Doing
112
131
  (start_a >= start_b && start_a <= end_b) || (end_a >= start_b && end_a <= end_b) || (start_a < start_b && end_a > end_b)
113
132
  end
114
133
 
134
+ ##
135
+ ## Updates the title of the Item by expanding natural
136
+ ## language dates within configured date tags (tags
137
+ ## whose value is expected to be a date)
138
+ ##
139
+ ## @param additional_tags An array of additional
140
+ ## tag names to consider
141
+ ## dates
142
+ ##
143
+ def expand_date_tags(additional_tags = nil)
144
+ @title.expand_date_tags(additional_tags)
145
+ end
146
+
115
147
  ##
116
148
  ## Add (or remove) tags from the title of the item
117
149
  ##
@@ -162,6 +194,11 @@ module Doing
162
194
  @title.scan(/(?<= |\A)@([^\s(]+)/).map { |tag| tag[0] }.sort.uniq
163
195
  end
164
196
 
197
+ ##
198
+ ## convert tags on item to an array with @ symbols removed
199
+ ##
200
+ ## @return [Array] array of tags
201
+ ##
165
202
  def tag_array
166
203
  tags.tags_to_array
167
204
  end
@@ -197,6 +234,37 @@ module Doing
197
234
  negate ? !matches : matches
198
235
  end
199
236
 
237
+ ##
238
+ ## Test if item matches tag values
239
+ ##
240
+ ## @param queries (Array) The tag value queries to test
241
+ ## @param bool (Symbol) The boolean to use for multiple tags (:and, :or, :not)
242
+ ## @param negate [Boolean] negate the result?
243
+ ##
244
+ ## @return [Boolean] true if tag/bool combination passes
245
+ ##
246
+ def tag_values?(queries, bool = :and, negate: false)
247
+ bool = bool.normalize_bool
248
+
249
+ matches = case bool
250
+ when :and
251
+ all_values?(queries)
252
+ when :not
253
+ no_values?(queries)
254
+ else
255
+ any_values?(queries)
256
+ end
257
+ negate ? !matches : matches
258
+ end
259
+
260
+ ##
261
+ ## Determine if case should be ignored for searches
262
+ ##
263
+ ## @param search [String] The search string
264
+ ## @param case_type [Symbol] The case type
265
+ ##
266
+ ## @return [Boolean] case should be ignored
267
+ ##
200
268
  def ignore_case(search, case_type)
201
269
  (case_type == :smart && search !~ /[A-Z]/) || case_type == :ignore
202
270
  end
@@ -256,10 +324,22 @@ module Doing
256
324
  negate ? !matches : matches
257
325
  end
258
326
 
327
+ ##
328
+ ## Test if item is included in never_finish config and
329
+ ## thus should not receive a @done tag
330
+ ##
331
+ ## @return [Boolean] item should receive @done tag
332
+ ##
259
333
  def should_finish?
260
334
  should?('never_finish')
261
335
  end
262
336
 
337
+ ##
338
+ ## Test if item is included in never_time config and
339
+ ## thus should not receive a date on the @done tag
340
+ ##
341
+ ## @return [Boolean] item should receive @done date
342
+ ##
263
343
  def should_time?
264
344
  should?('never_time')
265
345
  end
@@ -385,6 +465,102 @@ module Doing
385
465
  false
386
466
  end
387
467
 
468
+ def tag_value(tag)
469
+ res = @title.match(/@#{tag.sub(/^@/, '').wildcard_to_rx}\((.*?)\)/)
470
+ res ? res[1] : nil
471
+ end
472
+
473
+ def number_or_date(value)
474
+ return nil unless value
475
+
476
+ if value.strip =~ /^[0-9.]+%?$/
477
+ value.strip.to_f
478
+ else
479
+ value.strip.chronify(guess: :end)
480
+ end
481
+ end
482
+
483
+ def split_value_query(query)
484
+ val_rx = /^(!)?@?(\S+) +(!?[<>=][=*]?|[$*^]=) +(.*?)$/
485
+ query.match(val_rx)
486
+ end
487
+
488
+ def any_values?(queries)
489
+ return true if queries.nil? || queries.empty?
490
+
491
+ queries.each do |q|
492
+ parts = split_value_query(q)
493
+ return true if tag_value_matches?(parts[2], parts[3], parts[4], parts[1])
494
+ end
495
+ false
496
+ end
497
+
498
+ def all_values?(queries)
499
+ return true if queries.nil? || queries.empty?
500
+
501
+ queries.each do |q|
502
+ parts = split_value_query(q)
503
+ return false unless tag_value_matches?(parts[2], parts[3], parts[4], parts[1])
504
+ end
505
+ true
506
+ end
507
+
508
+ def no_values?(queries)
509
+ return true if queries.nil? || queries.empty?
510
+
511
+ queries.each do |q|
512
+ parts = split_value_query(q)
513
+ return false if tag_value_matches?(parts[2], parts[3], parts[4], parts[1])
514
+ end
515
+ true
516
+ end
517
+
518
+ def tag_value_matches?(tag, comp, value, negate)
519
+ if all_tags?([tag])
520
+ tag_val = tag_value(tag)
521
+
522
+ if (value.chronify.nil? && value =~ /[a-z]/i && comp =~ /^!?==?$/) || comp =~ /[$*^]=/
523
+ is_match = case comp
524
+ when /\^=/
525
+ tag_val =~ /^#{value.wildcard_to_rx}/i
526
+ when /\$=/
527
+ tag_val =~ /#{value.wildcard_to_rx}$/i
528
+ when %r{==}
529
+ tag_val =~ /^#{value.wildcard_to_rx}$/i
530
+ else
531
+ tag_val =~ /#{value.wildcard_to_rx}/i
532
+ end
533
+
534
+ comp =~ /!/ || negate ? !is_match : is_match
535
+ else
536
+ tag_val = number_or_date(tag_val)
537
+ val = number_or_date(value)
538
+
539
+ return false if val.nil? || tag_val.nil?
540
+
541
+ return false unless val.class == tag_val.class
542
+
543
+ matches = case comp
544
+ when /^<$/
545
+ tag_val < val
546
+ when /^<=$/
547
+ tag_val <= val
548
+ when /^>$/
549
+ tag_val > val
550
+ when /^>=$/
551
+ tag_val >= val
552
+ when /^!=/
553
+ tag_val != val
554
+ when /^=/
555
+ tag_val == val
556
+ end
557
+ negate.nil? ? matches : !matches
558
+ end
559
+ else
560
+ false
561
+ end
562
+ end
563
+
388
564
  def to_query(query)
389
565
  parser = BooleanTermParser::QueryParser.new
390
566
  transformer = BooleanTermParser::QueryTransformer.new
@@ -52,7 +52,7 @@ module Doing
52
52
  COUNT_KEYS.each { |key| @counters[key] = { tag: [], count: 0 } }
53
53
  @results = []
54
54
  @logdev = $stderr
55
- @max_length = `tput cols`.strip.to_i - 5 || 85
55
+ @max_length = TTY::Screen.columns - 5 || 85
56
56
  self.log_level = level
57
57
  @prev_level = level
58
58
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doing
4
+ ##
5
+ ## Number helpers
6
+ ##
7
+ class ::Numeric
8
+ ##
9
+ ## Format human readable time from seconds
10
+ ##
11
+ ## @param seconds [Integer] Seconds
12
+ ##
13
+ def format_time(human: false)
14
+ return [0, 0, 0] if nil?
15
+
16
+ seconds = dup.to_i
17
+ minutes = (seconds / 60).to_i
18
+ hours = (minutes / 60).to_i
19
+ if human
20
+ minutes = (minutes % 60).to_i
21
+ [0, hours, minutes]
22
+ else
23
+ days = (hours / 24).to_i
24
+ hours = (hours % 24).to_i
25
+ minutes = (minutes % 60).to_i
26
+ [days, hours, minutes]
27
+ end
28
+ end
29
+
30
+ ##
31
+ ## Format seconds as natural language time string
32
+ ##
33
+ ## @param format [Symbol] The format to output
34
+ ## (:dhm, :hm, :m, :clock, :natural)
35
+ ##
36
+ def time_string(format: :dhm)
37
+ format_time(human: true).time_string(format: format)
38
+ end
39
+ end
40
+ end
@@ -84,7 +84,7 @@ module Doing
84
84
  interval ||= false
85
85
  human_time = false
86
86
  if interval
87
- d, h, m = wwid.format_time(wwid.get_interval(i, formatted: false))
87
+ d, h, m = wwid.get_interval(i, formatted: false).format_time
88
88
  human_times = []
89
89
  human_times << format('%<d>d day%<p>s', d: d, p: d == 1 ? '' : 's') if d > 0
90
90
  human_times << format('%<h>d hour%<p>s', h: h, p: h == 1 ? '' : 's') if h > 0
@@ -56,7 +56,7 @@ module Doing
56
56
  end_date: end_date,
57
57
  title: title.strip, #+ " #{note}"
58
58
  note: note.instance_of?(Array) ? note.to_s : note,
59
- time: '%02d:%02d:%02d' % wwid.format_time(interval),
59
+ time: interval.time_string(format: :clock),
60
60
  tags: tags
61
61
  }
62
62
 
@@ -68,7 +68,7 @@ module Doing
68
68
  new_item = {
69
69
  'id' => index + 1,
70
70
  'content' => title.strip, #+ " #{note}"
71
- 'title' => title.strip + " (#{'%02d:%02d:%02d' % wwid.format_time(interval)})",
71
+ 'title' => title.strip + " (#{interval.time_string(format: :clock)})",
72
72
  'start' => i.date.strftime('%F %T'),
73
73
  'type' => 'box',
74
74
  'style' => 'color:#4c566b;background-color:#d8dee9;'