doing 2.1.23 → 2.1.27
Sign up to get free protection for your applications and to get access to all the features.
- 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 +329 -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 +69 -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 +289 -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 +14 -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/completion/fish_completion.rb +2 -1
- 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,
|