doing 2.1.4pre → 2.1.7
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/.yardoc/checksums +14 -13
- data/.yardoc/object_types +0 -0
- data/.yardoc/objects/root.dat +0 -0
- data/.yardopts +1 -1
- data/CHANGELOG.md +37 -1
- data/Gemfile.lock +3 -1
- data/README.md +5 -1
- data/bin/doing +192 -95
- data/docs/_config.yml +1 -0
- data/{doc → docs/doc}/Array.html +63 -1
- data/docs/doc/BooleanTermParser/Clause.html +293 -0
- data/docs/doc/BooleanTermParser/Operator.html +172 -0
- data/docs/doc/BooleanTermParser/Query.html +417 -0
- data/docs/doc/BooleanTermParser/QueryParser.html +135 -0
- data/docs/doc/BooleanTermParser/QueryTransformer.html +124 -0
- data/docs/doc/BooleanTermParser.html +115 -0
- data/docs/doc/Doing/CLIFormat.html +131 -0
- data/{doc → docs/doc}/Doing/Color.html +2 -2
- data/{doc → docs/doc}/Doing/Completion.html +1 -1
- data/{doc → docs/doc}/Doing/Configuration.html +117 -12
- data/{doc → docs/doc}/Doing/Content.html +0 -0
- data/{doc → docs/doc}/Doing/Errors/DoingNoTraceError.html +1 -1
- data/{doc → docs/doc}/Doing/Errors/DoingRuntimeError.html +1 -1
- data/{doc → docs/doc}/Doing/Errors/DoingStandardError.html +1 -1
- data/{doc → docs/doc}/Doing/Errors/EmptyInput.html +1 -1
- data/{doc → docs/doc}/Doing/Errors/NoResults.html +1 -1
- data/{doc → docs/doc}/Doing/Errors/PluginException.html +1 -1
- data/{doc → docs/doc}/Doing/Errors/UserCancelled.html +1 -1
- data/{doc → docs/doc}/Doing/Errors/WrongCommand.html +1 -1
- data/{doc → docs/doc}/Doing/Errors.html +1 -1
- data/{doc → docs/doc}/Doing/Hooks.html +1 -1
- data/{doc → docs/doc}/Doing/Item.html +100 -73
- data/{doc → docs/doc}/Doing/Items.html +2 -2
- data/{doc → docs/doc}/Doing/LogAdapter.html +70 -1
- data/{doc → docs/doc}/Doing/Note.html +5 -134
- data/{doc → docs/doc}/Doing/Pager.html +1 -1
- data/{doc → docs/doc}/Doing/Plugins.html +431 -35
- data/{doc → docs/doc}/Doing/Prompt.html +1 -1
- data/{doc → docs/doc}/Doing/Section.html +1 -1
- data/docs/doc/Doing/TemplateString.html +713 -0
- data/docs/doc/Doing/Util/Backup.html +686 -0
- data/{doc → docs/doc}/Doing/Util.html +1 -1
- data/{doc → docs/doc}/Doing/WWID.html +5 -5
- data/{doc → docs/doc}/Doing/WWIDFile.html +0 -0
- data/{doc → docs/doc}/Doing.html +4 -4
- data/{doc → docs/doc}/GLI/Commands/MarkdownDocumentListener.html +1 -1
- data/{doc → docs/doc}/GLI/Commands.html +1 -1
- data/{doc → docs/doc}/GLI.html +1 -1
- data/{doc → docs/doc}/Hash.html +1 -1
- data/docs/doc/PhraseParser/Operator.html +172 -0
- data/docs/doc/PhraseParser/PhraseClause.html +303 -0
- data/docs/doc/PhraseParser/Query.html +495 -0
- data/docs/doc/PhraseParser/QueryParser.html +136 -0
- data/docs/doc/PhraseParser/QueryTransformer.html +124 -0
- data/docs/doc/PhraseParser/TermClause.html +293 -0
- data/docs/doc/PhraseParser.html +115 -0
- data/{doc → docs/doc}/Status.html +1 -1
- data/{doc → docs/doc}/String.html +182 -12
- data/{doc → docs/doc}/Symbol.html +35 -1
- data/{doc → docs/doc}/Time.html +1 -1
- data/{doc → docs/doc}/_index.html +21 -14
- data/{doc → docs/doc}/class_list.html +1 -1
- data/{doc → docs/doc}/css/common.css +0 -0
- data/{doc → docs/doc}/css/full_list.css +0 -0
- data/{doc → docs/doc}/css/style.css +0 -0
- data/{doc → docs/doc}/file.README.html +6 -2
- data/{doc → docs/doc}/file_list.html +0 -0
- data/{doc → docs/doc}/frames.html +0 -0
- data/{doc → docs/doc}/index.html +6 -2
- data/{doc → docs/doc}/js/app.js +0 -0
- data/{doc → docs/doc}/js/full_list.js +0 -0
- data/{doc → docs/doc}/js/jquery.js +0 -0
- data/{doc → docs/doc}/method_list.html +313 -161
- data/{doc → docs/doc}/top-level-namespace.html +1 -1
- data/docs/index.md +60 -0
- data/doing.gemspec +1 -0
- data/doing.rdoc +74 -15
- data/example_plugin.rb +3 -1
- data/lib/completion/_doing.zsh +53 -41
- data/lib/completion/doing.bash +17 -6
- data/lib/completion/doing.fish +321 -2
- data/lib/doing/array.rb +9 -0
- data/lib/doing/completion/fish_completion.rb +46 -3
- data/lib/doing/completion/zsh_completion.rb +1 -1
- data/lib/doing/configuration.rb +33 -11
- data/lib/doing/item.rb +12 -3
- data/lib/doing/log_adapter.rb +28 -0
- data/lib/doing/note.rb +31 -30
- data/lib/doing/plugin_manager.rb +84 -21
- data/lib/doing/plugins/export/dayone_export.rb +209 -0
- data/lib/doing/plugins/export/html_export.rb +2 -2
- data/lib/doing/plugins/export/json_export.rb +1 -0
- data/lib/doing/plugins/export/markdown_export.rb +1 -1
- data/lib/doing/plugins/export/template_export.rb +90 -85
- data/lib/doing/prompt.rb +9 -6
- data/lib/doing/string.rb +68 -27
- data/lib/doing/symbol.rb +4 -0
- data/lib/doing/template_string.rb +197 -0
- data/lib/doing/util.rb +4 -2
- data/lib/doing/util_backup.rb +55 -3
- data/lib/doing/version.rb +1 -1
- data/lib/doing/wwid.rb +37 -22
- data/lib/doing.rb +3 -0
- data/lib/examples/plugins/say_export.rb +1 -1
- data/lib/examples/plugins/wiki_export/wiki_export.rb +3 -3
- data/lib/templates/doing-dayone-entry.erb +6 -0
- data/lib/templates/doing-dayone.erb +5 -0
- metadata +95 -53
data/bin/doing
CHANGED
|
@@ -51,11 +51,16 @@ if ENV['DOING_LOG_LEVEL'] || ENV['DOING_DEBUG'] || ENV['DOING_QUIET'] || ENV['DO
|
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
+
Doing.logger.benchmark(:total, :start)
|
|
55
|
+
|
|
54
56
|
if ENV['DOING_CONFIG']
|
|
55
57
|
Doing.config_with(ENV['DOING_CONFIG'], { ignore_local: true })
|
|
56
58
|
end
|
|
57
59
|
|
|
60
|
+
Doing.logger.benchmark(:configure, :start)
|
|
58
61
|
config = Doing.config
|
|
62
|
+
Doing.logger.benchmark(:configure, :finish)
|
|
63
|
+
|
|
59
64
|
settings = config.settings
|
|
60
65
|
wwid.config = settings
|
|
61
66
|
|
|
@@ -224,14 +229,14 @@ command %i[reset begin] do |c|
|
|
|
224
229
|
# c.switch [:fuzzy], default_value: false, negatable: false
|
|
225
230
|
|
|
226
231
|
c.desc 'Force exact search string matching (case sensitive)'
|
|
227
|
-
c.switch %i[x exact], default_value:
|
|
232
|
+
c.switch %i[x exact], default_value: config.exact_match?, negatable: config.exact_match?
|
|
228
233
|
|
|
229
234
|
c.desc 'Reset items that *don\'t* match search/tag filters'
|
|
230
235
|
c.switch [:not], default_value: false, negatable: false
|
|
231
236
|
|
|
232
237
|
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
|
233
238
|
c.arg_name 'TYPE'
|
|
234
|
-
c.flag [:case], must_match: /^[csi]/, default_value: '
|
|
239
|
+
c.flag [:case], must_match: /^[csi]/, default_value: settings.dig('search', 'case')
|
|
235
240
|
|
|
236
241
|
c.desc 'Boolean (AND|OR|NOT) with which to combine multiple tag filters'
|
|
237
242
|
c.arg_name 'BOOLEAN'
|
|
@@ -329,14 +334,14 @@ command :note do |c|
|
|
|
329
334
|
# c.switch [:fuzzy], default_value: false, negatable: false
|
|
330
335
|
|
|
331
336
|
c.desc 'Force exact search string matching (case sensitive)'
|
|
332
|
-
c.switch %i[x exact], default_value:
|
|
337
|
+
c.switch %i[x exact], default_value: config.exact_match?, negatable: config.exact_match?
|
|
333
338
|
|
|
334
339
|
c.desc 'Add note to item that *doesn\'t* match search/tag filters'
|
|
335
340
|
c.switch [:not], default_value: false, negatable: false
|
|
336
341
|
|
|
337
342
|
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
|
338
343
|
c.arg_name 'TYPE'
|
|
339
|
-
c.flag [:case], must_match: /^[csi]/, default_value: '
|
|
344
|
+
c.flag [:case], must_match: /^[csi]/, default_value: settings.dig('search', 'case')
|
|
340
345
|
|
|
341
346
|
c.desc 'Boolean (AND|OR|NOT) with which to combine multiple tag filters. Use PATTERN to parse + and - as booleans.'
|
|
342
347
|
c.arg_name 'BOOLEAN'
|
|
@@ -503,6 +508,13 @@ command :template do |c|
|
|
|
503
508
|
c.desc 'List in single column for completion'
|
|
504
509
|
c.switch %i[c column]
|
|
505
510
|
|
|
511
|
+
c.desc 'Save template to file instead of STDOUT'
|
|
512
|
+
c.switch %i[s save], default_value: false, negatable: false
|
|
513
|
+
|
|
514
|
+
c.desc 'Save template to alternate location'
|
|
515
|
+
c.arg_name 'DIRECTORY'
|
|
516
|
+
c.flag %i[p path], default_value: File.join(Doing::Util.user_home, '.config', 'doing', 'templates')
|
|
517
|
+
|
|
506
518
|
c.action do |_global_options, options, args|
|
|
507
519
|
if options[:list] || options[:column]
|
|
508
520
|
if options[:column]
|
|
@@ -515,13 +527,19 @@ command :template do |c|
|
|
|
515
527
|
|
|
516
528
|
if args.empty?
|
|
517
529
|
type = Doing::Prompt.choose_from(Doing::Plugins.plugin_templates, sorted: false, prompt: 'Select template type > ')
|
|
530
|
+
type.sub!(/ \(.*?\)$/, '').strip!
|
|
531
|
+
options[:save] = Doing::Prompt.yn("Save to #{options[:path]}? (No outputs to STDOUT)", default_response: false)
|
|
518
532
|
else
|
|
519
533
|
type = args[0]
|
|
520
534
|
end
|
|
521
535
|
|
|
522
536
|
raise InvalidPluginType, "No type specified, use `doing template [#{Doing::Plugins.plugin_templates.join('|')}]`" unless type
|
|
523
537
|
|
|
524
|
-
|
|
538
|
+
if options[:save]
|
|
539
|
+
Doing::Plugins.template_for_trigger(type, save_to: options[:path])
|
|
540
|
+
else
|
|
541
|
+
$stdout.puts Doing::Plugins.template_for_trigger(type, save_to: nil)
|
|
542
|
+
end
|
|
525
543
|
|
|
526
544
|
# case args[0]
|
|
527
545
|
# when /html|haml/i
|
|
@@ -599,14 +617,14 @@ command :select do |c|
|
|
|
599
617
|
c.flag [:from]
|
|
600
618
|
|
|
601
619
|
c.desc 'Force exact search string matching (case sensitive)'
|
|
602
|
-
c.switch %i[x exact], default_value:
|
|
620
|
+
c.switch %i[x exact], default_value: config.exact_match?, negatable: config.exact_match?
|
|
603
621
|
|
|
604
622
|
c.desc 'Select items that *don\'t* match search/tag filters'
|
|
605
623
|
c.switch [:not], default_value: false, negatable: false
|
|
606
624
|
|
|
607
625
|
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
|
608
626
|
c.arg_name 'TYPE'
|
|
609
|
-
c.flag [:case], must_match: /^[csi]/, default_value: '
|
|
627
|
+
c.flag [:case], must_match: /^[csi]/, default_value: settings.dig('search', 'case')
|
|
610
628
|
|
|
611
629
|
c.desc 'Use --no-menu to skip the interactive menu. Use with --query to filter items and act on results automatically. Test with `--output doing` to preview matches.'
|
|
612
630
|
c.switch %i[menu], negatable: true, default_value: true
|
|
@@ -711,7 +729,7 @@ command :later do |c|
|
|
|
711
729
|
end
|
|
712
730
|
|
|
713
731
|
desc 'Add a completed item with @done(date). No argument finishes last entry.'
|
|
714
|
-
|
|
732
|
+
long_desc 'Use this command to add an entry after you\'ve already finished it. It will be immediately marked as @done.
|
|
715
733
|
You can modify the start and end times of the entry using the --back, --took, and --at flags, making it an easy
|
|
716
734
|
way to add entries in post and maintain accurate (albeit manual) time tracking.'
|
|
717
735
|
arg_name 'ENTRY'
|
|
@@ -940,14 +958,14 @@ command :cancel do |c|
|
|
|
940
958
|
# c.switch [:fuzzy], default_value: false, negatable: false
|
|
941
959
|
|
|
942
960
|
c.desc 'Force exact search string matching (case sensitive)'
|
|
943
|
-
c.switch %i[x exact], default_value:
|
|
961
|
+
c.switch %i[x exact], default_value: config.exact_match?, negatable: config.exact_match?
|
|
944
962
|
|
|
945
963
|
c.desc 'Finish items that *don\'t* match search/tag filters'
|
|
946
964
|
c.switch [:not], default_value: false, negatable: false
|
|
947
965
|
|
|
948
966
|
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
|
949
967
|
c.arg_name 'TYPE'
|
|
950
|
-
c.flag [:case], must_match: /^[csi]/, default_value: '
|
|
968
|
+
c.flag [:case], must_match: /^[csi]/, default_value: settings.dig('search', 'case')
|
|
951
969
|
|
|
952
970
|
c.desc 'Cancel last entry (or entries) not already marked @done'
|
|
953
971
|
c.switch %i[u unfinished], negatable: false, default_value: false
|
|
@@ -1043,14 +1061,14 @@ command :finish do |c|
|
|
|
1043
1061
|
# c.switch [:fuzzy], default_value: false, negatable: false
|
|
1044
1062
|
|
|
1045
1063
|
c.desc 'Force exact search string matching (case sensitive)'
|
|
1046
|
-
c.switch %i[x exact], default_value:
|
|
1064
|
+
c.switch %i[x exact], default_value: config.exact_match?, negatable: config.exact_match?
|
|
1047
1065
|
|
|
1048
1066
|
c.desc 'Finish items that *don\'t* match search/tag filters'
|
|
1049
1067
|
c.switch [:not], default_value: false, negatable: false
|
|
1050
1068
|
|
|
1051
1069
|
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
|
1052
1070
|
c.arg_name 'TYPE'
|
|
1053
|
-
c.flag [:case], must_match: /^[csi]/, default_value: '
|
|
1071
|
+
c.flag [:case], must_match: /^[csi]/, default_value: settings.dig('search', 'case')
|
|
1054
1072
|
|
|
1055
1073
|
c.desc 'Boolean (AND|OR|NOT) with which to combine multiple tag filters. Use PATTERN to parse + and - as booleans.'
|
|
1056
1074
|
c.arg_name 'BOOLEAN'
|
|
@@ -1182,14 +1200,14 @@ command %i[again resume] do |c|
|
|
|
1182
1200
|
# c.switch [:fuzzy], default_value: false, negatable: false
|
|
1183
1201
|
|
|
1184
1202
|
c.desc 'Force exact search string matching (case sensitive)'
|
|
1185
|
-
c.switch %i[x exact], default_value:
|
|
1203
|
+
c.switch %i[x exact], default_value: config.exact_match?, negatable: config.exact_match?
|
|
1186
1204
|
|
|
1187
1205
|
c.desc 'Resume items that *don\'t* match search/tag filters'
|
|
1188
1206
|
c.switch [:not], default_value: false, negatable: false
|
|
1189
1207
|
|
|
1190
1208
|
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
|
1191
1209
|
c.arg_name 'TYPE'
|
|
1192
|
-
c.flag [:case], must_match: /^[csi]/, default_value: '
|
|
1210
|
+
c.flag [:case], must_match: /^[csi]/, default_value: settings.dig('search', 'case')
|
|
1193
1211
|
|
|
1194
1212
|
c.desc 'Boolean used to combine multiple tags. Use PATTERN to parse + and - as booleans.'
|
|
1195
1213
|
c.arg_name 'BOOLEAN'
|
|
@@ -1244,10 +1262,41 @@ command :tags do |c|
|
|
|
1244
1262
|
c.arg_name 'ORDER'
|
|
1245
1263
|
c.flag %i[o order], must_match: REGEX_SORT_ORDER, default_value: 'asc'
|
|
1246
1264
|
|
|
1265
|
+
c.desc 'Get tags for entries matching tags. Combine multiple tags with a comma. Wildcards allowed (*, ?).'
|
|
1266
|
+
c.arg_name 'TAG'
|
|
1267
|
+
c.flag [:tag]
|
|
1268
|
+
|
|
1269
|
+
c.desc 'Get tags for items matching search. Surround with
|
|
1270
|
+
slashes for regex (e.g. "/query/"), start with a single quote for exact match ("\'query").'
|
|
1271
|
+
c.arg_name 'QUERY'
|
|
1272
|
+
c.flag [:search]
|
|
1273
|
+
|
|
1274
|
+
# c.desc '[DEPRECATED] Use alternative fuzzy matching for search string'
|
|
1275
|
+
# c.switch [:fuzzy], default_value: false, negatable: false
|
|
1276
|
+
|
|
1277
|
+
c.desc 'Force exact search string matching (case sensitive)'
|
|
1278
|
+
c.switch %i[x exact], default_value: config.exact_match?, negatable: config.exact_match?
|
|
1279
|
+
|
|
1280
|
+
c.desc 'Get tags from items that *don\'t* match search/tag filters'
|
|
1281
|
+
c.switch [:not], default_value: false, negatable: false
|
|
1282
|
+
|
|
1283
|
+
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
|
1284
|
+
c.arg_name 'TYPE'
|
|
1285
|
+
c.flag [:case], must_match: /^[csi]/, default_value: settings.dig('search', 'case')
|
|
1286
|
+
|
|
1287
|
+
c.desc 'Boolean used to combine multiple tags. Use PATTERN to parse + and - as booleans.'
|
|
1288
|
+
c.arg_name 'BOOLEAN'
|
|
1289
|
+
c.flag [:bool], must_match: REGEX_BOOL, default_value: 'PATTERN'
|
|
1290
|
+
|
|
1291
|
+
c.desc 'Select items to scan from a menu of matching entries'
|
|
1292
|
+
c.switch %i[i interactive], negatable: false, default_value: false
|
|
1293
|
+
|
|
1247
1294
|
c.action do |_global, options, args|
|
|
1248
1295
|
section = wwid.guess_section(options[:section]) || options[:section].cap_first
|
|
1249
1296
|
|
|
1250
|
-
items = wwid.
|
|
1297
|
+
items = wwid.filter_items([], opt: options)
|
|
1298
|
+
|
|
1299
|
+
# items = wwid.content.in_section(section)
|
|
1251
1300
|
tags = wwid.all_tags(items, counts: true)
|
|
1252
1301
|
|
|
1253
1302
|
if options[:sort] =~ /^n/i
|
|
@@ -1332,14 +1381,14 @@ command :tag do |c|
|
|
|
1332
1381
|
# c.switch [:fuzzy], default_value: false, negatable: false
|
|
1333
1382
|
|
|
1334
1383
|
c.desc 'Force exact search string matching (case sensitive)'
|
|
1335
|
-
c.switch %i[x exact], default_value:
|
|
1384
|
+
c.switch %i[x exact], default_value: config.exact_match?, negatable: config.exact_match?
|
|
1336
1385
|
|
|
1337
1386
|
c.desc 'Tag items that *don\'t* match search/tag filters'
|
|
1338
1387
|
c.switch [:not], default_value: false, negatable: false
|
|
1339
1388
|
|
|
1340
1389
|
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
|
1341
1390
|
c.arg_name 'TYPE'
|
|
1342
|
-
c.flag [:case], must_match: /^[csi]/, default_value: '
|
|
1391
|
+
c.flag [:case], must_match: /^[csi]/, default_value: settings.dig('search', 'case')
|
|
1343
1392
|
|
|
1344
1393
|
c.desc 'Boolean (AND|OR|NOT) with which to combine multiple tag filters. Use PATTERN to parse + and - as booleans.'
|
|
1345
1394
|
c.arg_name 'BOOLEAN'
|
|
@@ -1395,37 +1444,41 @@ command :tag do |c|
|
|
|
1395
1444
|
options[:search] = search
|
|
1396
1445
|
end
|
|
1397
1446
|
|
|
1447
|
+
options[:count] = count
|
|
1448
|
+
options[:section] = section
|
|
1449
|
+
options[:tag] = search_tags
|
|
1450
|
+
options[:tags] = tags
|
|
1451
|
+
options[:tag_bool] = options[:bool].normalize_bool
|
|
1452
|
+
|
|
1398
1453
|
if count.zero? && !options[:force]
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1454
|
+
matches = wwid.filter_items([], opt: options).count
|
|
1455
|
+
|
|
1456
|
+
if matches > 5
|
|
1457
|
+
if options[:search]
|
|
1458
|
+
section_q = ' matching your search terms'
|
|
1459
|
+
elsif options[:tag]
|
|
1460
|
+
section_q = ' matching your tag search'
|
|
1461
|
+
elsif section == 'All'
|
|
1462
|
+
section_q = ''
|
|
1463
|
+
else
|
|
1464
|
+
section_q = " in section #{section}"
|
|
1465
|
+
end
|
|
1408
1466
|
|
|
1409
1467
|
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1468
|
+
question = if options[:autotag]
|
|
1469
|
+
"Are you sure you want to autotag #{matches} records#{section_q}"
|
|
1470
|
+
elsif options[:remove]
|
|
1471
|
+
"Are you sure you want to remove #{tags.join(' and ')} from #{matches} records#{section_q}"
|
|
1472
|
+
else
|
|
1473
|
+
"Are you sure you want to add #{tags.join(' and ')} to #{matches} records#{section_q}"
|
|
1474
|
+
end
|
|
1417
1475
|
|
|
1418
|
-
|
|
1476
|
+
res = Doing::Prompt.yn(question, default_response: false)
|
|
1419
1477
|
|
|
1420
|
-
|
|
1478
|
+
raise UserCancelled unless res
|
|
1479
|
+
end
|
|
1421
1480
|
end
|
|
1422
1481
|
|
|
1423
|
-
options[:count] = count
|
|
1424
|
-
options[:section] = section
|
|
1425
|
-
options[:tag] = search_tags
|
|
1426
|
-
options[:tags] = tags
|
|
1427
|
-
options[:tag_bool] = options[:bool].normalize_bool
|
|
1428
|
-
|
|
1429
1482
|
wwid.tag_last(options)
|
|
1430
1483
|
end
|
|
1431
1484
|
end
|
|
@@ -1470,14 +1523,14 @@ command %i[mark flag] do |c|
|
|
|
1470
1523
|
# c.switch [:fuzzy], default_value: false, negatable: false
|
|
1471
1524
|
|
|
1472
1525
|
c.desc 'Force exact search string matching (case sensitive)'
|
|
1473
|
-
c.switch %i[x exact], default_value:
|
|
1526
|
+
c.switch %i[x exact], default_value: config.exact_match?, negatable: config.exact_match?
|
|
1474
1527
|
|
|
1475
1528
|
c.desc 'Flag items that *don\'t* match search/tag/date filters'
|
|
1476
1529
|
c.switch [:not], default_value: false, negatable: false
|
|
1477
1530
|
|
|
1478
1531
|
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
|
1479
1532
|
c.arg_name 'TYPE'
|
|
1480
|
-
c.flag [:case], must_match: /^[csi]/, default_value: '
|
|
1533
|
+
c.flag [:case], must_match: /^[csi]/, default_value: settings.dig('search', 'case')
|
|
1481
1534
|
|
|
1482
1535
|
c.desc 'Boolean (AND|OR|NOT) with which to combine multiple tag filters. Use PATTERN to parse + and - as booleans.'
|
|
1483
1536
|
c.arg_name 'BOOLEAN'
|
|
@@ -1581,7 +1634,7 @@ command :show do |c|
|
|
|
1581
1634
|
|
|
1582
1635
|
c.desc 'Max count to show'
|
|
1583
1636
|
c.arg_name 'MAX'
|
|
1584
|
-
c.flag %i[c count], default_value: 0
|
|
1637
|
+
c.flag %i[c count], default_value: 0, must_match: /^\d+$/, type: Integer
|
|
1585
1638
|
|
|
1586
1639
|
c.desc 'Age (oldest|newest)'
|
|
1587
1640
|
c.arg_name 'AGE'
|
|
@@ -1615,14 +1668,14 @@ command :show do |c|
|
|
|
1615
1668
|
# c.switch [:fuzzy], default_value: false, negatable: false
|
|
1616
1669
|
|
|
1617
1670
|
c.desc 'Force exact search string matching (case sensitive)'
|
|
1618
|
-
c.switch %i[x exact], default_value:
|
|
1671
|
+
c.switch %i[x exact], default_value: config.exact_match?, negatable: config.exact_match?
|
|
1619
1672
|
|
|
1620
1673
|
c.desc 'Show items that *don\'t* match search/tag/date filters'
|
|
1621
1674
|
c.switch [:not], default_value: false, negatable: false
|
|
1622
1675
|
|
|
1623
1676
|
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
|
1624
1677
|
c.arg_name 'TYPE'
|
|
1625
|
-
c.flag [:case], must_match: /^[csi]/, default_value: '
|
|
1678
|
+
c.flag [:case], must_match: /^[csi]/, default_value: settings.dig('search', 'case')
|
|
1626
1679
|
|
|
1627
1680
|
c.desc 'Sort order (asc/desc)'
|
|
1628
1681
|
c.arg_name 'ORDER'
|
|
@@ -1699,24 +1752,11 @@ command :show do |c|
|
|
|
1699
1752
|
end
|
|
1700
1753
|
else
|
|
1701
1754
|
section = options[:menu] ? wwid.choose_section(include_all: true) : settings['current_section']
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
if options[:menu]
|
|
1705
|
-
tag = wwid.choose_tag(section, include_all: true)
|
|
1706
|
-
raise UserCancelled unless tag
|
|
1707
|
-
|
|
1708
|
-
tags.concat(tag.split(/ +/).map { |t| t.strip.sub(/^@/, '') }) if tag =~ /^@/
|
|
1755
|
+
section ||= 'All'
|
|
1709
1756
|
end
|
|
1710
1757
|
|
|
1711
1758
|
tags.concat(options[:tag].to_tags) if options[:tag]
|
|
1712
1759
|
|
|
1713
|
-
unless tags.empty?
|
|
1714
|
-
tag_filter = {
|
|
1715
|
-
'tags' => tags,
|
|
1716
|
-
'bool' => options[:bool].normalize_bool
|
|
1717
|
-
}
|
|
1718
|
-
end
|
|
1719
|
-
|
|
1720
1760
|
options[:times] = true if options[:totals]
|
|
1721
1761
|
|
|
1722
1762
|
template = settings['templates']['default'].deep_merge({
|
|
@@ -1734,18 +1774,46 @@ command :show do |c|
|
|
|
1734
1774
|
options[:search] = search
|
|
1735
1775
|
end
|
|
1736
1776
|
|
|
1777
|
+
options[:section] = section
|
|
1778
|
+
|
|
1779
|
+
unless tags.empty?
|
|
1780
|
+
tag_filter = {
|
|
1781
|
+
'tags' => tags,
|
|
1782
|
+
'bool' => options[:bool].normalize_bool
|
|
1783
|
+
}
|
|
1784
|
+
end
|
|
1785
|
+
|
|
1786
|
+
options[:tag_filter] = tag_filter
|
|
1787
|
+
options[:tag] = nil
|
|
1788
|
+
|
|
1789
|
+
items = wwid.filter_items([], opt: options)
|
|
1790
|
+
|
|
1791
|
+
if options[:menu]
|
|
1792
|
+
tag = wwid.choose_tag(section, items: items, include_all: true)
|
|
1793
|
+
raise UserCancelled unless tag
|
|
1794
|
+
|
|
1795
|
+
# options[:bool] = :and unless tags.empty?
|
|
1796
|
+
|
|
1797
|
+
tags = tag.split(/ +/).map { |t| t.strip.sub(/^@?/, '') } if tag =~ /^@/
|
|
1798
|
+
unless tags.empty?
|
|
1799
|
+
tag_filter = {
|
|
1800
|
+
'tags' => tags,
|
|
1801
|
+
'bool' => options[:bool].normalize_bool
|
|
1802
|
+
}
|
|
1803
|
+
options[:tag_filter] = tag_filter
|
|
1804
|
+
end
|
|
1805
|
+
end
|
|
1806
|
+
|
|
1737
1807
|
opt = options.dup
|
|
1738
1808
|
opt[:sort_tags] = options[:tag_sort] =~ /^n/i
|
|
1739
1809
|
opt[:count] = options[:count].to_i
|
|
1740
1810
|
opt[:highlight] = true
|
|
1741
1811
|
opt[:order] = options[:sort].normalize_order
|
|
1742
|
-
opt[:section] = section
|
|
1743
1812
|
opt[:tag] = nil
|
|
1744
|
-
opt[:tag_filter] = tag_filter
|
|
1745
1813
|
opt[:tag_order] = options[:tag_order].normalize_order
|
|
1746
1814
|
opt[:tags_color] = template['tags_color']
|
|
1747
1815
|
|
|
1748
|
-
Doing::Pager.page wwid.list_section(opt)
|
|
1816
|
+
Doing::Pager.page wwid.list_section(opt, items: items)
|
|
1749
1817
|
end
|
|
1750
1818
|
end
|
|
1751
1819
|
|
|
@@ -1812,14 +1880,14 @@ command %i[grep search] do |c|
|
|
|
1812
1880
|
# c.switch [:fuzzy], default_value: false, negatable: false
|
|
1813
1881
|
|
|
1814
1882
|
c.desc 'Force exact string matching (case sensitive)'
|
|
1815
|
-
c.switch %i[x exact], default_value:
|
|
1883
|
+
c.switch %i[x exact], default_value: config.exact_match?, negatable: config.exact_match?
|
|
1816
1884
|
|
|
1817
1885
|
c.desc 'Show items that *don\'t* match search string'
|
|
1818
1886
|
c.switch [:not], default_value: false, negatable: false
|
|
1819
1887
|
|
|
1820
1888
|
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
|
1821
1889
|
c.arg_name 'TYPE'
|
|
1822
|
-
c.flag [:case], must_match: /^[csi]/, default_value: '
|
|
1890
|
+
c.flag [:case], must_match: /^[csi]/, default_value: settings.dig('search', 'case')
|
|
1823
1891
|
|
|
1824
1892
|
c.desc 'Display an interactive menu of results to perform further operations'
|
|
1825
1893
|
c.switch %i[i interactive], default_value: false, negatable: false
|
|
@@ -2094,7 +2162,7 @@ command :since do |c|
|
|
|
2094
2162
|
end
|
|
2095
2163
|
|
|
2096
2164
|
desc 'List entries from yesterday'
|
|
2097
|
-
|
|
2165
|
+
long_desc 'Show only entries with start times within the previous 24 hour period. Use --before, --after, and --from to limit to
|
|
2098
2166
|
time spans within the day.'
|
|
2099
2167
|
command :yesterday do |c|
|
|
2100
2168
|
c.example 'doing yesterday', desc: 'List all entries from the previous day'
|
|
@@ -2204,14 +2272,14 @@ command :last do |c|
|
|
|
2204
2272
|
# c.switch [:fuzzy], default_value: false, negatable: false
|
|
2205
2273
|
|
|
2206
2274
|
c.desc 'Force exact search string matching (case sensitive)'
|
|
2207
|
-
c.switch %i[x exact], default_value:
|
|
2275
|
+
c.switch %i[x exact], default_value: config.exact_match?, negatable: config.exact_match?
|
|
2208
2276
|
|
|
2209
2277
|
c.desc 'Show items that *don\'t* match search string or tag filter'
|
|
2210
2278
|
c.switch [:not], default_value: false, negatable: false
|
|
2211
2279
|
|
|
2212
2280
|
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
|
2213
2281
|
c.arg_name 'TYPE'
|
|
2214
|
-
c.flag [:case], must_match: /^[csi]/, default_value: '
|
|
2282
|
+
c.flag [:case], must_match: /^[csi]/, default_value: settings.dig('search', 'case')
|
|
2215
2283
|
|
|
2216
2284
|
c.action do |global_options, options, _args|
|
|
2217
2285
|
options[:fuzzy] = false
|
|
@@ -2221,17 +2289,7 @@ command :last do |c|
|
|
|
2221
2289
|
tags = []
|
|
2222
2290
|
else
|
|
2223
2291
|
tags = options[:tag].to_tags
|
|
2224
|
-
options[:bool] =
|
|
2225
|
-
when /^p/i
|
|
2226
|
-
:pattern
|
|
2227
|
-
when /(any|or)/i
|
|
2228
|
-
:or
|
|
2229
|
-
when /(not|none)/i
|
|
2230
|
-
:not
|
|
2231
|
-
else
|
|
2232
|
-
:and
|
|
2233
|
-
end
|
|
2234
|
-
|
|
2292
|
+
options[:bool] = options[:bool].normalize_bool
|
|
2235
2293
|
end
|
|
2236
2294
|
|
|
2237
2295
|
options[:case] = options[:case].normalize_case
|
|
@@ -2336,7 +2394,7 @@ command :plugins do |c|
|
|
|
2336
2394
|
end
|
|
2337
2395
|
|
|
2338
2396
|
desc 'Generate shell completion scripts'
|
|
2339
|
-
|
|
2397
|
+
long_desc 'Generates the necessary scripts to add command line completion to various shells, so typing \'doing\' and hitting
|
|
2340
2398
|
tab will offer completions of subcommands and their options.'
|
|
2341
2399
|
command :completion do |c|
|
|
2342
2400
|
c.example 'doing completion', desc: 'Output zsh (default) to STDOUT'
|
|
@@ -2407,14 +2465,14 @@ command :view do |c|
|
|
|
2407
2465
|
# c.switch [:fuzzy], default_value: false, negatable: false
|
|
2408
2466
|
|
|
2409
2467
|
c.desc 'Force exact search string matching (case sensitive)'
|
|
2410
|
-
c.switch %i[x exact], default_value:
|
|
2468
|
+
c.switch %i[x exact], default_value: config.exact_match?, negatable: config.exact_match?
|
|
2411
2469
|
|
|
2412
2470
|
c.desc 'Show items that *don\'t* match search string'
|
|
2413
2471
|
c.switch [:not], default_value: false, negatable: false
|
|
2414
2472
|
|
|
2415
2473
|
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
|
2416
2474
|
c.arg_name 'TYPE'
|
|
2417
|
-
c.flag [:case], must_match: /^[csi]/, default_value: '
|
|
2475
|
+
c.flag [:case], must_match: /^[csi]/, default_value: settings.dig('search', 'case')
|
|
2418
2476
|
|
|
2419
2477
|
c.desc 'Sort tags by (name|time)'
|
|
2420
2478
|
c.arg_name 'KEY'
|
|
@@ -2476,6 +2534,7 @@ command :view do |c|
|
|
|
2476
2534
|
end
|
|
2477
2535
|
|
|
2478
2536
|
view = wwid.get_view(title)
|
|
2537
|
+
|
|
2479
2538
|
if view
|
|
2480
2539
|
page_title = view.key?('title') ? view['title'] : title.cap_first
|
|
2481
2540
|
only_timed = if (view.key?('only_timed') && view['only_timed']) || options[:only_timed]
|
|
@@ -2555,6 +2614,7 @@ command :view do |c|
|
|
|
2555
2614
|
end
|
|
2556
2615
|
|
|
2557
2616
|
opts = options.dup
|
|
2617
|
+
opts[:view_template] = title
|
|
2558
2618
|
opts[:count] = count
|
|
2559
2619
|
opts[:format] = date_format
|
|
2560
2620
|
opts[:highlight] = options[:color]
|
|
@@ -2631,14 +2691,14 @@ command %i[archive move] do |c|
|
|
|
2631
2691
|
# c.switch [:fuzzy], default_value: false, negatable: false
|
|
2632
2692
|
|
|
2633
2693
|
c.desc 'Force exact search string matching (case sensitive)'
|
|
2634
|
-
c.switch %i[x exact], default_value:
|
|
2694
|
+
c.switch %i[x exact], default_value: config.exact_match?, negatable: config.exact_match?
|
|
2635
2695
|
|
|
2636
2696
|
c.desc 'Show items that *don\'t* match search string'
|
|
2637
2697
|
c.switch [:not], default_value: false, negatable: false
|
|
2638
2698
|
|
|
2639
2699
|
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
|
2640
2700
|
c.arg_name 'TYPE'
|
|
2641
|
-
c.flag [:case], must_match: /^[csi]/, default_value: '
|
|
2701
|
+
c.flag [:case], must_match: /^[csi]/, default_value: settings.dig('search', 'case')
|
|
2642
2702
|
|
|
2643
2703
|
c.desc 'Archive entries older than date
|
|
2644
2704
|
(Flexible date format, e.g. 1/27/2021, 2020-07-19, or Monday 3pm)'
|
|
@@ -2716,14 +2776,14 @@ command :rotate do |c|
|
|
|
2716
2776
|
# c.switch [:fuzzy], default_value: false, negatable: false
|
|
2717
2777
|
|
|
2718
2778
|
c.desc 'Force exact search string matching (case sensitive)'
|
|
2719
|
-
c.switch %i[x exact], default_value:
|
|
2779
|
+
c.switch %i[x exact], default_value: config.exact_match?, negatable: config.exact_match?
|
|
2720
2780
|
|
|
2721
2781
|
c.desc 'Rotate items that *don\'t* match search string or tag filter'
|
|
2722
2782
|
c.switch [:not], default_value: false, negatable: false
|
|
2723
2783
|
|
|
2724
2784
|
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
|
2725
2785
|
c.arg_name 'TYPE'
|
|
2726
|
-
c.flag [:case], must_match: /^[csi]/, default_value: '
|
|
2786
|
+
c.flag [:case], must_match: /^[csi]/, default_value: settings.dig('search', 'case')
|
|
2727
2787
|
|
|
2728
2788
|
c.desc 'Rotate entries older than date
|
|
2729
2789
|
(Flexible date format, e.g. 1/27/2021, 2020-07-19, or Monday 3pm)'
|
|
@@ -2930,7 +2990,7 @@ command :config do |c|
|
|
|
2930
2990
|
c.command :undo do |undo|
|
|
2931
2991
|
undo.action do |_global, options, args|
|
|
2932
2992
|
config_file = config.choose_config
|
|
2933
|
-
|
|
2993
|
+
Doing::Util::Backup.restore_last_backup(config_file, count: 1)
|
|
2934
2994
|
end
|
|
2935
2995
|
end
|
|
2936
2996
|
|
|
@@ -3078,7 +3138,11 @@ command :undo do |c|
|
|
|
3078
3138
|
if options[:prune]
|
|
3079
3139
|
Doing::Util::Backup.prune_backups(file, options[:prune])
|
|
3080
3140
|
elsif options[:redo]
|
|
3081
|
-
|
|
3141
|
+
if options[:interactive]
|
|
3142
|
+
Doing::Util::Backup.select_redo(file)
|
|
3143
|
+
else
|
|
3144
|
+
Doing::Util::Backup.redo_backup(file, count: count)
|
|
3145
|
+
end
|
|
3082
3146
|
else
|
|
3083
3147
|
if options[:interactive]
|
|
3084
3148
|
Doing::Util::Backup.select_backup(file)
|
|
@@ -3096,12 +3160,18 @@ command :redo do |c|
|
|
|
3096
3160
|
c.arg_name 'PATH'
|
|
3097
3161
|
c.flag %i[f file], default_value: wwid.doing_file
|
|
3098
3162
|
|
|
3163
|
+
c.desc 'Select from an interactive menu'
|
|
3164
|
+
c.switch %i[i interactive]
|
|
3165
|
+
|
|
3099
3166
|
c.action do |_global, options, args|
|
|
3100
3167
|
file = options[:file] || wwid.doing_file
|
|
3101
3168
|
count = args.empty? ? 1 : args[0].to_i
|
|
3102
3169
|
raise InvalidArgument, "Invalid count specified for redo" unless count&.positive?
|
|
3103
|
-
|
|
3104
|
-
|
|
3170
|
+
if options[:interactive]
|
|
3171
|
+
Doing::Util::Backup.select_redo(file)
|
|
3172
|
+
else
|
|
3173
|
+
Doing::Util::Backup.redo_backup(file, count: count)
|
|
3174
|
+
end
|
|
3105
3175
|
end
|
|
3106
3176
|
end
|
|
3107
3177
|
|
|
@@ -3120,6 +3190,32 @@ command %i[changelog changes] do |c|
|
|
|
3120
3190
|
end
|
|
3121
3191
|
end
|
|
3122
3192
|
|
|
3193
|
+
arg_name 'OPTION'
|
|
3194
|
+
command :commands_accepting do |c|
|
|
3195
|
+
c.desc 'Output in single column for completion'
|
|
3196
|
+
c.switch %i[c column]
|
|
3197
|
+
|
|
3198
|
+
c.action do |g, o, a|
|
|
3199
|
+
a.each do |option|
|
|
3200
|
+
cmds = []
|
|
3201
|
+
commands.each do |cmd, v|
|
|
3202
|
+
v.flags.merge(v.switches).each do |n, flag|
|
|
3203
|
+
if flag.name == option.to_sym || flag.aliases&.include?(option.to_sym)
|
|
3204
|
+
cmds.push(cmd)
|
|
3205
|
+
end
|
|
3206
|
+
end
|
|
3207
|
+
end
|
|
3208
|
+
|
|
3209
|
+
if o[:column]
|
|
3210
|
+
puts cmds
|
|
3211
|
+
else
|
|
3212
|
+
puts "Commands accepting --#{option}: #{cmds.join(', ')}"
|
|
3213
|
+
end
|
|
3214
|
+
end
|
|
3215
|
+
end
|
|
3216
|
+
end
|
|
3217
|
+
|
|
3218
|
+
|
|
3123
3219
|
desc 'Import entries from an external source'
|
|
3124
3220
|
long_desc "Imports entries from other sources. Available plugins: #{Doing::Plugins.plugin_names(type: :import, separator: ', ')}"
|
|
3125
3221
|
arg_name 'PATH'
|
|
@@ -3140,14 +3236,14 @@ command :import do |c|
|
|
|
3140
3236
|
# c.switch [:fuzzy], default_value: false, negatable: false
|
|
3141
3237
|
|
|
3142
3238
|
c.desc 'Force exact search string matching (case sensitive)'
|
|
3143
|
-
c.switch %i[x exact], default_value:
|
|
3239
|
+
c.switch %i[x exact], default_value: config.exact_match?, negatable: config.exact_match?
|
|
3144
3240
|
|
|
3145
3241
|
c.desc 'Import items that *don\'t* match search/tag/date filters'
|
|
3146
3242
|
c.switch [:not], default_value: false, negatable: false
|
|
3147
3243
|
|
|
3148
3244
|
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
|
3149
3245
|
c.arg_name 'TYPE'
|
|
3150
|
-
c.flag [:case], must_match: /^[csi]/, default_value: '
|
|
3246
|
+
c.flag [:case], must_match: /^[csi]/, default_value: settings.dig('search', 'case')
|
|
3151
3247
|
|
|
3152
3248
|
c.desc 'Only import items with recorded time intervals'
|
|
3153
3249
|
c.switch [:only_timed], default_value: false, negatable: false
|
|
@@ -3222,7 +3318,6 @@ end
|
|
|
3222
3318
|
|
|
3223
3319
|
pre do |global, _command, _options, _args|
|
|
3224
3320
|
# global[:pager] ||= settings['paginate']
|
|
3225
|
-
|
|
3226
3321
|
Doing::Pager.paginate = global[:pager]
|
|
3227
3322
|
|
|
3228
3323
|
$stdout.puts "doing v#{Doing::VERSION}" if global[:version]
|
|
@@ -3253,6 +3348,8 @@ post do |global, _command, _options, _args|
|
|
|
3253
3348
|
# Use skips_post before a command to skip this
|
|
3254
3349
|
# block on that command only
|
|
3255
3350
|
Doing.logger.output_results
|
|
3351
|
+
Doing.logger.benchmark(:total, :finish)
|
|
3352
|
+
Doing.logger.log_benchmarks
|
|
3256
3353
|
end
|
|
3257
3354
|
|
|
3258
3355
|
around do |global, command, options, arguments, code|
|
|
@@ -3286,13 +3383,13 @@ around do |global, command, options, arguments, code|
|
|
|
3286
3383
|
config.config_file = cf
|
|
3287
3384
|
settings = config.configure({ ignore_local: true })
|
|
3288
3385
|
end
|
|
3289
|
-
|
|
3386
|
+
Doing.logger.benchmark(:init, :start)
|
|
3290
3387
|
if global[:doing_file]
|
|
3291
3388
|
wwid.init_doing_file(global[:doing_file])
|
|
3292
3389
|
else
|
|
3293
3390
|
wwid.init_doing_file
|
|
3294
3391
|
end
|
|
3295
|
-
|
|
3392
|
+
Doing.logger.benchmark(:init, :finish)
|
|
3296
3393
|
wwid.auto_tag = !global[:noauto]
|
|
3297
3394
|
|
|
3298
3395
|
settings[:include_notes] = false unless global[:notes]
|
data/docs/_config.yml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
theme: jekyll-theme-slate
|