doing 2.1.39 → 2.1.40
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 +23 -0
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/bin/commands/config.rb +43 -34
- data/bin/commands/done.rb +1 -18
- data/bin/commands/finish.rb +30 -25
- data/bin/commands/grep.rb +3 -14
- data/bin/commands/last.rb +2 -8
- data/bin/commands/meanwhile.rb +13 -6
- data/bin/commands/on.rb +3 -16
- data/bin/commands/recent.rb +2 -8
- data/bin/commands/reset.rb +24 -1
- data/bin/commands/select.rb +1 -1
- data/bin/commands/show.rb +6 -17
- data/bin/commands/since.rb +1 -12
- data/bin/commands/today.rb +2 -13
- data/bin/commands/view.rb +1 -1
- data/bin/commands/yesterday.rb +2 -13
- data/bin/doing +15 -8
- 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 +166 -20
- data/docs/doc/Doing/Completion.html +1 -1
- data/docs/doc/Doing/Configuration.html +1 -1
- data/docs/doc/Doing/Errors/DoingNoTraceError.html +7 -3
- data/docs/doc/Doing/Errors/DoingRuntimeError.html +7 -3
- data/docs/doc/Doing/Errors/DoingStandardError.html +1 -1
- data/docs/doc/Doing/Errors/EmptyInput.html +10 -2
- data/docs/doc/Doing/Errors/HistoryLimitError.html +194 -0
- data/docs/doc/Doing/Errors/InvalidPlugin.html +194 -0
- data/docs/doc/Doing/Errors/MissingBackupFile.html +194 -0
- data/docs/doc/Doing/Errors/NoResults.html +10 -2
- data/docs/doc/Doing/Errors/PluginException.html +1 -1
- data/docs/doc/Doing/Errors/UserCancelled.html +10 -2
- data/docs/doc/Doing/Errors/WrongCommand.html +10 -2
- data/docs/doc/Doing/Errors.html +9 -9
- data/docs/doc/Doing/Hooks.html +1 -1
- data/docs/doc/Doing/Item.html +90 -1615
- data/docs/doc/Doing/Items.html +121 -5
- 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 +2 -2
- data/docs/doc/Doing/Section.html +1 -1
- data/docs/doc/Doing/TemplateString.html +2 -2
- data/docs/doc/Doing/Types.html +1 -1
- data/docs/doc/Doing/Util/Backup.html +5 -5
- data/docs/doc/Doing/Util.html +1 -1
- data/docs/doc/Doing/WWID.html +197 -4033
- 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 +26 -5
- data/docs/doc/class_list.html +1 -1
- data/docs/doc/file.README.html +2 -2
- data/docs/doc/index.html +2 -2
- data/docs/doc/method_list.html +293 -773
- data/docs/doc/top-level-namespace.html +3 -3
- data/docs/index.md +1 -1
- data/doing.rdoc +49 -7
- data/lib/completion/_doing.zsh +5 -5
- data/lib/completion/doing.bash +8 -8
- data/lib/completion/doing.fish +7 -2
- data/lib/doing/add_options.rb +31 -1
- data/lib/doing/chronify/array.rb +64 -22
- data/lib/doing/colors.rb +77 -30
- data/lib/doing/completion.rb +4 -5
- data/lib/doing/errors.rb +51 -35
- data/lib/doing/hooks.rb +3 -3
- data/lib/doing/item/dates.rb +112 -0
- data/lib/doing/item/query.rb +433 -0
- data/lib/doing/item/state.rb +59 -0
- data/lib/doing/item/tags.rb +87 -0
- data/lib/doing/item.rb +6 -667
- data/lib/doing/items.rb +38 -13
- data/lib/doing/plugin_manager.rb +3 -3
- data/lib/doing/plugins/export/template_export.rb +4 -4
- data/lib/doing/plugins/import/cal_to_json.scpt +0 -0
- data/lib/doing/util_backup.rb +6 -8
- data/lib/doing/version.rb +1 -1
- data/lib/doing/wwid/display.rb +399 -0
- data/lib/doing/wwid/editor.rb +214 -0
- data/lib/doing/wwid/filetools.rb +186 -0
- data/lib/doing/wwid/filter.rb +218 -0
- data/lib/doing/wwid/guess.rb +87 -0
- data/lib/doing/wwid/interactive.rb +385 -0
- data/lib/doing/wwid/modify.rb +618 -0
- data/lib/doing/wwid/tags.rb +54 -0
- data/lib/doing/wwid/timers.rb +345 -0
- data/lib/doing/wwid/wwidutil.rb +104 -0
- data/lib/doing/wwid.rb +31 -2317
- metadata +19 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8bd8641c5280331189462c44f52c5bc4437c77610072d3c142cf7a56a6e75be6
|
|
4
|
+
data.tar.gz: 40a53127983360a0b7720dd4b27c71d5b783d23d22790bfbcdc8b7f49556ce2d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4d47d3a88086dd579b3b0f1f37a7e17890dd5969487bebd00f92f6194b6281987056b792ece88718c1a4da35803a9748d7cddb7e72f5c908fb0056e299ff9ef3
|
|
7
|
+
data.tar.gz: b2ba0a2c7a3b21e09c1da73c959895fb4dff4f72244cc5c6f855a1d44668d8b5620292881bbb47a7c1896c0fb68430fe33d1e5509a657c5c1fd870c1f5211028
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
### 2.1.40
|
|
2
|
+
|
|
3
|
+
2022-03-14 19:56
|
|
4
|
+
|
|
5
|
+
#### NEW
|
|
6
|
+
|
|
7
|
+
- `doing finish` accepts `--from` ranges to update both start and finish dates
|
|
8
|
+
- `doing finish` allows `--back` and `--took` to be used together
|
|
9
|
+
- `doing finish` allows `--search` and `--tag` to be used together
|
|
10
|
+
- `doing finish --from 'DATE to DATE'` allows you to set a new start and end time with a single range string
|
|
11
|
+
- `doing reset --from 'DATE to DATE'` allows you to reset an entry's start time and update or add @done time
|
|
12
|
+
- `doing reset` accepts a `--took Xm` flag to change the finish time
|
|
13
|
+
- `--output FORMAT` option for all display commands, including last, recent and today
|
|
14
|
+
|
|
15
|
+
#### IMPROVED
|
|
16
|
+
|
|
17
|
+
- Code refactoring, split up WWID class
|
|
18
|
+
- Better diff method available to hooks to see what changed
|
|
19
|
+
|
|
20
|
+
#### FIXED
|
|
21
|
+
|
|
22
|
+
- Search highlighting was being skipped in all cases
|
|
23
|
+
|
|
1
24
|
### 2.1.39
|
|
2
25
|
|
|
3
26
|
2022-03-13 04:32
|
data/Gemfile.lock
CHANGED
data/README.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
|
<!--README-->
|
|
10
10
|
|
|
11
|
-
The current version of `doing` is <!--VER-->2.1.
|
|
11
|
+
The current version of `doing` is <!--VER-->2.1.39<!--END VER-->.
|
|
12
12
|
|
|
13
13
|
Find all of the documentation in the [doing wiki][wiki].
|
|
14
14
|
|
data/bin/commands/config.rb
CHANGED
|
@@ -29,7 +29,7 @@ command :config do |c|
|
|
|
29
29
|
c.long_desc 'Config files are listed in order of precedence (if there are multiple configs detected).
|
|
30
30
|
Values defined in the top item in the list will override values in configutations below it.'
|
|
31
31
|
c.command :list do |list|
|
|
32
|
-
list.action do
|
|
32
|
+
list.action do
|
|
33
33
|
puts Doing.config.additional_configs.join("\n")
|
|
34
34
|
puts Doing.config.config_file
|
|
35
35
|
end
|
|
@@ -54,7 +54,8 @@ command :config do |c|
|
|
|
54
54
|
edit.arg_name 'BUNDLE_ID'
|
|
55
55
|
edit.flag %i[b bundle_id]
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
default_editor = Doing.setting('editors.config', 'editors.config not set')
|
|
58
|
+
edit.desc "Use the config editor defined in ~/.config/doing/config.yml (#{default_editor})"
|
|
58
59
|
edit.switch %i[x default], negatable: false
|
|
59
60
|
end
|
|
60
61
|
|
|
@@ -68,10 +69,11 @@ command :config do |c|
|
|
|
68
69
|
end
|
|
69
70
|
action = cmd.send(:get_action, nil)
|
|
70
71
|
action.call(global, options, args)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
|
|
73
|
+
raise DoingNoTraceError.new('--dump and --update are deprecated,
|
|
74
|
+
use `doing config get` and `doing config update`',
|
|
75
|
+
level: :warn,
|
|
76
|
+
topic: 'Deprecated:')
|
|
75
77
|
end
|
|
76
78
|
|
|
77
79
|
config_file = Doing.config.choose_config
|
|
@@ -79,14 +81,12 @@ command :config do |c|
|
|
|
79
81
|
if `uname` =~ /Darwin/
|
|
80
82
|
if options[:default]
|
|
81
83
|
editor = Doing::Util.find_default_editor('config')
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
`open -a "#{editor}" "#{config_file}"`
|
|
87
|
-
end
|
|
84
|
+
raise InvalidArgument, 'No viable editor found in config or environment.' unless editor
|
|
85
|
+
|
|
86
|
+
if Doing::Util.exec_available(editor.split(/ /).first)
|
|
87
|
+
system %(#{editor} "#{config_file}")
|
|
88
88
|
else
|
|
89
|
-
|
|
89
|
+
`open -a "#{editor}" "#{config_file}"`
|
|
90
90
|
end
|
|
91
91
|
elsif options[:app] || options[:bundle_id]
|
|
92
92
|
if options[:app]
|
|
@@ -107,7 +107,10 @@ command :config do |c|
|
|
|
107
107
|
end
|
|
108
108
|
else
|
|
109
109
|
editor = options[:editor] || Doing::Util.default_editor
|
|
110
|
-
|
|
110
|
+
unless editor && Doing::Util.exec_available(editor.split(/ /).first)
|
|
111
|
+
raise MissingEditor, 'No EDITOR variable defined in environment'
|
|
112
|
+
|
|
113
|
+
end
|
|
111
114
|
|
|
112
115
|
system %(#{editor} "#{config_file}")
|
|
113
116
|
end
|
|
@@ -117,8 +120,8 @@ command :config do |c|
|
|
|
117
120
|
# @@config.update @@config.refresh
|
|
118
121
|
c.desc 'Update default config file, adding any missing keys'
|
|
119
122
|
c.command %i[update refresh] do |update|
|
|
120
|
-
update.action do
|
|
121
|
-
Doing.config.configure({rewrite: true, ignore_local: true})
|
|
123
|
+
update.action do
|
|
124
|
+
Doing.config.configure({ rewrite: true, ignore_local: true })
|
|
122
125
|
Doing.logger.warn('Config:', 'config refreshed')
|
|
123
126
|
end
|
|
124
127
|
end
|
|
@@ -126,7 +129,7 @@ command :config do |c|
|
|
|
126
129
|
# @@config.undo
|
|
127
130
|
c.desc 'Undo the last change to a config file'
|
|
128
131
|
c.command :undo do |undo|
|
|
129
|
-
undo.action do
|
|
132
|
+
undo.action do
|
|
130
133
|
config_file = Doing.config.choose_config
|
|
131
134
|
Doing::Util::Backup.restore_last_backup(config_file, count: 1)
|
|
132
135
|
end
|
|
@@ -137,22 +140,24 @@ command :config do |c|
|
|
|
137
140
|
c.arg 'KEY_PATH'
|
|
138
141
|
c.command %i[get dump] do |dump|
|
|
139
142
|
dump.example 'doing config get', desc: 'Output the entire configuration'
|
|
140
|
-
dump.example 'doing config get timer_format --output raw',
|
|
141
|
-
|
|
142
|
-
dump.example 'doing config get
|
|
143
|
+
dump.example 'doing config get timer_format --output raw',
|
|
144
|
+
desc: 'Output the value of timer_format as a plain string'
|
|
145
|
+
dump.example 'doing config get doing_file',
|
|
146
|
+
desc: 'Output the value of the doing_file setting, respecting local configurations'
|
|
147
|
+
dump.example 'doing config get -o json plug.plugpath',
|
|
148
|
+
desc: 'Key path is fuzzy matched: output the value of plugins.plugin_path as JSON'
|
|
143
149
|
|
|
144
150
|
dump.desc 'Format for output (json|yaml|raw)'
|
|
145
151
|
dump.arg_name 'FORMAT'
|
|
146
152
|
dump.flag %i[o output], default_value: 'yaml', must_match: /^(?:y(?:aml)?|j(?:son)?|r(?:aw)?)$/
|
|
147
153
|
|
|
148
154
|
dump.action do |_global, options, args|
|
|
149
|
-
|
|
150
155
|
keypath = args.join('.')
|
|
151
156
|
cfg = Doing.config.value_for_key(keypath)
|
|
152
157
|
real_path = Doing.config.resolve_key_path(keypath)
|
|
153
158
|
|
|
154
159
|
if cfg
|
|
155
|
-
val = cfg.map {|
|
|
160
|
+
val = cfg.map { |_, v| v }[0]
|
|
156
161
|
if real_path.count.positive?
|
|
157
162
|
nested_cfg = {}
|
|
158
163
|
nested_cfg.deep_set(real_path, val)
|
|
@@ -161,13 +166,15 @@ command :config do |c|
|
|
|
161
166
|
end
|
|
162
167
|
|
|
163
168
|
if options[:output] =~ /^r/
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
169
|
+
|
|
170
|
+
$stdout.puts case val
|
|
171
|
+
when Hash
|
|
172
|
+
YAML.dump(val)
|
|
173
|
+
when Array
|
|
174
|
+
val.join(', ')
|
|
175
|
+
else
|
|
176
|
+
val.to_s
|
|
177
|
+
end
|
|
171
178
|
else
|
|
172
179
|
$stdout.puts case options[:output]
|
|
173
180
|
when /^j/
|
|
@@ -188,13 +195,14 @@ command :config do |c|
|
|
|
188
195
|
c.arg 'KEY VALUE'
|
|
189
196
|
c.command :set do |set|
|
|
190
197
|
set.example 'doing config set timer_format human', desc: 'Set the value of timer_format to "human"'
|
|
191
|
-
set.example 'doing config set plug.plugpath ~/my_plugins',
|
|
198
|
+
set.example 'doing config set plug.plugpath ~/my_plugins',
|
|
199
|
+
desc: 'Key path is fuzzy matched: set the value of plugins.plugin_path'
|
|
192
200
|
|
|
193
201
|
set.desc 'Delete specified key'
|
|
194
202
|
set.switch %i[r remove], negatable: false
|
|
195
203
|
|
|
196
204
|
set.desc 'Force update to .doingrc in the current directory'
|
|
197
|
-
set.switch %[local], negatable: false
|
|
205
|
+
set.switch %i[local], negatable: false
|
|
198
206
|
|
|
199
207
|
set.action do |_global, options, args|
|
|
200
208
|
if args.count < 2 && !options[:remove]
|
|
@@ -209,10 +217,11 @@ command :config do |c|
|
|
|
209
217
|
old_type = old_value&.class.to_s || nil
|
|
210
218
|
|
|
211
219
|
if old_value.is_a?(Hash) && !options[:remove]
|
|
212
|
-
Doing.logger.log_now(:warn, 'Config:',
|
|
220
|
+
Doing.logger.log_now(:warn, 'Config:', ['Config key must point to a single value, ',
|
|
221
|
+
"#{real_path.join('.').boldwhite} is a mapping"].join(' '))
|
|
213
222
|
didyou = 'Did you mean:'
|
|
214
|
-
old_value.
|
|
215
|
-
Doing.logger.log_now(:warn,
|
|
223
|
+
old_value.each_key do |k|
|
|
224
|
+
Doing.logger.log_now(:warn, didyou, "#{keypath}.#{k}?")
|
|
216
225
|
didyou = '..........or:'
|
|
217
226
|
end
|
|
218
227
|
raise InvalidArgument, 'Config value is a mapping, can not be set to a single value'
|
data/bin/commands/done.rb
CHANGED
|
@@ -19,24 +19,6 @@ command %i[done did] do |c|
|
|
|
19
19
|
c.desc 'Immediately archive the entry'
|
|
20
20
|
c.switch %i[a archive], negatable: false, default_value: false
|
|
21
21
|
|
|
22
|
-
c.desc %(Set finish date to specific date/time (natural langauge parsed, e.g. --at=1:30pm).
|
|
23
|
-
Used with --took, backdates start date)
|
|
24
|
-
c.arg_name 'DATE_STRING'
|
|
25
|
-
c.flag %i[at finished], type: DateEndString
|
|
26
|
-
|
|
27
|
-
c.desc %(
|
|
28
|
-
Start and end times as a date/time range `doing done --from "1am to 8am"`.
|
|
29
|
-
Overrides other date flags.
|
|
30
|
-
)
|
|
31
|
-
c.arg_name 'TIME_RANGE'
|
|
32
|
-
c.flag [:from], must_match: REGEX_RANGE
|
|
33
|
-
|
|
34
|
-
c.desc %(Set completion date to start date plus interval (XX[mhd] or HH:MM).
|
|
35
|
-
If used without the --back option, the start date will be moved back to allow
|
|
36
|
-
the completion date to be the current time.)
|
|
37
|
-
c.arg_name 'INTERVAL'
|
|
38
|
-
c.flag %i[t took for], type: DateIntervalString
|
|
39
|
-
|
|
40
22
|
c.desc 'Section'
|
|
41
23
|
c.arg_name 'NAME'
|
|
42
24
|
c.flag %i[s section]
|
|
@@ -45,6 +27,7 @@ command %i[done did] do |c|
|
|
|
45
27
|
c.switch %i[u unfinished], negatable: false, default_value: false
|
|
46
28
|
|
|
47
29
|
add_options(:add_entry, c)
|
|
30
|
+
add_options(:finish_entry, c)
|
|
48
31
|
|
|
49
32
|
c.action do |global_options, options, args|
|
|
50
33
|
Doing.auto_tag = !options[:noauto]
|
data/bin/commands/finish.rb
CHANGED
|
@@ -14,14 +14,6 @@ command :finish do |c|
|
|
|
14
14
|
c.arg_name 'DATE_STRING'
|
|
15
15
|
c.flag %i[b back started], type: DateBeginString
|
|
16
16
|
|
|
17
|
-
c.desc 'Set the completed date to the start date plus XX[hmd]'
|
|
18
|
-
c.arg_name 'INTERVAL'
|
|
19
|
-
c.flag %i[t took for], type: DateIntervalString
|
|
20
|
-
|
|
21
|
-
c.desc %(Set finish date to specific date/time (natural langauge parsed, e.g. --at=1:30pm). If used, ignores --back.)
|
|
22
|
-
c.arg_name 'DATE_STRING'
|
|
23
|
-
c.flag %i[at finished], type: DateEndString
|
|
24
|
-
|
|
25
17
|
c.desc 'Overwrite existing @done tag with new date'
|
|
26
18
|
c.switch %i[update], negatable: false, default_value: false
|
|
27
19
|
|
|
@@ -48,32 +40,43 @@ command :finish do |c|
|
|
|
48
40
|
|
|
49
41
|
add_options(:search, c)
|
|
50
42
|
add_options(:tag_filter, c)
|
|
43
|
+
add_options(:finish_entry, c)
|
|
51
44
|
|
|
52
45
|
c.action do |_global_options, options, args|
|
|
53
46
|
options[:fuzzy] = false
|
|
54
47
|
unless options[:auto]
|
|
55
|
-
if options[:
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
48
|
+
if options[:from]
|
|
49
|
+
options[:from] = options[:from].split(/#{REGEX_RANGE_INDICATOR}/).map do |time|
|
|
50
|
+
time =~ REGEX_TIME ? "today #{time.sub(/(?mi)(^.*?(?=\d+)|(?<=[ap]m).*?$)/, '')}" : time
|
|
51
|
+
end.join(' to ').split_date_range
|
|
52
|
+
start_date, finish_date = options[:from]
|
|
53
|
+
finish_date ||= Time.now
|
|
54
|
+
else
|
|
55
|
+
if options[:took]
|
|
56
|
+
took = options[:took]
|
|
57
|
+
raise InvalidTimeExpression, 'Unable to parse date string for --took' if took.nil?
|
|
59
58
|
|
|
60
|
-
|
|
59
|
+
end
|
|
61
60
|
|
|
62
|
-
|
|
61
|
+
if options[:at]
|
|
62
|
+
finish_date = options[:at]
|
|
63
|
+
finish_date = finish_date.chronify(guess: :begin) if finish_date.is_a? String
|
|
64
|
+
raise InvalidTimeExpression, 'Unable to parse date string for --at' if finish_date.nil?
|
|
63
65
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
start_date = options[:took] ? finish_date - took : nil
|
|
67
|
+
elsif options[:back]
|
|
68
|
+
start_date = options[:back]
|
|
69
|
+
finish_date = options[:took] ? start_date + took : Time.now
|
|
68
70
|
|
|
69
|
-
|
|
70
|
-
elsif options[:back]
|
|
71
|
-
date = options[:back]
|
|
71
|
+
raise InvalidTimeExpression, 'Unable to parse date string' if start_date.nil?
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
else
|
|
74
|
+
start_date = options[:took] ? Time.now - took : nil
|
|
75
|
+
finish_date = Time.now
|
|
76
|
+
end
|
|
76
77
|
end
|
|
78
|
+
|
|
79
|
+
|
|
77
80
|
end
|
|
78
81
|
|
|
79
82
|
if options[:tag].nil?
|
|
@@ -101,10 +104,11 @@ command :finish do |c|
|
|
|
101
104
|
|
|
102
105
|
opts = {
|
|
103
106
|
archive: options[:archive],
|
|
104
|
-
back:
|
|
107
|
+
back: start_date,
|
|
105
108
|
case: options[:case].normalize_case,
|
|
106
109
|
count: count,
|
|
107
110
|
date: options[:date],
|
|
111
|
+
done_date: finish_date,
|
|
108
112
|
fuzzy: options[:fuzzy],
|
|
109
113
|
interactive: options[:interactive],
|
|
110
114
|
not: options[:not],
|
|
@@ -112,6 +116,7 @@ command :finish do |c|
|
|
|
112
116
|
search: search,
|
|
113
117
|
section: options[:section],
|
|
114
118
|
sequential: options[:auto],
|
|
119
|
+
start_date: start_date,
|
|
115
120
|
tag: tags,
|
|
116
121
|
tag_bool: options[:bool].normalize_bool,
|
|
117
122
|
tags: ['done'],
|
data/bin/commands/grep.rb
CHANGED
|
@@ -16,25 +16,12 @@ command %i[grep search] do |c|
|
|
|
16
16
|
c.arg_name 'NAME'
|
|
17
17
|
c.flag %i[s section], default_value: 'All'
|
|
18
18
|
|
|
19
|
-
c.desc "Output to export format (#{Doing::Plugins.plugin_names(type: :export)})"
|
|
20
|
-
c.arg_name 'FORMAT'
|
|
21
|
-
c.flag %i[o output]
|
|
22
|
-
|
|
23
|
-
c.desc "Output using a template from configuration"
|
|
24
|
-
c.arg_name 'TEMPLATE_KEY'
|
|
25
|
-
c.flag [:config_template], type: TemplateName, default_value: 'default'
|
|
26
|
-
|
|
27
|
-
c.desc 'Override output format with a template string containing %placeholders'
|
|
28
|
-
c.arg_name 'TEMPLATE_STRING'
|
|
29
|
-
c.flag [:template]
|
|
30
|
-
|
|
31
19
|
# c.desc '[DEPRECATED] Use alternative fuzzy matching for search string'
|
|
32
20
|
# c.switch [:fuzzy], default_value: false, negatable: false
|
|
33
21
|
|
|
34
22
|
c.desc 'Force exact string matching (case sensitive)'
|
|
35
23
|
c.switch %i[x exact], default_value: Doing.config.exact_match?, negatable: Doing.config.exact_match?
|
|
36
24
|
|
|
37
|
-
|
|
38
25
|
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
|
39
26
|
c.arg_name 'TYPE'
|
|
40
27
|
c.flag [:case], must_match: REGEX_CASE,
|
|
@@ -53,13 +40,15 @@ command %i[grep search] do |c|
|
|
|
53
40
|
c.desc 'Display an interactive menu of results to perform further operations'
|
|
54
41
|
c.switch %i[i interactive], default_value: false, negatable: false
|
|
55
42
|
|
|
43
|
+
add_options(:output_template, c)
|
|
56
44
|
add_options(:tag_filter, c)
|
|
57
45
|
add_options(:date_filter, c)
|
|
58
46
|
add_options(:time_display, c)
|
|
59
47
|
|
|
60
48
|
c.action do |_global_options, options, args|
|
|
61
49
|
options[:fuzzy] = false
|
|
62
|
-
|
|
50
|
+
|
|
51
|
+
raise InvalidPlugin.new('output', options[:output]) if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
|
|
63
52
|
|
|
64
53
|
template = Doing.setting(['templates', options[:config_template]]).deep_merge(Doing.settings)
|
|
65
54
|
tags_color = template.key?('tags_color') ? template['tags_color'] : nil
|
data/bin/commands/last.rb
CHANGED
|
@@ -21,20 +21,13 @@ command :last do |c|
|
|
|
21
21
|
c.desc "Delete the last entry"
|
|
22
22
|
c.switch %i[d delete], negatable: false, default_value: false
|
|
23
23
|
|
|
24
|
-
c.desc "Output using a template from configuration"
|
|
25
|
-
c.arg_name 'TEMPLATE_KEY'
|
|
26
|
-
c.flag [:config_template], type: TemplateName, default_value: 'last'
|
|
27
|
-
|
|
28
|
-
c.desc 'Override output format with a template string containing %placeholders'
|
|
29
|
-
c.arg_name 'TEMPLATE_STRING'
|
|
30
|
-
c.flag [:template]
|
|
31
|
-
|
|
32
24
|
c.desc "Highlight search matches in output. Only affects command line output"
|
|
33
25
|
c.switch %i[h hilite], default_value: Doing.settings.dig('search', 'highlight')
|
|
34
26
|
|
|
35
27
|
c.desc 'Show elapsed time if entry is not tagged @done'
|
|
36
28
|
c.switch [:duration]
|
|
37
29
|
|
|
30
|
+
add_options(:output_template, c, default_template: 'last')
|
|
38
31
|
add_options(:search, c)
|
|
39
32
|
add_options(:tag_filter, c)
|
|
40
33
|
|
|
@@ -69,6 +62,7 @@ command :last do |c|
|
|
|
69
62
|
case: options[:case],
|
|
70
63
|
hilite: options[:hilite],
|
|
71
64
|
negate: options[:not],
|
|
65
|
+
output: options[:output],
|
|
72
66
|
tag: options[:tag],
|
|
73
67
|
tag_bool: options[:bool],
|
|
74
68
|
delete: options[:delete],
|
data/bin/commands/meanwhile.rb
CHANGED
|
@@ -19,6 +19,8 @@ command :meanwhile do |c|
|
|
|
19
19
|
c.switch %i[a archive], negatable: false, default_value: false
|
|
20
20
|
|
|
21
21
|
add_options(:add_entry, c)
|
|
22
|
+
# TODO: Add took and from handling for post-dating meanwhile entries
|
|
23
|
+
# add_options(:add_dated, c)
|
|
22
24
|
|
|
23
25
|
c.action do |global_options, options, args|
|
|
24
26
|
Doing.auto_tag = !options[:noauto]
|
|
@@ -31,17 +33,18 @@ command :meanwhile do |c|
|
|
|
31
33
|
date = Time.now
|
|
32
34
|
end
|
|
33
35
|
|
|
34
|
-
if options[:section]
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
section = if options[:section]
|
|
37
|
+
@wwid.guess_section(options[:section]) || options[:section].cap_first
|
|
38
|
+
else
|
|
39
|
+
Doing.setting('current_section')
|
|
40
|
+
end
|
|
39
41
|
input = ''
|
|
40
42
|
|
|
41
43
|
ask_note = options[:ask] ? Doing::Prompt.read_lines(prompt: 'Add a note') : []
|
|
42
44
|
|
|
43
45
|
if options[:editor]
|
|
44
46
|
raise MissingEditor, 'No EDITOR variable defined in environment' if Doing::Util.default_editor.nil?
|
|
47
|
+
|
|
45
48
|
input += date.strftime('%F %R | ')
|
|
46
49
|
input += args.join(' ') unless args.empty?
|
|
47
50
|
input += "\n#{options[:note]}" if options[:note]
|
|
@@ -70,7 +73,11 @@ command :meanwhile do |c|
|
|
|
70
73
|
note.add(ask_note) if ask_note.good?
|
|
71
74
|
end
|
|
72
75
|
|
|
73
|
-
@wwid.stop_start('meanwhile', { new_item: input,
|
|
76
|
+
@wwid.stop_start('meanwhile', { new_item: input,
|
|
77
|
+
back: date,
|
|
78
|
+
section: section,
|
|
79
|
+
archive: options[:archive],
|
|
80
|
+
note: note })
|
|
74
81
|
@wwid.write(@wwid.doing_file)
|
|
75
82
|
end
|
|
76
83
|
end
|
data/bin/commands/on.rb
CHANGED
|
@@ -13,35 +13,22 @@ command :on do |c|
|
|
|
13
13
|
c.arg_name 'NAME'
|
|
14
14
|
c.flag %i[s section], default_value: 'All'
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
c.arg_name 'FORMAT'
|
|
18
|
-
c.flag %i[o output]
|
|
19
|
-
|
|
20
|
-
c.desc "Output using a template from configuration"
|
|
21
|
-
c.arg_name 'TEMPLATE_KEY'
|
|
22
|
-
c.flag [:config_template], type: TemplateName, default_value: 'default'
|
|
23
|
-
|
|
24
|
-
c.desc 'Override output format with a template string containing %placeholders'
|
|
25
|
-
c.arg_name 'TEMPLATE_STRING'
|
|
26
|
-
c.flag [:template]
|
|
27
|
-
|
|
16
|
+
add_options(:output_template, c)
|
|
28
17
|
add_options(:time_display, c)
|
|
29
18
|
add_options(:search, c)
|
|
30
19
|
add_options(:tag_filter, c)
|
|
31
20
|
add_options(:time_filter, c)
|
|
32
21
|
|
|
33
22
|
c.action do |_global_options, options, args|
|
|
34
|
-
raise
|
|
23
|
+
raise InvalidPlugin.new('output', options[:output]) if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
|
|
35
24
|
|
|
36
25
|
raise MissingArgument, 'Missing date argument' if args.empty?
|
|
37
26
|
|
|
38
27
|
date_string = args.join(' ').strip
|
|
39
28
|
if date_string =~ /^tod(?:ay)?/i
|
|
40
|
-
date_string = '
|
|
29
|
+
date_string = 'midnight to today 23:59'
|
|
41
30
|
end
|
|
42
31
|
|
|
43
|
-
puts date_string
|
|
44
|
-
|
|
45
32
|
start, finish = date_string.split_date_range
|
|
46
33
|
|
|
47
34
|
raise InvalidTimeExpression, "Unrecognized date string (#{date_string})" unless start
|
data/bin/commands/recent.rb
CHANGED
|
@@ -12,17 +12,10 @@ command :recent do |c|
|
|
|
12
12
|
c.arg_name 'NAME'
|
|
13
13
|
c.flag %i[s section], default_value: 'All'
|
|
14
14
|
|
|
15
|
-
c.desc "Output using a template from configuration"
|
|
16
|
-
c.arg_name 'TEMPLATE_KEY'
|
|
17
|
-
c.flag [:config_template], type: TemplateName, default_value: 'recent'
|
|
18
|
-
|
|
19
|
-
c.desc 'Override output format with a template string containing %placeholders'
|
|
20
|
-
c.arg_name 'TEMPLATE_STRING'
|
|
21
|
-
c.flag [:template]
|
|
22
|
-
|
|
23
15
|
c.desc 'Select from a menu of matching entries to perform additional operations'
|
|
24
16
|
c.switch %i[i interactive], negatable: false, default_value: false
|
|
25
17
|
|
|
18
|
+
add_options(:output_template, c, default_template: 'recent')
|
|
26
19
|
add_options(:time_display, c)
|
|
27
20
|
|
|
28
21
|
c.action do |global_options, options, args|
|
|
@@ -53,6 +46,7 @@ command :recent do |c|
|
|
|
53
46
|
times: options[:times],
|
|
54
47
|
totals: options[:totals],
|
|
55
48
|
interactive: options[:interactive],
|
|
49
|
+
output: options[:output],
|
|
56
50
|
duration: options[:duration],
|
|
57
51
|
config_template: options[:config_template],
|
|
58
52
|
template: options[:template]
|
data/bin/commands/reset.rb
CHANGED
|
@@ -17,6 +17,17 @@ command %i[reset begin] do |c|
|
|
|
17
17
|
c.desc 'Resume entry (remove @done)'
|
|
18
18
|
c.switch %i[r resume], default_value: true
|
|
19
19
|
|
|
20
|
+
c.desc %(
|
|
21
|
+
Start and end times as a date/time range `doing done --from "1am to 8am"`.
|
|
22
|
+
Overrides any date argument and disables --resume.
|
|
23
|
+
)
|
|
24
|
+
c.arg_name 'TIME_RANGE'
|
|
25
|
+
c.flag [:from], must_match: REGEX_RANGE
|
|
26
|
+
|
|
27
|
+
c.desc %(Set completion date to start date plus interval (XX[mhd] or HH:MM). Disables --resume)
|
|
28
|
+
c.arg_name 'INTERVAL'
|
|
29
|
+
c.flag %i[t took for], type: DateIntervalString
|
|
30
|
+
|
|
20
31
|
c.desc 'Change start date but do not remove @done (shortcut for --no-resume)'
|
|
21
32
|
c.switch [:n]
|
|
22
33
|
|
|
@@ -62,9 +73,21 @@ command %i[reset begin] do |c|
|
|
|
62
73
|
|
|
63
74
|
raise NoResults, 'No entry matching parameters was found.' unless last_entry
|
|
64
75
|
|
|
76
|
+
finish_date = nil
|
|
77
|
+
|
|
78
|
+
if options[:from]
|
|
79
|
+
options[:from] = options[:from].split(/#{REGEX_RANGE_INDICATOR}/).map do |time|
|
|
80
|
+
time =~ REGEX_TIME ? "today #{time.sub(/(?mi)(^.*?(?=\d+)|(?<=[ap]m).*?$)/, '')}" : time
|
|
81
|
+
end.join(' to ').split_date_range
|
|
82
|
+
reset_date, finish_date = options[:from]
|
|
83
|
+
options[:resume] = false if finish_date
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
finish_date = reset_date + options[:took] if options[:took]
|
|
87
|
+
|
|
65
88
|
old_item = last_entry.clone
|
|
66
89
|
|
|
67
|
-
@wwid.reset_item(last_entry, date: reset_date, resume: options[:resume])
|
|
90
|
+
@wwid.reset_item(last_entry, date: reset_date, finish_date: finish_date, resume: options[:resume])
|
|
68
91
|
Doing::Hooks.trigger :post_entry_updated, @wwid, last_entry, old_item
|
|
69
92
|
# new_entry = Doing::Item.new(last_entry.date, last_entry.title, last_entry.section, new_note)
|
|
70
93
|
|
data/bin/commands/select.rb
CHANGED
|
@@ -94,7 +94,7 @@ command :select do |c|
|
|
|
94
94
|
|
|
95
95
|
c.action do |_global_options, options, _args|
|
|
96
96
|
if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
|
|
97
|
-
raise
|
|
97
|
+
raise InvalidPlugin.new('output', options[:output])
|
|
98
98
|
|
|
99
99
|
end
|
|
100
100
|
|
data/bin/commands/show.rb
CHANGED
|
@@ -22,38 +22,27 @@ command :show do |c|
|
|
|
22
22
|
c.arg_name 'MAX'
|
|
23
23
|
c.flag %i[c count], default_value: 0, must_match: /^\d+$/, type: Integer
|
|
24
24
|
|
|
25
|
-
c.desc 'Age (oldest|newest)'
|
|
26
|
-
c.arg_name 'AGE'
|
|
27
|
-
c.flag %i[a age], default_value: :newest, type: AgeSymbol
|
|
28
|
-
|
|
29
25
|
c.desc "Highlight search matches in output. Only affects command line output"
|
|
30
26
|
c.switch %i[h hilite], default_value: Doing.settings.dig('search', 'highlight')
|
|
31
27
|
|
|
32
28
|
c.desc "Edit matching entries with #{Doing::Util.default_editor}"
|
|
33
29
|
c.switch %i[e editor], negatable: false, default_value: false
|
|
34
30
|
|
|
31
|
+
c.desc 'Age (oldest|newest)'
|
|
32
|
+
c.arg_name 'AGE'
|
|
33
|
+
c.flag %i[a age], default_value: :newest, type: AgeSymbol
|
|
34
|
+
|
|
35
35
|
c.desc 'Sort order (asc/desc)'
|
|
36
36
|
c.arg_name 'ORDER'
|
|
37
37
|
c.flag %i[s sort], must_match: REGEX_SORT_ORDER, default_value: :asc, type: OrderSymbol
|
|
38
38
|
|
|
39
|
-
c.desc "Output using a template from configuration"
|
|
40
|
-
c.arg_name 'TEMPLATE_KEY'
|
|
41
|
-
c.flag [:config_template], type: TemplateName, default_value: 'default'
|
|
42
|
-
|
|
43
|
-
c.desc 'Override output format with a template string containing %placeholders'
|
|
44
|
-
c.arg_name 'TEMPLATE_STRING'
|
|
45
|
-
c.flag [:template]
|
|
46
|
-
|
|
47
39
|
c.desc 'Select section or tag to display from a menu'
|
|
48
40
|
c.switch %i[m menu], negatable: false, default_value: false
|
|
49
41
|
|
|
50
42
|
c.desc 'Select from a menu of matching entries to perform additional operations'
|
|
51
43
|
c.switch %i[i interactive], negatable: false, default_value: false
|
|
52
44
|
|
|
53
|
-
|
|
54
|
-
c.arg_name 'FORMAT'
|
|
55
|
-
c.flag %i[o output]
|
|
56
|
-
|
|
45
|
+
add_options(:output_template, c)
|
|
57
46
|
add_options(:time_display, c)
|
|
58
47
|
add_options(:search, c)
|
|
59
48
|
add_options(:tag_filter, c)
|
|
@@ -62,7 +51,7 @@ command :show do |c|
|
|
|
62
51
|
c.action do |global_options, options, args|
|
|
63
52
|
options[:fuzzy] = false
|
|
64
53
|
if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
|
|
65
|
-
raise
|
|
54
|
+
raise InvalidPlugin.new('output', options[:output])
|
|
66
55
|
|
|
67
56
|
end
|
|
68
57
|
|