doing 2.1.24 → 2.1.28
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 +17 -21
- data/.yardoc/object_types +0 -0
- data/.yardoc/objects/root.dat +0 -0
- data/CHANGELOG.md +325 -102
- data/Dockerfile +5 -5
- data/Dockerfile-2.6 +5 -5
- data/Dockerfile-2.7 +5 -4
- data/Dockerfile-3.0 +5 -4
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/Rakefile +3 -3
- data/bin/commands/add_section.rb +15 -0
- data/bin/commands/again.rb +57 -0
- data/bin/commands/archive.rb +55 -0
- data/bin/commands/cancel.rb +60 -0
- data/bin/commands/changes.rb +73 -0
- data/bin/commands/choose.rb +9 -0
- data/bin/commands/colors.rb +21 -0
- data/bin/commands/commands.rb +89 -0
- data/bin/commands/commands_accepting.rb +76 -0
- data/bin/commands/completion.rb +27 -0
- data/bin/commands/config.rb +245 -0
- data/bin/commands/done.rb +235 -0
- data/bin/commands/finish.rb +126 -0
- data/bin/commands/flag.rb +90 -0
- data/bin/commands/grep.rb +108 -0
- data/bin/commands/import.rb +71 -0
- data/bin/commands/install_fzf.rb +17 -0
- data/bin/commands/last.rb +81 -0
- data/bin/commands/meanwhile.rb +76 -0
- data/bin/commands/note.rb +91 -0
- data/bin/commands/now.rb +145 -0
- data/bin/commands/on.rb +65 -0
- data/bin/commands/open.rb +53 -0
- data/bin/commands/plugins.rb +23 -0
- data/bin/commands/recent.rb +77 -0
- data/bin/commands/redo.rb +26 -0
- data/bin/commands/reset.rb +73 -0
- data/bin/commands/rotate.rb +42 -0
- data/bin/commands/sections.rb +11 -0
- data/bin/commands/select.rb +105 -0
- data/bin/commands/show.rb +185 -0
- data/bin/commands/since.rb +63 -0
- data/bin/commands/tag.rb +149 -0
- data/bin/commands/tag_dir.rb +29 -0
- data/bin/commands/tags.rb +66 -0
- data/bin/commands/template.rb +61 -0
- data/bin/commands/today.rb +64 -0
- data/bin/commands/undo.rb +49 -0
- data/bin/commands/view.rb +201 -0
- data/bin/commands/views.rb +11 -0
- data/bin/commands/yesterday.rb +72 -0
- data/bin/doing +241 -3662
- data/docs/doc/Array.html +13 -449
- data/docs/doc/BooleanTermParser/Clause.html +5 -5
- data/docs/doc/BooleanTermParser/Operator.html +4 -4
- data/docs/doc/BooleanTermParser/Query.html +8 -8
- data/docs/doc/BooleanTermParser/QueryParser.html +2 -2
- data/docs/doc/BooleanTermParser/QueryTransformer.html +2 -2
- data/docs/doc/BooleanTermParser.html +1 -1
- data/docs/doc/Doing/Color.html +65 -59
- data/docs/doc/Doing/Completion.html +2 -2
- data/docs/doc/Doing/Configuration.html +49 -16
- data/docs/doc/Doing/Errors/DoingNoTraceError.html +2 -2
- data/docs/doc/Doing/Errors/DoingRuntimeError.html +2 -2
- data/docs/doc/Doing/Errors/DoingStandardError.html +2 -2
- data/docs/doc/Doing/Errors/EmptyInput.html +2 -2
- data/docs/doc/Doing/Errors/NoResults.html +2 -2
- data/docs/doc/Doing/Errors/PluginException.html +3 -3
- data/docs/doc/Doing/Errors/UserCancelled.html +2 -2
- data/docs/doc/Doing/Errors/WrongCommand.html +2 -2
- data/docs/doc/Doing/Errors.html +1 -1
- data/docs/doc/Doing/Hooks.html +6 -6
- data/docs/doc/Doing/Item.html +50 -16
- data/docs/doc/Doing/Items.html +10 -10
- data/docs/doc/Doing/LogAdapter.html +24 -24
- data/docs/doc/Doing/Note.html +7 -7
- data/docs/doc/Doing/Pager.html +4 -4
- data/docs/doc/Doing/Plugins.html +7 -7
- data/docs/doc/Doing/Prompt.html +59 -14
- data/docs/doc/Doing/Section.html +6 -6
- data/docs/doc/Doing/TemplateString.html +8 -8
- data/docs/doc/Doing/Types.html +46 -1
- data/docs/doc/Doing/Util/Backup.html +10 -10
- data/docs/doc/Doing/Util.html +15 -15
- data/docs/doc/Doing/WWID.html +73 -61
- data/docs/doc/Doing.html +3 -3
- data/docs/doc/FalseClass.html +235 -0
- data/docs/doc/GLI/Commands/Help.html +3 -3
- data/docs/doc/GLI/Commands/MarkdownDocumentListener.html +17 -17
- data/docs/doc/GLI/Commands.html +1 -1
- data/docs/doc/GLI.html +1 -1
- data/docs/doc/Hash.html +45 -11
- data/docs/doc/Numeric.html +5 -5
- data/docs/doc/Object.html +203 -0
- data/docs/doc/PhraseParser/Operator.html +4 -4
- data/docs/doc/PhraseParser/PhraseClause.html +5 -5
- data/docs/doc/PhraseParser/Query.html +10 -10
- data/docs/doc/PhraseParser/QueryParser.html +2 -2
- data/docs/doc/PhraseParser/QueryTransformer.html +2 -2
- data/docs/doc/PhraseParser/TermClause.html +5 -5
- data/docs/doc/PhraseParser.html +1 -1
- data/docs/doc/Status.html +7 -7
- data/docs/doc/String.html +306 -3111
- data/docs/doc/Symbol.html +45 -11
- data/docs/doc/Time.html +6 -6
- data/docs/doc/TrueClass.html +235 -0
- data/docs/doc/_index.html +37 -19
- 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 +240 -576
- data/docs/doc/top-level-namespace.html +2 -2
- data/doing.rdoc +297 -169
- data/example_plugin.rb +2 -2
- data/lib/completion/_doing.zsh +35 -31
- data/lib/completion/doing.bash +30 -19
- data/lib/completion/doing.fish +81 -67
- data/lib/doing/array/array.rb +4 -0
- data/lib/doing/array/nested_hash.rb +17 -0
- data/lib/doing/{array.rb → array/tags.rb} +7 -25
- data/lib/doing/changelog/change.rb +26 -11
- data/lib/doing/changelog/changes.rb +16 -4
- data/lib/doing/{array_chronify.rb → chronify/array.rb} +0 -0
- data/lib/doing/chronify/chronify.rb +5 -0
- data/lib/doing/{numeric_chronify.rb → chronify/numeric.rb} +0 -0
- data/lib/doing/{string_chronify.rb → chronify/string.rb} +0 -0
- data/lib/doing/colors.rb +115 -54
- data/lib/doing/configuration.rb +9 -6
- data/lib/doing/good.rb +72 -0
- data/lib/doing/hash.rb +4 -0
- data/lib/doing/help_monkey_patch.rb +6 -5
- data/lib/doing/hooks.rb +3 -3
- data/lib/doing/item.rb +19 -15
- data/lib/doing/items.rb +2 -2
- data/lib/doing/log_adapter.rb +35 -2
- data/lib/doing/normalize.rb +188 -0
- data/lib/doing/pager.rb +1 -0
- data/lib/doing/plugins/export/dayone_export.rb +1 -1
- data/lib/doing/plugins/export/html_export.rb +1 -1
- data/lib/doing/plugins/export/json_export.rb +1 -1
- data/lib/doing/plugins/export/markdown_export.rb +1 -1
- data/lib/doing/plugins/export/template_export.rb +3 -1
- data/lib/doing/plugins/import/calendar_import.rb +1 -1
- data/lib/doing/plugins/import/doing_import.rb +1 -1
- data/lib/doing/plugins/import/timing_import.rb +1 -1
- data/lib/doing/prompt.rb +9 -3
- data/lib/doing/string/highlight.rb +95 -0
- data/lib/doing/string/query.rb +129 -0
- data/lib/doing/string/string.rb +12 -0
- data/lib/doing/string/tags.rb +164 -0
- data/lib/doing/string/transform.rb +168 -0
- data/lib/doing/string/truncate.rb +75 -0
- data/lib/doing/string/url.rb +82 -0
- data/lib/doing/template_string.rb +2 -24
- data/lib/doing/types.rb +9 -0
- data/lib/doing/util.rb +20 -16
- data/lib/doing/version.rb +1 -1
- data/lib/doing/wwid.rb +91 -51
- data/lib/doing.rb +5 -6
- data/lib/examples/commands/wiki.rb +6 -7
- data/lib/examples/plugins/wiki_export/wiki_export.rb +1 -1
- data/lib/helpers/threaded_tests.rb +69 -79
- data/lib/helpers/threaded_tests_string.rb +50 -0
- data/scripts/deploy.rb +107 -0
- data/scripts/runtests.sh +4 -0
- metadata +65 -8
- data/lib/doing/string.rb +0 -765
- data/lib/doing/symbol.rb +0 -28
data/lib/doing/wwid.rb
CHANGED
|
@@ -338,6 +338,7 @@ module Doing
|
|
|
338
338
|
## @option opt :note [Array] item note (will be converted if value is String)
|
|
339
339
|
## @option opt :back [Date] backdate
|
|
340
340
|
## @option opt :timed [Boolean] new item is timed entry, marks previous entry as @done
|
|
341
|
+
## @option opt :done [Date] If set, adds a @done tag to new entry
|
|
341
342
|
##
|
|
342
343
|
def add_item(title, section = nil, opt)
|
|
343
344
|
opt ||= {}
|
|
@@ -360,9 +361,18 @@ module Doing
|
|
|
360
361
|
|
|
361
362
|
title.compress!
|
|
362
363
|
entry = Item.new(opt[:back], title.strip, section)
|
|
364
|
+
|
|
365
|
+
if opt[:done] && entry.should_finish?
|
|
366
|
+
if entry.should_time?
|
|
367
|
+
entry.tag('done', value: opt[:done])
|
|
368
|
+
else
|
|
369
|
+
entry.tag('done')
|
|
370
|
+
end
|
|
371
|
+
end
|
|
372
|
+
|
|
363
373
|
entry.note = note
|
|
364
374
|
|
|
365
|
-
items = @content.
|
|
375
|
+
items = @content.clone
|
|
366
376
|
if opt[:timed]
|
|
367
377
|
items.reverse!
|
|
368
378
|
items.each_with_index do |i, x|
|
|
@@ -380,7 +390,8 @@ module Doing
|
|
|
380
390
|
# logger.count(:added, level: :debug)
|
|
381
391
|
logger.info('New entry:', %(added "#{entry.date.relative_date}: #{entry.title}" to #{section}))
|
|
382
392
|
|
|
383
|
-
Hooks.trigger :post_entry_added, self, entry
|
|
393
|
+
Hooks.trigger :post_entry_added, self, entry
|
|
394
|
+
entry
|
|
384
395
|
end
|
|
385
396
|
|
|
386
397
|
##
|
|
@@ -474,6 +485,7 @@ module Doing
|
|
|
474
485
|
#
|
|
475
486
|
def repeat_item(item, opt)
|
|
476
487
|
opt ||= {}
|
|
488
|
+
old_item = item.clone
|
|
477
489
|
if item.should_finish?
|
|
478
490
|
if item.should_time?
|
|
479
491
|
finish_date = verify_duration(item.date, Time.now, title: item.title)
|
|
@@ -481,7 +493,7 @@ module Doing
|
|
|
481
493
|
else
|
|
482
494
|
item.title.tag!('done')
|
|
483
495
|
end
|
|
484
|
-
Hooks.trigger :post_entry_updated, self, item
|
|
496
|
+
Hooks.trigger :post_entry_updated, self, item, old_item
|
|
485
497
|
end
|
|
486
498
|
|
|
487
499
|
# Remove @done tag
|
|
@@ -647,11 +659,12 @@ module Doing
|
|
|
647
659
|
## @option opt [Array] :val (nil) Array of tag value queries
|
|
648
660
|
##
|
|
649
661
|
def filter_items(items = Items.new, opt: {})
|
|
662
|
+
logger.benchmark(:filter_items, :start)
|
|
650
663
|
time_rx = /^(\d{1,2}+(:\d{1,2}+)?( *(am|pm))?|midnight|noon)$/
|
|
651
664
|
|
|
652
665
|
if items.nil? || items.empty?
|
|
653
666
|
section = opt[:section] ? guess_section(opt[:section]) : 'All'
|
|
654
|
-
items = section =~ /^all$/i ? @content.
|
|
667
|
+
items = section =~ /^all$/i ? @content.clone : @content.in_section(section)
|
|
655
668
|
end
|
|
656
669
|
|
|
657
670
|
opt[:time_filter] = [nil, nil]
|
|
@@ -798,6 +811,8 @@ module Doing
|
|
|
798
811
|
output.concat(filtered_items.reverse.slice(0, count))
|
|
799
812
|
end
|
|
800
813
|
|
|
814
|
+
logger.benchmark(:filter_items, :finish)
|
|
815
|
+
|
|
801
816
|
output
|
|
802
817
|
end
|
|
803
818
|
|
|
@@ -847,7 +862,7 @@ module Doing
|
|
|
847
862
|
note.map!(&:strip)
|
|
848
863
|
note.delete_if(&:ignore?)
|
|
849
864
|
item = items[i]
|
|
850
|
-
old_item = item.
|
|
865
|
+
old_item = item.clone
|
|
851
866
|
item.date = date || items[i].date
|
|
852
867
|
item.title = title
|
|
853
868
|
item.note = note
|
|
@@ -855,7 +870,7 @@ module Doing
|
|
|
855
870
|
Doing.logger.count(:skipped, level: :debug)
|
|
856
871
|
else
|
|
857
872
|
Doing.logger.count(:updated)
|
|
858
|
-
Hooks.trigger :post_entry_updated, self, item
|
|
873
|
+
Hooks.trigger :post_entry_updated, self, item, old_item
|
|
859
874
|
end
|
|
860
875
|
end
|
|
861
876
|
end
|
|
@@ -1045,9 +1060,10 @@ module Doing
|
|
|
1045
1060
|
else
|
|
1046
1061
|
opt[:resume]
|
|
1047
1062
|
end
|
|
1063
|
+
old_item = item.clone
|
|
1048
1064
|
new_entry = reset_item(item, date: date, resume: res)
|
|
1049
1065
|
@content.update_item(item, new_entry)
|
|
1050
|
-
Hooks.trigger :post_entry_updated, self, new_entry
|
|
1066
|
+
Hooks.trigger :post_entry_updated, self, new_entry, old_item
|
|
1051
1067
|
end
|
|
1052
1068
|
write(@doing_file)
|
|
1053
1069
|
|
|
@@ -1062,8 +1078,9 @@ module Doing
|
|
|
1062
1078
|
if opt[:flag]
|
|
1063
1079
|
tag = @config['marker_tag'] || 'flagged'
|
|
1064
1080
|
items.map! do |i|
|
|
1081
|
+
old_item = i.clone
|
|
1065
1082
|
i.tag(tag, date: false, remove: opt[:remove], single: single)
|
|
1066
|
-
Hooks.trigger :post_entry_updated, self, i
|
|
1083
|
+
Hooks.trigger :post_entry_updated, self, i, old_item
|
|
1067
1084
|
end
|
|
1068
1085
|
end
|
|
1069
1086
|
|
|
@@ -1071,9 +1088,10 @@ module Doing
|
|
|
1071
1088
|
tag = 'done'
|
|
1072
1089
|
items.map! do |i|
|
|
1073
1090
|
if i.should_finish?
|
|
1091
|
+
old_item = i.clone
|
|
1074
1092
|
should_date = !opt[:cancel] && i.should_time?
|
|
1075
1093
|
i.tag(tag, date: should_date, remove: opt[:remove], single: single)
|
|
1076
|
-
Hooks.trigger :post_entry_updated, self, i
|
|
1094
|
+
Hooks.trigger :post_entry_updated, self, i, old_item
|
|
1077
1095
|
end
|
|
1078
1096
|
end
|
|
1079
1097
|
end
|
|
@@ -1087,8 +1105,9 @@ module Doing
|
|
|
1087
1105
|
else
|
|
1088
1106
|
logger.count(:added_tags)
|
|
1089
1107
|
logger.write(items.count == 1 ? :info : :debug, 'Tagged:', new_title)
|
|
1108
|
+
old_item = i.clone
|
|
1090
1109
|
i.title = new_title
|
|
1091
|
-
Hooks.trigger :post_entry_updated, self, i
|
|
1110
|
+
Hooks.trigger :post_entry_updated, self, i, old_item
|
|
1092
1111
|
end
|
|
1093
1112
|
end
|
|
1094
1113
|
end
|
|
@@ -1096,17 +1115,19 @@ module Doing
|
|
|
1096
1115
|
if opt[:tag]
|
|
1097
1116
|
tag = opt[:tag]
|
|
1098
1117
|
items.map! do |i|
|
|
1118
|
+
old_item = i.clone
|
|
1099
1119
|
i.tag(tag, date: false, remove: opt[:remove], single: single)
|
|
1100
1120
|
i.expand_date_tags(@config['date_tags'])
|
|
1101
|
-
Hooks.trigger :post_entry_updated, self, i
|
|
1121
|
+
Hooks.trigger :post_entry_updated, self, i, old_item
|
|
1102
1122
|
end
|
|
1103
1123
|
end
|
|
1104
1124
|
|
|
1105
1125
|
if opt[:archive] || opt[:move]
|
|
1106
1126
|
section = opt[:archive] ? 'Archive' : guess_section(opt[:move])
|
|
1107
1127
|
items.map! do |i|
|
|
1128
|
+
old_item = i.clone
|
|
1108
1129
|
i.move_to(section, label: true)
|
|
1109
|
-
Hooks.trigger :post_entry_updated, self, i
|
|
1130
|
+
Hooks.trigger :post_entry_updated, self, i, old_item
|
|
1110
1131
|
end
|
|
1111
1132
|
end
|
|
1112
1133
|
|
|
@@ -1193,6 +1214,7 @@ module Doing
|
|
|
1193
1214
|
opt[:sequential] ||= false
|
|
1194
1215
|
opt[:date] ||= false
|
|
1195
1216
|
opt[:remove] ||= false
|
|
1217
|
+
opt[:update] ||= false
|
|
1196
1218
|
opt[:autotag] ||= false
|
|
1197
1219
|
opt[:back] ||= false
|
|
1198
1220
|
opt[:unfinished] ||= false
|
|
@@ -1228,6 +1250,7 @@ module Doing
|
|
|
1228
1250
|
end
|
|
1229
1251
|
|
|
1230
1252
|
items.each do |item|
|
|
1253
|
+
old_item = item.clone
|
|
1231
1254
|
added = []
|
|
1232
1255
|
removed = []
|
|
1233
1256
|
|
|
@@ -1304,7 +1327,7 @@ module Doing
|
|
|
1304
1327
|
else
|
|
1305
1328
|
old_title = item.title.dup
|
|
1306
1329
|
should_date = opt[:date] && item.should_time?
|
|
1307
|
-
item.title.tag!('done', remove: true) if tag =~ /done/ && !should_date
|
|
1330
|
+
item.title.tag!('done', remove: true) if tag =~ /done/ && (!should_date || opt[:update])
|
|
1308
1331
|
item.title.tag!(tag, value: should_date ? done_date.strftime('%F %R') : nil)
|
|
1309
1332
|
added << tag if old_title != item.title
|
|
1310
1333
|
end
|
|
@@ -1322,7 +1345,7 @@ module Doing
|
|
|
1322
1345
|
end
|
|
1323
1346
|
|
|
1324
1347
|
item.expand_date_tags(@config['date_tags'])
|
|
1325
|
-
Hooks.trigger :post_entry_updated, self, item
|
|
1348
|
+
Hooks.trigger :post_entry_updated, self, item, old_item
|
|
1326
1349
|
end
|
|
1327
1350
|
|
|
1328
1351
|
write(@doing_file)
|
|
@@ -1361,6 +1384,7 @@ module Doing
|
|
|
1361
1384
|
return
|
|
1362
1385
|
end
|
|
1363
1386
|
|
|
1387
|
+
old_item = item.clone
|
|
1364
1388
|
content = ["#{item.date.strftime('%F %R')} | #{item.title.dup}"]
|
|
1365
1389
|
content << item.note.strip_lines.join("\n") unless item.note.empty?
|
|
1366
1390
|
new_item = fork_editor(content.join("\n"))
|
|
@@ -1376,7 +1400,7 @@ module Doing
|
|
|
1376
1400
|
item.title = title
|
|
1377
1401
|
item.note.add(note, replace: true)
|
|
1378
1402
|
logger.info('Edited:', item.title)
|
|
1379
|
-
Hooks.trigger :post_entry_updated, self, item
|
|
1403
|
+
Hooks.trigger :post_entry_updated, self, item, old_item
|
|
1380
1404
|
|
|
1381
1405
|
write(@doing_file)
|
|
1382
1406
|
end
|
|
@@ -1413,6 +1437,7 @@ module Doing
|
|
|
1413
1437
|
found_items = 0
|
|
1414
1438
|
|
|
1415
1439
|
@content.each_with_index do |item, i|
|
|
1440
|
+
old_item = i.clone
|
|
1416
1441
|
next unless item.section == opt[:section] || opt[:section] =~ /all/i
|
|
1417
1442
|
|
|
1418
1443
|
next unless item.title =~ /@#{tag}/
|
|
@@ -1431,7 +1456,7 @@ module Doing
|
|
|
1431
1456
|
logger.count(:completed)
|
|
1432
1457
|
logger.info('Completed:', item.title)
|
|
1433
1458
|
end
|
|
1434
|
-
Hooks.trigger :post_entry_updated, self, item
|
|
1459
|
+
Hooks.trigger :post_entry_updated, self, item, old_item
|
|
1435
1460
|
end
|
|
1436
1461
|
|
|
1437
1462
|
|
|
@@ -1492,7 +1517,7 @@ module Doing
|
|
|
1492
1517
|
|
|
1493
1518
|
unless ((!tags.empty? && !item.tags?(tags, bool)) || (opt[:search] && !item.search(opt[:search].to_s)) || (opt[:before] && item.date >= cutoff))
|
|
1494
1519
|
new_item = @content.delete(item)
|
|
1495
|
-
Hooks.trigger :post_entry_removed, self, item.
|
|
1520
|
+
Hooks.trigger :post_entry_removed, self, item.clone
|
|
1496
1521
|
raise DoingRuntimeError, "Error deleting item: #{item}" if new_item.nil?
|
|
1497
1522
|
|
|
1498
1523
|
new_content.add_section(new_item.section, log: false)
|
|
@@ -1598,6 +1623,7 @@ module Doing
|
|
|
1598
1623
|
## @param opt [Hash] Additional Options
|
|
1599
1624
|
##
|
|
1600
1625
|
def list_section(opt, items: Items.new)
|
|
1626
|
+
logger.benchmark(:list_section, :start)
|
|
1601
1627
|
opt[:config_template] ||= 'default'
|
|
1602
1628
|
|
|
1603
1629
|
tpl_cfg = @config.dig('templates', opt[:config_template])
|
|
@@ -1611,7 +1637,7 @@ module Doing
|
|
|
1611
1637
|
cfg.deep_merge({
|
|
1612
1638
|
'wrap_width' => @config['wrap_width'] || 0,
|
|
1613
1639
|
'date_format' => @config['default_date_format'],
|
|
1614
|
-
'order' => @config['order'] ||
|
|
1640
|
+
'order' => @config['order'] || :asc,
|
|
1615
1641
|
'tags_color' => @config['tags_color'],
|
|
1616
1642
|
'duration' => @config['duration'],
|
|
1617
1643
|
'interval_format' => @config['interval_format']
|
|
@@ -1623,8 +1649,8 @@ module Doing
|
|
|
1623
1649
|
opt[:age] ||= :newest
|
|
1624
1650
|
opt[:age] = opt[:age].normalize_age
|
|
1625
1651
|
opt[:format] ||= cfg['date_format']
|
|
1626
|
-
opt[:order] ||= cfg['order'] ||
|
|
1627
|
-
opt[:tag_order] ||=
|
|
1652
|
+
opt[:order] ||= cfg['order'] || :asc
|
|
1653
|
+
opt[:tag_order] ||= :asc
|
|
1628
1654
|
opt[:tags_color] = cfg['tags_color'] || false if opt[:tags_color].nil?
|
|
1629
1655
|
opt[:template] ||= cfg['template']
|
|
1630
1656
|
|
|
@@ -1650,7 +1676,7 @@ module Doing
|
|
|
1650
1676
|
|
|
1651
1677
|
items = filter_items(items, opt: opt)
|
|
1652
1678
|
|
|
1653
|
-
items.reverse! unless opt[:order]
|
|
1679
|
+
items.reverse! unless opt[:order].normalize_order == :desc
|
|
1654
1680
|
|
|
1655
1681
|
if opt[:delete]
|
|
1656
1682
|
delete_items(items, force: opt[:force])
|
|
@@ -1673,6 +1699,7 @@ module Doing
|
|
|
1673
1699
|
opt[:output] ||= 'template'
|
|
1674
1700
|
opt[:wrap_width] ||= @config['templates']['default']['wrap_width'] || 0
|
|
1675
1701
|
|
|
1702
|
+
logger.benchmark(:list_section, :finish)
|
|
1676
1703
|
output(items, title, is_single, opt)
|
|
1677
1704
|
end
|
|
1678
1705
|
|
|
@@ -1700,7 +1727,7 @@ module Doing
|
|
|
1700
1727
|
destination = guess_section(destination)
|
|
1701
1728
|
|
|
1702
1729
|
if @content.section?(destination) && (@content.section?(section) || archive_all)
|
|
1703
|
-
do_archive(section, destination, { count: count, tags: tags, bool: bool, search: options[:search], label: options[:label], before: options[:before] })
|
|
1730
|
+
do_archive(section, destination, { count: count, tags: tags, bool: bool, search: options[:search], label: options[:label], before: options[:before], after: options[:after], from: options[:from] })
|
|
1704
1731
|
write(doing_file)
|
|
1705
1732
|
else
|
|
1706
1733
|
raise InvalidArgument, 'Either source or destination does not exist'
|
|
@@ -1722,7 +1749,7 @@ module Doing
|
|
|
1722
1749
|
cfg = @config['templates'][opt[:config_template]].deep_merge(@config['templates']['default'], { extend_existing_arrays: true, sort_merged_arrays: true }).deep_merge({
|
|
1723
1750
|
'wrap_width' => @config['wrap_width'] || 0,
|
|
1724
1751
|
'date_format' => @config['default_date_format'],
|
|
1725
|
-
'order' => @config['order'] ||
|
|
1752
|
+
'order' => @config['order'] || :asc,
|
|
1726
1753
|
'tags_color' => @config['tags_color'],
|
|
1727
1754
|
'duration' => @config['duration'],
|
|
1728
1755
|
'interval_format' => @config['interval_format']
|
|
@@ -1741,7 +1768,7 @@ module Doing
|
|
|
1741
1768
|
from: opt[:from],
|
|
1742
1769
|
format: cfg['date_format'],
|
|
1743
1770
|
interval_format: opt[:interval_format],
|
|
1744
|
-
order: cfg['order'] ||
|
|
1771
|
+
order: cfg['order'] || :asc,
|
|
1745
1772
|
output: output,
|
|
1746
1773
|
section: opt[:section],
|
|
1747
1774
|
sort_tags: opt[:sort_tags],
|
|
@@ -1776,7 +1803,7 @@ module Doing
|
|
|
1776
1803
|
list_section({
|
|
1777
1804
|
section: section,
|
|
1778
1805
|
count: 0,
|
|
1779
|
-
order:
|
|
1806
|
+
order: :asc,
|
|
1780
1807
|
date_filter: dates,
|
|
1781
1808
|
times: times,
|
|
1782
1809
|
output: output,
|
|
@@ -1842,7 +1869,7 @@ module Doing
|
|
|
1842
1869
|
cfg = @config['templates'][opt[:config_template]].deep_merge(@config['templates']['default'], { extend_existing_arrays: true, sort_merged_arrays: true }).deep_merge({
|
|
1843
1870
|
'wrap_width' => @config['wrap_width'] || 0,
|
|
1844
1871
|
'date_format' => @config['default_date_format'],
|
|
1845
|
-
'order' => @config['order'] ||
|
|
1872
|
+
'order' => @config['order'] || :asc,
|
|
1846
1873
|
'tags_color' => @config['tags_color'],
|
|
1847
1874
|
'duration' => @config['duration'],
|
|
1848
1875
|
'interval_format' => @config['interval_format']
|
|
@@ -1858,7 +1885,7 @@ module Doing
|
|
|
1858
1885
|
opt[:count] = count
|
|
1859
1886
|
opt[:format] = cfg['date_format']
|
|
1860
1887
|
opt[:template] = opt[:template] || cfg['template']
|
|
1861
|
-
opt[:order] =
|
|
1888
|
+
opt[:order] = :asc
|
|
1862
1889
|
opt[:times] = times
|
|
1863
1890
|
|
|
1864
1891
|
list_section(opt)
|
|
@@ -1875,7 +1902,7 @@ module Doing
|
|
|
1875
1902
|
cfg = @config['templates'][options[:config_template]].deep_merge(@config['templates']['default'], { extend_existing_arrays: true, sort_merged_arrays: true }).deep_merge({
|
|
1876
1903
|
'wrap_width' => @config['wrap_width'] || 0,
|
|
1877
1904
|
'date_format' => @config['default_date_format'],
|
|
1878
|
-
'order' => @config['order'] ||
|
|
1905
|
+
'order' => @config['order'] || :asc,
|
|
1879
1906
|
'tags_color' => @config['tags_color'],
|
|
1880
1907
|
'duration' => @config['duration'],
|
|
1881
1908
|
'interval_format' => @config['interval_format']
|
|
@@ -2022,10 +2049,10 @@ module Doing
|
|
|
2022
2049
|
##
|
|
2023
2050
|
## @param format [String] return format (html,
|
|
2024
2051
|
## json, or text)
|
|
2025
|
-
## @param
|
|
2026
|
-
## @param sort_order [
|
|
2052
|
+
## @param sort_by [Symbol] Sort by :name or :time
|
|
2053
|
+
## @param sort_order [Symbol] The sort order (:asc or :desc)
|
|
2027
2054
|
##
|
|
2028
|
-
def tag_times(format: :text,
|
|
2055
|
+
def tag_times(format: :text, sort_by: :time, sort_order: :asc)
|
|
2029
2056
|
return '' if @timers.empty?
|
|
2030
2057
|
|
|
2031
2058
|
max = @timers.keys.sort_by { |k| k.length }.reverse[0].length + 1
|
|
@@ -2033,13 +2060,13 @@ module Doing
|
|
|
2033
2060
|
total = @timers.delete('All')
|
|
2034
2061
|
|
|
2035
2062
|
tags_data = @timers.delete_if { |_k, v| v == 0 }
|
|
2036
|
-
sorted_tags_data = if
|
|
2063
|
+
sorted_tags_data = if sort_by.normalize_tag_sort == :name
|
|
2037
2064
|
tags_data.sort_by { |k, _v| k }
|
|
2038
2065
|
else
|
|
2039
2066
|
tags_data.sort_by { |_k, v| v }
|
|
2040
2067
|
end
|
|
2041
2068
|
|
|
2042
|
-
sorted_tags_data.reverse! if sort_order
|
|
2069
|
+
sorted_tags_data.reverse! if sort_order.normalize_order == :asc
|
|
2043
2070
|
case format
|
|
2044
2071
|
when :html
|
|
2045
2072
|
|
|
@@ -2189,9 +2216,9 @@ EOS
|
|
|
2189
2216
|
Doing.config_with(ENV['DOING_CONFIG'], { ignore_local: true })
|
|
2190
2217
|
end
|
|
2191
2218
|
|
|
2192
|
-
|
|
2219
|
+
logger.benchmark(:configure, :start)
|
|
2193
2220
|
config = Doing.config
|
|
2194
|
-
|
|
2221
|
+
logger.benchmark(:configure, :finish)
|
|
2195
2222
|
|
|
2196
2223
|
config.settings['backup_dir'] = ENV['DOING_BACKUP_DIR'] if ENV['DOING_BACKUP_DIR']
|
|
2197
2224
|
@config = config.settings
|
|
@@ -2202,7 +2229,7 @@ EOS
|
|
|
2202
2229
|
|
|
2203
2230
|
filename ||= @config['doing_file']
|
|
2204
2231
|
init_doing_file(filename)
|
|
2205
|
-
current_content = @content.
|
|
2232
|
+
current_content = @content.clone
|
|
2206
2233
|
backup_file = Util::Backup.last_backup(filename, count: 1)
|
|
2207
2234
|
raise DoingRuntimeError, 'No undo history to diff' if backup_file.nil?
|
|
2208
2235
|
|
|
@@ -2245,6 +2272,7 @@ EOS
|
|
|
2245
2272
|
## template trigger
|
|
2246
2273
|
##
|
|
2247
2274
|
def output(items, title, is_single, opt)
|
|
2275
|
+
logger.benchmark(:output, :start)
|
|
2248
2276
|
opt ||= {}
|
|
2249
2277
|
out = nil
|
|
2250
2278
|
|
|
@@ -2262,7 +2290,7 @@ EOS
|
|
|
2262
2290
|
end
|
|
2263
2291
|
|
|
2264
2292
|
logger.debug('Output:', "#{items.count} #{items.count == 1 ? 'item' : 'items'} shown")
|
|
2265
|
-
|
|
2293
|
+
logger.benchmark(:output, :finish)
|
|
2266
2294
|
out
|
|
2267
2295
|
end
|
|
2268
2296
|
|
|
@@ -2306,25 +2334,37 @@ EOS
|
|
|
2306
2334
|
section_items = @content.in_section(section)
|
|
2307
2335
|
max = section_items.count - count.to_i
|
|
2308
2336
|
|
|
2337
|
+
opt[:after] = opt[:from][0] if opt[:from]
|
|
2338
|
+
opt[:before] = opt[:from][1] if opt[:from]
|
|
2339
|
+
|
|
2340
|
+
time_rx = /^(\d{1,2}+(:\d{1,2}+)?( *(am|pm))?|midnight|noon)$/
|
|
2341
|
+
|
|
2342
|
+
if opt[:before].is_a?(String) && opt[:before] =~ time_rx
|
|
2343
|
+
opt[:before] = opt[:before].chronify(guess: :end, future: false)
|
|
2344
|
+
end
|
|
2345
|
+
|
|
2346
|
+
if opt[:after].is_a?(String) && opt[:after] =~ time_rx
|
|
2347
|
+
opt[:after] = opt[:after].chronify(guess: :begin, future: false)
|
|
2348
|
+
end
|
|
2349
|
+
|
|
2309
2350
|
counter = 0
|
|
2310
2351
|
|
|
2311
2352
|
@content.map do |item|
|
|
2312
2353
|
break if counter >= max
|
|
2313
|
-
if opt[:before]
|
|
2314
|
-
time_string = opt[:before]
|
|
2315
|
-
cutoff = time_string.chronify(guess: :begin)
|
|
2316
|
-
end
|
|
2317
2354
|
|
|
2318
|
-
if
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2355
|
+
next if item.section.downcase == destination.downcase
|
|
2356
|
+
|
|
2357
|
+
next if item.section.downcase != section.downcase && section != /^all$/i
|
|
2358
|
+
|
|
2359
|
+
next if (opt[:before] && item.date > opt[:before]) || (opt[:after] && item.date < opt[:after])
|
|
2360
|
+
|
|
2361
|
+
next if (!tags.empty? && !item.tags?(tags, bool)) || (opt[:search] && !item.search(opt[:search].to_s))
|
|
2362
|
+
|
|
2363
|
+
counter += 1
|
|
2364
|
+
old_item = item.clone
|
|
2365
|
+
item.move_to(destination, label: label, log: false)
|
|
2366
|
+
Hooks.trigger :post_entry_updated, self, item, old_item
|
|
2367
|
+
item
|
|
2328
2368
|
end
|
|
2329
2369
|
|
|
2330
2370
|
if counter.positive?
|
data/lib/doing.rb
CHANGED
|
@@ -28,10 +28,11 @@ require_relative 'doing/hash'
|
|
|
28
28
|
require_relative 'doing/types'
|
|
29
29
|
require_relative 'doing/colors'
|
|
30
30
|
require_relative 'doing/template_string'
|
|
31
|
-
require_relative 'doing/string'
|
|
31
|
+
require_relative 'doing/string/string'
|
|
32
32
|
require_relative 'doing/time'
|
|
33
|
-
require_relative 'doing/array'
|
|
34
|
-
require_relative 'doing/
|
|
33
|
+
require_relative 'doing/array/array'
|
|
34
|
+
require_relative 'doing/good'
|
|
35
|
+
require_relative 'doing/normalize'
|
|
35
36
|
require_relative 'doing/util'
|
|
36
37
|
require_relative 'doing/util_backup'
|
|
37
38
|
require_relative 'doing/configuration'
|
|
@@ -49,9 +50,7 @@ require_relative 'doing/pager'
|
|
|
49
50
|
require_relative 'doing/completion'
|
|
50
51
|
require_relative 'doing/boolean_term_parser'
|
|
51
52
|
require_relative 'doing/phrase_parser'
|
|
52
|
-
require_relative 'doing/
|
|
53
|
-
require_relative 'doing/numeric_chronify'
|
|
54
|
-
require_relative 'doing/string_chronify'
|
|
53
|
+
require_relative 'doing/chronify/chronify'
|
|
55
54
|
# require 'doing/markdown_document_listener'
|
|
56
55
|
|
|
57
56
|
# Main doing module
|
|
@@ -36,8 +36,7 @@ command :wiki do |c|
|
|
|
36
36
|
c.switch [:only_timed], default_value: false, negatable: false
|
|
37
37
|
|
|
38
38
|
c.action do |global, options, args|
|
|
39
|
-
|
|
40
|
-
tags = wwid.tag_groups([], opt: options)
|
|
39
|
+
tags = @wwid.tag_groups([], opt: options)
|
|
41
40
|
|
|
42
41
|
wiki = Doing::Plugins.plugins.dig(:export, 'wiki', :class)
|
|
43
42
|
|
|
@@ -46,7 +45,7 @@ command :wiki do |c|
|
|
|
46
45
|
|
|
47
46
|
raise RuntimeError, 'Missing plugin "wiki"' unless wiki
|
|
48
47
|
|
|
49
|
-
out = wiki.render(wwid, items, variables: export_options)
|
|
48
|
+
out = wiki.render(@wwid, items, variables: export_options)
|
|
50
49
|
|
|
51
50
|
if out
|
|
52
51
|
FileUtils.mkdir_p('doing_wiki')
|
|
@@ -56,13 +55,13 @@ command :wiki do |c|
|
|
|
56
55
|
end
|
|
57
56
|
end
|
|
58
57
|
|
|
59
|
-
template = if
|
|
60
|
-
IO.read(File.expand_path(
|
|
58
|
+
template = if @settings['export_templates']['wiki_index'] && File.exist?(File.expand_path(@settings['export_templates']['wiki_index']))
|
|
59
|
+
IO.read(File.expand_path(@settings['export_templates']['wiki_index']))
|
|
61
60
|
else
|
|
62
61
|
wiki.template('wiki_index')
|
|
63
62
|
end
|
|
64
|
-
style = if
|
|
65
|
-
IO.read(File.expand_path(
|
|
63
|
+
style = if @settings['export_templates']['wiki_css'] && File.exist?(File.expand_path(@settings['export_templates']['wiki_css']))
|
|
64
|
+
IO.read(File.expand_path(@settings['export_templates']['wiki_css']))
|
|
66
65
|
else
|
|
67
66
|
wiki.template('wiki_css')
|
|
68
67
|
end
|
|
@@ -74,7 +74,7 @@ module Doing
|
|
|
74
74
|
self.template('wiki_css')
|
|
75
75
|
end
|
|
76
76
|
|
|
77
|
-
totals = opt[:totals] ? wwid.tag_times(format: :html,
|
|
77
|
+
totals = opt[:totals] ? wwid.tag_times(format: :html, sort_by: opt[:sort_tags], sort_order: opt[:tag_order]) : ''
|
|
78
78
|
engine = Haml::Engine.new(template)
|
|
79
79
|
Doing.logger.debug('Wiki Export:', "#{items_out.count} items output to #{variables[:page_title]} wiki page")
|
|
80
80
|
@out = engine.render(Object.new,
|