doing 2.1.10 → 2.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -0
- data/Dockerfile +9 -0
- data/Dockerfile-2.6 +9 -0
- data/Dockerfile-2.7 +8 -0
- data/Dockerfile-3.0 +8 -0
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/Rakefile +39 -5
- data/bin/doing +2106 -1979
- data/lib/doing/configuration.rb +18 -8
- data/lib/doing/hooks.rb +10 -5
- data/lib/doing/items.rb +16 -1
- data/lib/doing/pager.rb +2 -20
- data/lib/doing/plugins/import/calendar_import.rb +5 -0
- data/lib/doing/plugins/import/doing_import.rb +2 -0
- data/lib/doing/plugins/import/timing_import.rb +5 -0
- data/lib/doing/util_backup.rb +16 -5
- data/lib/doing/version.rb +1 -1
- data/lib/doing/wwid.rb +147 -66
- data/lib/doing.rb +1 -0
- data/lib/examples/plugins/hooks.rb +31 -0
- data/scripts/sort_commands.rb +59 -0
- metadata +7 -2
data/lib/doing/wwid.rb
CHANGED
@@ -114,6 +114,8 @@ module Doing
|
|
114
114
|
filename = @doing_file if filename.nil?
|
115
115
|
return if File.exist?(filename) && File.stat(filename).size.positive?
|
116
116
|
|
117
|
+
FileUtils.mkdir_p(File.dirname(filename)) unless File.directory?(File.dirname(filename))
|
118
|
+
|
117
119
|
File.open(filename, 'w+') do |f|
|
118
120
|
f.puts "#{@config['current_section']}:"
|
119
121
|
end
|
@@ -372,9 +374,13 @@ module Doing
|
|
372
374
|
end
|
373
375
|
end
|
374
376
|
|
377
|
+
Hooks.trigger :pre_entry_add, self, entry
|
378
|
+
|
375
379
|
@content.push(entry)
|
376
380
|
# logger.count(:added, level: :debug)
|
377
381
|
logger.info('New entry:', %(added "#{entry.title}" to #{section}))
|
382
|
+
|
383
|
+
Hooks.trigger :post_entry_added, self, entry.dup
|
378
384
|
end
|
379
385
|
|
380
386
|
##
|
@@ -471,6 +477,7 @@ module Doing
|
|
471
477
|
else
|
472
478
|
item.title.tag!('done')
|
473
479
|
end
|
480
|
+
Hooks.trigger :post_entry_updated, self, item
|
474
481
|
end
|
475
482
|
|
476
483
|
# Remove @done tag
|
@@ -798,6 +805,65 @@ module Doing
|
|
798
805
|
output
|
799
806
|
end
|
800
807
|
|
808
|
+
def delete_items(items, force: false)
|
809
|
+
res = force ? true : Prompt.yn("Delete #{items.size} #{items.size == 1 ? 'item' : 'items'}?", default_response: 'y')
|
810
|
+
if res
|
811
|
+
items.each do |i|
|
812
|
+
deleted = @content.delete_item(i, single: items.count == 1)
|
813
|
+
Hooks.trigger :post_entry_removed, self, deleted
|
814
|
+
end
|
815
|
+
write(@doing_file)
|
816
|
+
end
|
817
|
+
end
|
818
|
+
|
819
|
+
def edit_items(items)
|
820
|
+
editable_items = []
|
821
|
+
|
822
|
+
items.each do |i|
|
823
|
+
editable = "#{i.date.strftime('%F %R')} | #{i.title}"
|
824
|
+
old_note = i.note ? i.note.strip_lines.join("\n") : nil
|
825
|
+
editable += "\n#{old_note}" unless old_note.nil?
|
826
|
+
editable_items << editable
|
827
|
+
end
|
828
|
+
divider = "\n-----------\n"
|
829
|
+
notice =<<~EONOTICE
|
830
|
+
# - You may delete entries, but leave all divider lines (---) in place.
|
831
|
+
# - Start and @done dates replaced with a time string (yesterday 3pm) will
|
832
|
+
# be parsed automatically. Do not delete the pipe (|) between start date
|
833
|
+
# and entry title.
|
834
|
+
EONOTICE
|
835
|
+
input = "#{editable_items.map(&:strip).join(divider)}\n\n#{notice}"
|
836
|
+
|
837
|
+
new_items = fork_editor(input).split(/#{divider}/)
|
838
|
+
|
839
|
+
new_items.each_with_index do |new_item, i|
|
840
|
+
input_lines = new_item.split(/[\n\r]+/).delete_if(&:ignore?)
|
841
|
+
first_line = input_lines[0]&.strip
|
842
|
+
|
843
|
+
if first_line.nil? || first_line =~ /^#{divider.strip}$/ || first_line.strip.empty?
|
844
|
+
deleted = @content.delete_item(items[i], single: new_items.count == 1)
|
845
|
+
Hooks.trigger :post_entry_removed, self, deleted
|
846
|
+
Doing.logger.count(:deleted)
|
847
|
+
else
|
848
|
+
date, title, note = format_input(new_item)
|
849
|
+
|
850
|
+
note.map!(&:strip)
|
851
|
+
note.delete_if(&:ignore?)
|
852
|
+
item = items[i]
|
853
|
+
old_item = item.dup
|
854
|
+
item.date = date || items[i].date
|
855
|
+
item.title = title
|
856
|
+
item.note = note
|
857
|
+
if (item.equal?(old_item))
|
858
|
+
Doing.logger.count(:skipped, level: :debug)
|
859
|
+
else
|
860
|
+
Doing.logger.count(:updated)
|
861
|
+
Hooks.trigger :post_entry_updated, self, item
|
862
|
+
end
|
863
|
+
end
|
864
|
+
end
|
865
|
+
end
|
866
|
+
|
801
867
|
##
|
802
868
|
## Display an interactive menu of entries
|
803
869
|
##
|
@@ -958,7 +1024,7 @@ module Doing
|
|
958
1024
|
|
959
1025
|
item = items[0]
|
960
1026
|
if opt[:resume] && !opt[:reset]
|
961
|
-
repeat_item(item, { editor: opt[:editor] })
|
1027
|
+
repeat_item(item, { editor: opt[:editor] }) # hooked
|
962
1028
|
elsif opt[:reset]
|
963
1029
|
res = Prompt.enter_text('Start date (blank for current time)', default_response: '')
|
964
1030
|
if res =~ /^ *$/
|
@@ -972,7 +1038,9 @@ module Doing
|
|
972
1038
|
else
|
973
1039
|
opt[:resume]
|
974
1040
|
end
|
975
|
-
|
1041
|
+
new_entry = reset_item(item, date: date, resume: res)
|
1042
|
+
@content.update_item(item, new_entry)
|
1043
|
+
Hooks.trigger :post_entry_updated, self, new_entry
|
976
1044
|
end
|
977
1045
|
write(@doing_file)
|
978
1046
|
|
@@ -980,11 +1048,7 @@ module Doing
|
|
980
1048
|
end
|
981
1049
|
|
982
1050
|
if opt[:delete]
|
983
|
-
|
984
|
-
if res
|
985
|
-
items.each { |i| @content.delete_item(i, single: items.count == 1) }
|
986
|
-
write(@doing_file)
|
987
|
-
end
|
1051
|
+
delete_items(items, force: opt[:force]) # hooked
|
988
1052
|
return
|
989
1053
|
end
|
990
1054
|
|
@@ -992,6 +1056,7 @@ module Doing
|
|
992
1056
|
tag = @config['marker_tag'] || 'flagged'
|
993
1057
|
items.map! do |i|
|
994
1058
|
i.tag(tag, date: false, remove: opt[:remove], single: single)
|
1059
|
+
Hooks.trigger :post_entry_updated, self, i
|
995
1060
|
end
|
996
1061
|
end
|
997
1062
|
|
@@ -1001,6 +1066,7 @@ module Doing
|
|
1001
1066
|
if i.should_finish?
|
1002
1067
|
should_date = !opt[:cancel] && i.should_time?
|
1003
1068
|
i.tag(tag, date: should_date, remove: opt[:remove], single: single)
|
1069
|
+
Hooks.trigger :post_entry_updated, self, i
|
1004
1070
|
end
|
1005
1071
|
end
|
1006
1072
|
end
|
@@ -1009,61 +1075,22 @@ module Doing
|
|
1009
1075
|
tag = opt[:tag]
|
1010
1076
|
items.map! do |i|
|
1011
1077
|
i.tag(tag, date: false, remove: opt[:remove], single: single)
|
1078
|
+
Hooks.trigger :post_entry_updated, self, i
|
1012
1079
|
end
|
1013
1080
|
end
|
1014
1081
|
|
1015
1082
|
if opt[:archive] || opt[:move]
|
1016
1083
|
section = opt[:archive] ? 'Archive' : guess_section(opt[:move])
|
1017
|
-
items.map!
|
1084
|
+
items.map! do |i|
|
1085
|
+
i.move_to(section, label: true)
|
1086
|
+
Hooks.trigger :post_entry_updated, self, i
|
1087
|
+
end
|
1018
1088
|
end
|
1019
1089
|
|
1020
1090
|
write(@doing_file)
|
1021
1091
|
|
1022
1092
|
if opt[:editor]
|
1023
|
-
|
1024
|
-
editable_items = []
|
1025
|
-
|
1026
|
-
items.each do |i|
|
1027
|
-
editable = "#{i.date.strftime('%F %R')} | #{i.title}"
|
1028
|
-
old_note = i.note ? i.note.strip_lines.join("\n") : nil
|
1029
|
-
editable += "\n#{old_note}" unless old_note.nil?
|
1030
|
-
editable_items << editable
|
1031
|
-
end
|
1032
|
-
divider = "\n-----------\n"
|
1033
|
-
notice =<<~EONOTICE
|
1034
|
-
# - You may delete entries, but leave all divider lines (---) in place.
|
1035
|
-
# - Start and @done dates replaced with a time string (yesterday 3pm) will
|
1036
|
-
# be parsed automatically. Do not delete the pipe (|) between start date
|
1037
|
-
# and entry title.
|
1038
|
-
EONOTICE
|
1039
|
-
input = "#{editable_items.map(&:strip).join(divider)}\n\n#{notice}"
|
1040
|
-
|
1041
|
-
new_items = fork_editor(input).split(/#{divider}/)
|
1042
|
-
|
1043
|
-
new_items.each_with_index do |new_item, i|
|
1044
|
-
input_lines = new_item.split(/[\n\r]+/).delete_if(&:ignore?)
|
1045
|
-
first_line = input_lines[0]&.strip
|
1046
|
-
|
1047
|
-
if first_line.nil? || first_line =~ /^#{divider.strip}$/ || first_line.strip.empty?
|
1048
|
-
@content.delete_item(items[i], single: new_items.count == 1)
|
1049
|
-
Doing.logger.count(:deleted)
|
1050
|
-
else
|
1051
|
-
date, title, note = format_input(new_item)
|
1052
|
-
|
1053
|
-
note.map!(&:strip)
|
1054
|
-
note.delete_if(&:ignore?)
|
1055
|
-
item = items[i]
|
1056
|
-
old_item = item.dup
|
1057
|
-
item.date = date || items[i].date
|
1058
|
-
item.title = title
|
1059
|
-
item.note = note
|
1060
|
-
if (item.equal?(old_item))
|
1061
|
-
Doing.logger.count(:skipped, level: :debug)
|
1062
|
-
else
|
1063
|
-
Doing.logger.count(:updated)
|
1064
|
-
end
|
1065
|
-
end
|
1066
|
-
end
|
1093
|
+
edit_items(items) # hooked
|
1067
1094
|
|
1068
1095
|
write(@doing_file)
|
1069
1096
|
end
|
@@ -1088,7 +1115,7 @@ module Doing
|
|
1088
1115
|
options[:template] = opt[:template] || nil
|
1089
1116
|
end
|
1090
1117
|
|
1091
|
-
output = list_section(options)
|
1118
|
+
output = list_section(options) # hooked
|
1092
1119
|
|
1093
1120
|
if opt[:save_to]
|
1094
1121
|
file = File.expand_path(opt[:save_to])
|
@@ -1116,7 +1143,7 @@ module Doing
|
|
1116
1143
|
##
|
1117
1144
|
## @see #filter_items
|
1118
1145
|
##
|
1119
|
-
def tag_last(opt)
|
1146
|
+
def tag_last(opt) # hooked
|
1120
1147
|
opt ||= {}
|
1121
1148
|
opt[:count] ||= 1
|
1122
1149
|
opt[:archive] ||= false
|
@@ -1227,6 +1254,8 @@ module Doing
|
|
1227
1254
|
elsif opt[:archive] && opt[:count].zero?
|
1228
1255
|
logger.warn('Skipped:', 'Archiving is skipped when operating on all entries')
|
1229
1256
|
end
|
1257
|
+
|
1258
|
+
Hooks.trigger :post_entry_updated, self, item
|
1230
1259
|
end
|
1231
1260
|
|
1232
1261
|
write(@doing_file)
|
@@ -1280,6 +1309,7 @@ module Doing
|
|
1280
1309
|
item.title = title
|
1281
1310
|
item.note.add(note, replace: true)
|
1282
1311
|
logger.info('Edited:', item.title)
|
1312
|
+
Hooks.trigger :post_entry_updated, self, item.dup
|
1283
1313
|
|
1284
1314
|
write(@doing_file)
|
1285
1315
|
end
|
@@ -1334,8 +1364,10 @@ module Doing
|
|
1334
1364
|
logger.count(:completed)
|
1335
1365
|
logger.info('Completed:', item.title)
|
1336
1366
|
end
|
1367
|
+
Hooks.trigger :post_entry_updated, self, item
|
1337
1368
|
end
|
1338
1369
|
|
1370
|
+
|
1339
1371
|
logger.debug('Skipped:', "No active @#{tag} tasks found.") if found_items.zero?
|
1340
1372
|
|
1341
1373
|
if opt[:new_item]
|
@@ -1393,6 +1425,7 @@ module Doing
|
|
1393
1425
|
|
1394
1426
|
unless ((!tags.empty? && !item.tags?(tags, bool)) || (opt[:search] && !item.search(opt[:search].to_s)) || (opt[:before] && item.date >= cutoff))
|
1395
1427
|
new_item = @content.delete(item)
|
1428
|
+
Hooks.trigger :post_entry_removed, self, item.dup
|
1396
1429
|
raise DoingRuntimeError, "Error deleting item: #{item}" if new_item.nil?
|
1397
1430
|
|
1398
1431
|
new_content.add_section(new_item.section, log: false)
|
@@ -1503,7 +1536,7 @@ module Doing
|
|
1503
1536
|
tpl_cfg = @config.dig('templates', opt[:config_template])
|
1504
1537
|
|
1505
1538
|
cfg = if opt[:view_template]
|
1506
|
-
@config.dig('views', opt[:view_template]).deep_merge(tpl_cfg)
|
1539
|
+
@config.dig('views', opt[:view_template]).deep_merge(tpl_cfg, { extend_existing_arrays: true, sort_merged_arrays: true })
|
1507
1540
|
else
|
1508
1541
|
tpl_cfg
|
1509
1542
|
end
|
@@ -1515,7 +1548,7 @@ module Doing
|
|
1515
1548
|
'tags_color' => @config['tags_color'],
|
1516
1549
|
'duration' => @config['duration'],
|
1517
1550
|
'interval_format' => @config['interval_format']
|
1518
|
-
})
|
1551
|
+
}, { extend_existing_arrays: true, sort_merged_arrays: true })
|
1519
1552
|
opt[:duration] ||= cfg['duration'] || false
|
1520
1553
|
opt[:interval_format] ||= cfg['interval_format'] || 'text'
|
1521
1554
|
opt[:count] ||= 0
|
@@ -1551,7 +1584,13 @@ module Doing
|
|
1551
1584
|
|
1552
1585
|
items.reverse! unless opt[:order] =~ /^d/i
|
1553
1586
|
|
1554
|
-
if opt[:
|
1587
|
+
if opt[:delete]
|
1588
|
+
delete_items(items, force: opt[:force])
|
1589
|
+
return
|
1590
|
+
elsif opt[:editor]
|
1591
|
+
edit_items(items)
|
1592
|
+
return
|
1593
|
+
elsif opt[:interactive]
|
1555
1594
|
opt[:menu] = !opt[:force]
|
1556
1595
|
opt[:query] = '' # opt[:search]
|
1557
1596
|
opt[:multiple] = true
|
@@ -1611,14 +1650,14 @@ module Doing
|
|
1611
1650
|
opt[:totals] ||= false
|
1612
1651
|
opt[:sort_tags] ||= false
|
1613
1652
|
|
1614
|
-
cfg = @config['templates']['today'].deep_merge(@config['templates']['default']).deep_merge({
|
1653
|
+
cfg = @config['templates']['today'].deep_merge(@config['templates']['default'], { extend_existing_arrays: true, sort_merged_arrays: true }).deep_merge({
|
1615
1654
|
'wrap_width' => @config['wrap_width'] || 0,
|
1616
1655
|
'date_format' => @config['default_date_format'],
|
1617
1656
|
'order' => @config['order'] || 'asc',
|
1618
1657
|
'tags_color' => @config['tags_color'],
|
1619
1658
|
'duration' => @config['duration'],
|
1620
1659
|
'interval_format' => @config['interval_format']
|
1621
|
-
})
|
1660
|
+
}, { extend_existing_arrays: true, sort_merged_arrays: true })
|
1622
1661
|
|
1623
1662
|
opt[:duration] ||= cfg['duration'] || false
|
1624
1663
|
opt[:interval_format] ||= cfg['interval_format'] || 'text'
|
@@ -1727,14 +1766,14 @@ module Doing
|
|
1727
1766
|
opt[:totals] ||= false
|
1728
1767
|
opt[:sort_tags] ||= false
|
1729
1768
|
|
1730
|
-
cfg = @config['templates']['recent'].deep_merge(@config['templates']['default']).deep_merge({
|
1769
|
+
cfg = @config['templates']['recent'].deep_merge(@config['templates']['default'], { extend_existing_arrays: true, sort_merged_arrays: true }).deep_merge({
|
1731
1770
|
'wrap_width' => @config['wrap_width'] || 0,
|
1732
1771
|
'date_format' => @config['default_date_format'],
|
1733
1772
|
'order' => @config['order'] || 'asc',
|
1734
1773
|
'tags_color' => @config['tags_color'],
|
1735
1774
|
'duration' => @config['duration'],
|
1736
1775
|
'interval_format' => @config['interval_format']
|
1737
|
-
})
|
1776
|
+
}, { extend_existing_arrays: true, sort_merged_arrays: true })
|
1738
1777
|
opt[:duration] ||= cfg['duration'] || false
|
1739
1778
|
opt[:interval_format] ||= cfg['interval_format'] || 'text'
|
1740
1779
|
|
@@ -1761,14 +1800,14 @@ module Doing
|
|
1761
1800
|
##
|
1762
1801
|
def last(times: true, section: nil, options: {})
|
1763
1802
|
section = section.nil? || section =~ /all/i ? 'All' : guess_section(section)
|
1764
|
-
cfg = @config['templates']['last'].deep_merge(@config['templates']['default']).deep_merge({
|
1803
|
+
cfg = @config['templates']['last'].deep_merge(@config['templates']['default'], { extend_existing_arrays: true, sort_merged_arrays: true }).deep_merge({
|
1765
1804
|
'wrap_width' => @config['wrap_width'] || 0,
|
1766
1805
|
'date_format' => @config['default_date_format'],
|
1767
1806
|
'order' => @config['order'] || 'asc',
|
1768
1807
|
'tags_color' => @config['tags_color'],
|
1769
1808
|
'duration' => @config['duration'],
|
1770
1809
|
'interval_format' => @config['interval_format']
|
1771
|
-
})
|
1810
|
+
}, { extend_existing_arrays: true, sort_merged_arrays: true })
|
1772
1811
|
options[:duration] ||= cfg['duration'] || false
|
1773
1812
|
options[:interval_format] ||= cfg['interval_format'] || 'text'
|
1774
1813
|
|
@@ -1783,7 +1822,8 @@ module Doing
|
|
1783
1822
|
interval_format: options[:interval_format],
|
1784
1823
|
case: options[:case],
|
1785
1824
|
not: options[:negate],
|
1786
|
-
config_template: 'last'
|
1825
|
+
config_template: 'last',
|
1826
|
+
delete: options[:delete]
|
1787
1827
|
}
|
1788
1828
|
|
1789
1829
|
if options[:tag]
|
@@ -1832,6 +1872,7 @@ module Doing
|
|
1832
1872
|
|
1833
1873
|
@config['autotag']['synonyms'].each do |tag, v|
|
1834
1874
|
v.each do |word|
|
1875
|
+
word = word.wildcard_to_rx
|
1835
1876
|
next unless text =~ /\b#{word}\b/i
|
1836
1877
|
|
1837
1878
|
unless current_tags.include?(tag) || tagged[:whitelisted].include?(tag)
|
@@ -1845,7 +1886,12 @@ module Doing
|
|
1845
1886
|
@config['autotag']['transform'].each do |tag|
|
1846
1887
|
next unless tag =~ /\S+:\S+/
|
1847
1888
|
|
1848
|
-
|
1889
|
+
if tag =~ /::/
|
1890
|
+
rx, r = tag.split(/::/)
|
1891
|
+
else
|
1892
|
+
rx, r = tag.split(/:/)
|
1893
|
+
end
|
1894
|
+
|
1849
1895
|
flag_rx = %r{/([r]+)$}
|
1850
1896
|
if r =~ flag_rx
|
1851
1897
|
flags = r.match(flag_rx)[1].split(//)
|
@@ -2087,6 +2133,36 @@ EOS
|
|
2087
2133
|
end
|
2088
2134
|
end
|
2089
2135
|
|
2136
|
+
def configure(filename = nil)
|
2137
|
+
if filename
|
2138
|
+
Doing.config_with(filename, { ignore_local: true })
|
2139
|
+
elsif ENV['DOING_CONFIG']
|
2140
|
+
Doing.config_with(ENV['DOING_CONFIG'], { ignore_local: true })
|
2141
|
+
end
|
2142
|
+
|
2143
|
+
Doing.logger.benchmark(:configure, :start)
|
2144
|
+
config = Doing.config
|
2145
|
+
Doing.logger.benchmark(:configure, :finish)
|
2146
|
+
|
2147
|
+
config.settings['backup_dir'] = ENV['DOING_BACKUP_DIR'] if ENV['DOING_BACKUP_DIR']
|
2148
|
+
@config = config.settings
|
2149
|
+
end
|
2150
|
+
|
2151
|
+
def get_diff(filename = nil)
|
2152
|
+
configure if @config.nil?
|
2153
|
+
|
2154
|
+
filename ||= @config['doing_file']
|
2155
|
+
init_doing_file(filename)
|
2156
|
+
current_content = @content.dup
|
2157
|
+
backup_file = Util::Backup.last_backup(filename, count: 1)
|
2158
|
+
raise DoingRuntimeError, 'No undo history to diff' if backup_file.nil?
|
2159
|
+
|
2160
|
+
backup = WWID.new
|
2161
|
+
backup.config = @config
|
2162
|
+
backup.init_doing_file(backup_file)
|
2163
|
+
current_content.diff(backup.content)
|
2164
|
+
end
|
2165
|
+
|
2090
2166
|
private
|
2091
2167
|
|
2092
2168
|
##
|
@@ -2127,6 +2203,8 @@ EOS
|
|
2127
2203
|
|
2128
2204
|
export_options = { page_title: title, is_single: is_single, options: opt }
|
2129
2205
|
|
2206
|
+
Hooks.trigger :pre_export, self, opt[:output], items
|
2207
|
+
|
2130
2208
|
Plugins.plugins[:export].each do |_, options|
|
2131
2209
|
next unless opt[:output] =~ /^(#{options[:trigger].normalize_trigger})$/i
|
2132
2210
|
|
@@ -2176,10 +2254,11 @@ EOS
|
|
2176
2254
|
|
2177
2255
|
section_items = @content.in_section(section)
|
2178
2256
|
max = section_items.count - count.to_i
|
2257
|
+
moved_items = []
|
2179
2258
|
|
2180
2259
|
counter = 0
|
2181
2260
|
|
2182
|
-
@content.map
|
2261
|
+
@content.map do |item|
|
2183
2262
|
break if counter >= max
|
2184
2263
|
if opt[:before]
|
2185
2264
|
time_string = opt[:before]
|
@@ -2193,6 +2272,8 @@ EOS
|
|
2193
2272
|
else
|
2194
2273
|
counter += 1
|
2195
2274
|
item.move_to(destination, label: label, log: false)
|
2275
|
+
Hooks.trigger :post_entry_updated, self, item.dup
|
2276
|
+
item
|
2196
2277
|
end
|
2197
2278
|
end
|
2198
2279
|
|
data/lib/doing.rb
CHANGED
@@ -18,5 +18,36 @@ module Doing
|
|
18
18
|
Hooks.register :post_write do |filename|
|
19
19
|
res = `/bin/bash /Users/ttscoff/scripts/after_doing.sh`.strip
|
20
20
|
Doing.logger.debug('Hooks:', res) unless res =~ /^\.\.\.$/
|
21
|
+
|
22
|
+
wwid = WWID.new
|
23
|
+
wwid.configure
|
24
|
+
if filename == wwid.config['doing_file']
|
25
|
+
diff = wwid.get_diff(filename)
|
26
|
+
puts diff
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Hooks.register :post_entry_added do |wwid, entry|
|
31
|
+
if wwid.config.key?('day_one_trigger') && entry.tags?(wwid.config['day_one_trigger'], :and)
|
32
|
+
|
33
|
+
logger.info('New entry:', 'Adding to Day One')
|
34
|
+
add_to_day_one(entry, wwid.config)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
## Add the entry to Day One using the CLI
|
40
|
+
##
|
41
|
+
## @param entry The entry to add
|
42
|
+
##
|
43
|
+
def self.add_to_day_one(entry, config)
|
44
|
+
dayone = TTY::Which.which('dayone2')
|
45
|
+
flagged = entry.tags?('flagged') ? ' -s' : ''
|
46
|
+
tags = entry.tags.map { |t| Shellwords.escape(t) }.join(' ')
|
47
|
+
tags = tags.length.positive? ? " -t #{tags}" : ''
|
48
|
+
date = " -d '#{entry.date.strftime('%Y-%m-%d %H:%M:%S')}'"
|
49
|
+
title = entry.title.tag(config['day_one_trigger'], remove: true)
|
50
|
+
title += "\n#{entry.note}" unless entry.note.empty?
|
51
|
+
`echo #{Shellwords.escape(title)} | #{dayone} new#{flagged}#{date}#{tags}`
|
21
52
|
end
|
22
53
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'awesome_print'
|
3
|
+
|
4
|
+
input = STDIN.read.force_encoding('utf-8')
|
5
|
+
|
6
|
+
commands = input.split(/^# @@/).delete_if(&:empty?).sort
|
7
|
+
# commands.each do |cmd|
|
8
|
+
# puts cmd.split(/^(\w+)(.*)$/m)[1]
|
9
|
+
# end
|
10
|
+
indexes = %w[
|
11
|
+
again
|
12
|
+
cancel
|
13
|
+
done
|
14
|
+
finish
|
15
|
+
later
|
16
|
+
mark
|
17
|
+
meanwhile
|
18
|
+
note
|
19
|
+
now
|
20
|
+
reset
|
21
|
+
select
|
22
|
+
tag
|
23
|
+
choose
|
24
|
+
grep
|
25
|
+
last
|
26
|
+
recent
|
27
|
+
show
|
28
|
+
tags
|
29
|
+
today
|
30
|
+
view
|
31
|
+
yesterday
|
32
|
+
open
|
33
|
+
config
|
34
|
+
archive
|
35
|
+
import
|
36
|
+
rotate
|
37
|
+
colors
|
38
|
+
completion
|
39
|
+
plugins
|
40
|
+
sections
|
41
|
+
template
|
42
|
+
views
|
43
|
+
undo
|
44
|
+
redo
|
45
|
+
add_section
|
46
|
+
tag_dir
|
47
|
+
changelog
|
48
|
+
]
|
49
|
+
|
50
|
+
result = Array.new(indexes.count)
|
51
|
+
|
52
|
+
commands.each do |cmd|
|
53
|
+
key = cmd.match(/^(\w+)/)[1]
|
54
|
+
idx = indexes.index(key)
|
55
|
+
result[idx] = "#@@#{cmd}"
|
56
|
+
# puts commands.join('# @@')
|
57
|
+
end
|
58
|
+
|
59
|
+
puts result.join('')
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: doing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Terpstra
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: safe_yaml
|
@@ -405,6 +405,10 @@ files:
|
|
405
405
|
- AUTHORS
|
406
406
|
- CHANGELOG.md
|
407
407
|
- COMMANDS.md
|
408
|
+
- Dockerfile
|
409
|
+
- Dockerfile-2.6
|
410
|
+
- Dockerfile-2.7
|
411
|
+
- Dockerfile-3.0
|
408
412
|
- Gemfile
|
409
413
|
- Gemfile.lock
|
410
414
|
- LICENSE
|
@@ -642,6 +646,7 @@ files:
|
|
642
646
|
- scripts/generate_bash_completions.rb
|
643
647
|
- scripts/generate_fish_completions.rb
|
644
648
|
- scripts/generate_zsh_completions.rb
|
649
|
+
- scripts/sort_commands.rb
|
645
650
|
- yard_templates/default/method_details/setup.rb
|
646
651
|
homepage: http://brettterpstra.com/project/doing/
|
647
652
|
licenses:
|