doing 2.0.13 → 2.0.18
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/bin/doing +14 -6
- data/doing.rdoc +1 -1
- data/lib/doing/plugins/export/template_export.rb +17 -9
- data/lib/doing/string.rb +22 -9
- data/lib/doing/version.rb +1 -1
- data/lib/doing/wwid.rb +42 -14
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cbd007c83df322397ff7da7025dfbc0e31fd0b54b3247bfffb2e7a61134366a5
|
4
|
+
data.tar.gz: 78e741e12e3f28771d68bc7028caf2ed03edb677be1cfe8f975f32406d3d4f01
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a7262555d07ecea5e0e504df1edaacd48654156a50dff44f1d5ee365c04b6c5ae5f4785d9a97f7b6363c450d8184f186aff21ac47653684494e5aec3d1e5f8a
|
7
|
+
data.tar.gz: 1b2e38445ffbe3a6a9687bdd8607f5b41591a4370e4ac68f4036155baceac97e98a50c58cb31e1948f6bdbfd6419fa419e9e1db75170e339227e09361f0b601b
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
### 2.0.18
|
2
|
+
|
3
|
+
#### FIXED
|
4
|
+
|
5
|
+
- Escape codes being included in doing file
|
6
|
+
|
7
|
+
### 2.0.17
|
8
|
+
|
9
|
+
#### IMPROVED
|
10
|
+
|
11
|
+
- Improvements to %title formatting and wrapping
|
12
|
+
|
13
|
+
### 2.0.16
|
14
|
+
|
15
|
+
- Test release to validate git flow automation
|
16
|
+
|
1
17
|
### 2.0.13
|
2
18
|
|
3
19
|
#### FIXED
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -6,7 +6,7 @@ _If you're one of the rare people like me who find this useful, feel free to [bu
|
|
6
6
|
|
7
7
|
<!--README-->
|
8
8
|
|
9
|
-
The current version of `doing` is <!--VER-->2.0.
|
9
|
+
The current version of `doing` is <!--VER-->2.0.17<!--END VER-->.
|
10
10
|
|
11
11
|
Find all of the documentation in the [doing wiki](https://github.com/ttscoff/doing/wiki).
|
12
12
|
|
data/bin/doing
CHANGED
@@ -1582,7 +1582,12 @@ command :show do |c|
|
|
1582
1582
|
|
1583
1583
|
options[:times] = true if options[:totals]
|
1584
1584
|
|
1585
|
-
|
1585
|
+
template = settings['templates']['default'].deep_merge({
|
1586
|
+
'wrap_width' => settings['wrap_width'] || 0,
|
1587
|
+
'date_format' => settings['default_date_format'],
|
1588
|
+
'order' => settings['order'] || 'asc',
|
1589
|
+
'tags_color' => settings['tags_color']
|
1590
|
+
})
|
1586
1591
|
|
1587
1592
|
options[:case] = options[:case].normalize_case
|
1588
1593
|
|
@@ -1603,7 +1608,7 @@ command :show do |c|
|
|
1603
1608
|
opt[:tag] = nil
|
1604
1609
|
opt[:tag_filter] = tag_filter
|
1605
1610
|
opt[:tag_order] = options[:tag_order].normalize_order
|
1606
|
-
opt[:tags_color] = tags_color
|
1611
|
+
opt[:tags_color] = template['tags_color']
|
1607
1612
|
|
1608
1613
|
Doing::Pager.page wwid.list_section(opt)
|
1609
1614
|
end
|
@@ -1674,7 +1679,8 @@ command %i[grep search] do |c|
|
|
1674
1679
|
options[:fuzzy] = false
|
1675
1680
|
raise DoingRuntimeError, %(Invalid output type "#{options[:output]}") if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
|
1676
1681
|
|
1677
|
-
|
1682
|
+
template = settings['templates']['default'].deep_merge(settings)
|
1683
|
+
tags_color = template.key?('tags_color') ? template['tags_color'] : nil
|
1678
1684
|
|
1679
1685
|
section = wwid.guess_section(options[:section]) if options[:section]
|
1680
1686
|
|
@@ -1740,7 +1746,9 @@ command :recent do |c|
|
|
1740
1746
|
|
1741
1747
|
options[:t] = true if options[:totals]
|
1742
1748
|
options[:sort_tags] = options[:tag_sort] =~ /^n/i
|
1743
|
-
|
1749
|
+
|
1750
|
+
template = settings['templates']['recent'].deep_merge(settings['templates']['default'])
|
1751
|
+
tags_color = template.key?('tags_color') ? template['tags_color'] : nil
|
1744
1752
|
|
1745
1753
|
opts = {
|
1746
1754
|
sort_tags: options[:sort_tags],
|
@@ -1801,8 +1809,7 @@ command :today do |c|
|
|
1801
1809
|
before: options[:before],
|
1802
1810
|
section: options[:section],
|
1803
1811
|
sort_tags: options[:sort_tags],
|
1804
|
-
totals: options[:totals]
|
1805
|
-
order: settings.dig('templates', 'today', 'order')
|
1812
|
+
totals: options[:totals]
|
1806
1813
|
}
|
1807
1814
|
Doing::Pager.page wwid.today(options[:times], options[:output], opt).chomp
|
1808
1815
|
end
|
@@ -2278,6 +2285,7 @@ command :view do |c|
|
|
2278
2285
|
|
2279
2286
|
template = view.key?('template') ? view['template'] : nil
|
2280
2287
|
date_format = view.key?('date_format') ? view['date_format'] : nil
|
2288
|
+
|
2281
2289
|
tags_color = view.key?('tags_color') ? view['tags_color'] : nil
|
2282
2290
|
tag_filter = false
|
2283
2291
|
if options[:tag]
|
data/doing.rdoc
CHANGED
@@ -5,7 +5,7 @@ record of what you've been doing, complete with tag-based time tracking. The
|
|
5
5
|
command line tool allows you to add entries, annotate with tags and notes, and
|
6
6
|
view your entries with myriad options, with a focus on a "natural" language syntax.
|
7
7
|
|
8
|
-
v2.0.
|
8
|
+
v2.0.18
|
9
9
|
|
10
10
|
=== Global Options
|
11
11
|
=== --config_file arg
|
@@ -42,6 +42,7 @@ module Doing
|
|
42
42
|
else
|
43
43
|
note = []
|
44
44
|
end
|
45
|
+
|
45
46
|
output = opt[:template].dup
|
46
47
|
|
47
48
|
output.gsub!(/%[a-z]+/) do |m|
|
@@ -69,22 +70,28 @@ module Doing
|
|
69
70
|
|
70
71
|
output.sub!(/%section/, item.section) if item.section
|
71
72
|
|
72
|
-
|
73
|
-
output.
|
73
|
+
title_rx = /(?mi)%(?<width>-?\d+)?(?:(?<ichar>[ _t])(?<icount>\d+))?(?<prefix>.[ _t]?)?title(?<after>.*?)$/
|
74
|
+
title_color = Doing::Color.reset + output.match(/(?mi)^(.*?)(%.*?title)/)[1].last_color
|
75
|
+
|
76
|
+
title_offset = Doing::Color.uncolor(output).match(title_rx).begin(0)
|
77
|
+
|
78
|
+
output.sub!(title_rx) do
|
74
79
|
m = Regexp.last_match
|
75
|
-
|
80
|
+
|
81
|
+
after = m['after']
|
82
|
+
pad = m['width'].to_i
|
76
83
|
indent = ''
|
77
|
-
if m[
|
78
|
-
char = m[
|
79
|
-
indent = char * m[
|
84
|
+
if m['ichar']
|
85
|
+
char = m['ichar'] =~ /t/ ? "\t" : ' '
|
86
|
+
indent = char * m['icount'].to_i
|
80
87
|
end
|
81
|
-
|
88
|
+
prefix = m['prefix']
|
82
89
|
if opt[:wrap_width]&.positive? || pad.positive?
|
83
90
|
width = pad.positive? ? pad : opt[:wrap_width]
|
84
|
-
item.title.wrap(width, pad: pad, indent: indent, offset: title_offset, prefix:
|
91
|
+
item.title.wrap(width, pad: pad, indent: indent, offset: title_offset, prefix: prefix, color: title_color, after: after, reset: reset)
|
85
92
|
# flag + item.title.gsub(/(.{#{opt[:wrap_width]}})(?=\s+|\Z)/, "\\1\n ").sub(/\s*$/, '') + reset
|
86
93
|
else
|
87
|
-
format("%s%#{pad}s%s
|
94
|
+
format("%s%#{pad}s%s", prefix, item.title.sub(/\s*$/, ''), after)
|
88
95
|
end
|
89
96
|
end
|
90
97
|
|
@@ -129,6 +136,7 @@ module Doing
|
|
129
136
|
|
130
137
|
out += "#{output}\n"
|
131
138
|
end
|
139
|
+
|
132
140
|
# Doing.logger.debug('Template Export:', "#{items.count} items output to template #{opt[:template]}")
|
133
141
|
out += wwid.tag_times(format: wwid.config['timer_format'].to_sym, sort_by_name: opt[:sort_tags], sort_order: opt[:tag_order]) if opt[:totals]
|
134
142
|
out
|
data/lib/doing/string.rb
CHANGED
@@ -77,13 +77,15 @@ module Doing
|
|
77
77
|
##
|
78
78
|
def highlight_tags(color = 'yellow')
|
79
79
|
escapes = scan(/(\e\[[\d;]+m)[^\e]+@/)
|
80
|
-
|
80
|
+
color = color.split(' ') unless color.is_a?(Array)
|
81
|
+
tag_color = ''
|
82
|
+
color.each { |c| tag_color += Doing::Color.send(c) }
|
81
83
|
last_color = if !escapes.empty?
|
82
84
|
escapes[-1][0]
|
83
85
|
else
|
84
86
|
Doing::Color.default
|
85
87
|
end
|
86
|
-
gsub(/(\s|m)(@[^ ("']+)/, "\\1#{tag_color}\\2#{last_color}")
|
88
|
+
gsub(/(\s|m)(@[^ ("']+)/, "\\1#{tag_color}\\2#{Doing::Color.reset}#{last_color}")
|
87
89
|
end
|
88
90
|
|
89
91
|
##
|
@@ -159,19 +161,21 @@ module Doing
|
|
159
161
|
## @param offset [Integer] (Optional) The width to pad each subsequent line
|
160
162
|
## @param prefix [String] (Optional) A prefix to add to each line
|
161
163
|
##
|
162
|
-
def wrap(len, pad: 0, indent: ' ', offset: 0, prefix: '', after: '', reset: '')
|
164
|
+
def wrap(len, pad: 0, indent: ' ', offset: 0, prefix: '', color: '', after: '', reset: '')
|
165
|
+
last_color = color.empty? ? '' : after.last_color
|
163
166
|
note_rx = /(?i-m)(%(?:[io]d|(?:\^[\s\S])?(?:(?:[ _t]|[^a-z0-9])?\d+)?(?:[\s\S][ _t]?)?)?note)/
|
164
|
-
|
167
|
+
# Don't break inside of tag values
|
168
|
+
str = gsub(/@\S+\(.*?\)/) { |tag| tag.gsub(/\s/, '%%%%') }
|
165
169
|
words = str.split(/ /).map { |word| word.gsub(/%%%%/, ' ') }
|
166
170
|
out = []
|
167
171
|
line = []
|
168
172
|
words.each do |word|
|
169
|
-
if line.join(' ').length + word.length + 1 > len
|
173
|
+
if line.join(' ').uncolor.length + word.uncolor.length + 1 > len
|
170
174
|
out.push(line.join(' '))
|
171
175
|
line.clear
|
172
176
|
end
|
173
177
|
|
174
|
-
line << word
|
178
|
+
line << word.uncolor
|
175
179
|
end
|
176
180
|
out.push(line.join(' '))
|
177
181
|
note = ''
|
@@ -180,10 +184,11 @@ module Doing
|
|
180
184
|
''
|
181
185
|
end
|
182
186
|
|
183
|
-
out[0] = format("%-#{pad}s%s", out[0], after)
|
184
|
-
|
187
|
+
out[0] = format("%-#{pad}s%s%s", out[0], last_color, after)
|
188
|
+
|
189
|
+
left_pad = ' ' * offset
|
185
190
|
left_pad += indent
|
186
|
-
out.map { |l| "#{left_pad}#{
|
191
|
+
out.map { |l| "#{left_pad}#{color}#{l}#{last_color}" }.join("\n").strip + last_color + " #{note}".chomp
|
187
192
|
end
|
188
193
|
|
189
194
|
##
|
@@ -368,6 +373,14 @@ module Doing
|
|
368
373
|
title
|
369
374
|
end
|
370
375
|
|
376
|
+
# Returns the last escape sequence from a string
|
377
|
+
#
|
378
|
+
# @param string The string to examine
|
379
|
+
#
|
380
|
+
def last_color
|
381
|
+
scan(/\e\[[\d;]+m/).join('')
|
382
|
+
end
|
383
|
+
|
371
384
|
##
|
372
385
|
## Turn raw urls into HTML links
|
373
386
|
##
|
data/lib/doing/version.rb
CHANGED
data/lib/doing/wwid.rb
CHANGED
@@ -1637,13 +1637,22 @@ module Doing
|
|
1637
1637
|
## @param opt [Hash] Additional Options
|
1638
1638
|
##
|
1639
1639
|
def list_section(opt = {})
|
1640
|
+
opt[:config_template] ||= 'default'
|
1641
|
+
cfg = @config.dig('templates', opt[:config_template]).deep_merge({
|
1642
|
+
'wrap_width' => @config['wrap_width'] || 0,
|
1643
|
+
'date_format' => @config['default_date_format'],
|
1644
|
+
'order' => @config['order'] || 'asc',
|
1645
|
+
'tags_color' => @config['tags_color']
|
1646
|
+
})
|
1640
1647
|
opt[:count] ||= 0
|
1641
1648
|
opt[:age] ||= 'newest'
|
1642
|
-
opt[:format] ||=
|
1643
|
-
opt[:order] ||=
|
1649
|
+
opt[:format] ||= cfg['date_format']
|
1650
|
+
opt[:order] ||= cfg['order'] || 'asc'
|
1644
1651
|
opt[:tag_order] ||= 'asc'
|
1645
|
-
opt[:tags_color]
|
1646
|
-
|
1652
|
+
if opt[:tags_color].nil?
|
1653
|
+
opt[:tags_color] = cfg['tags_color'] || false
|
1654
|
+
end
|
1655
|
+
opt[:template] ||= cfg['template']
|
1647
1656
|
|
1648
1657
|
# opt[:highlight] ||= true
|
1649
1658
|
title = ''
|
@@ -1684,7 +1693,7 @@ module Doing
|
|
1684
1693
|
|
1685
1694
|
opt[:output] ||= 'template'
|
1686
1695
|
|
1687
|
-
opt[:wrap_width] ||= @config['templates']['default']['wrap_width']
|
1696
|
+
opt[:wrap_width] ||= @config['templates']['default']['wrap_width'] || 0
|
1688
1697
|
|
1689
1698
|
output(items, title, is_single, opt)
|
1690
1699
|
end
|
@@ -1729,13 +1738,18 @@ module Doing
|
|
1729
1738
|
opt[:totals] ||= false
|
1730
1739
|
opt[:sort_tags] ||= false
|
1731
1740
|
|
1732
|
-
cfg = @config['templates']['today']
|
1741
|
+
cfg = @config['templates']['today'].deep_merge(@config['templates']['default']).deep_merge({
|
1742
|
+
'wrap_width' => @config['wrap_width'] || 0,
|
1743
|
+
'date_format' => @config['default_date_format'],
|
1744
|
+
'order' => @config['order'] || 'asc',
|
1745
|
+
'tags_color' => @config['tags_color']
|
1746
|
+
})
|
1733
1747
|
options = {
|
1734
1748
|
after: opt[:after],
|
1735
1749
|
before: opt[:before],
|
1736
1750
|
count: 0,
|
1737
1751
|
format: cfg['date_format'],
|
1738
|
-
order: 'asc',
|
1752
|
+
order: cfg['order'] || 'asc',
|
1739
1753
|
output: output,
|
1740
1754
|
section: opt[:section],
|
1741
1755
|
sort_tags: opt[:sort_tags],
|
@@ -1743,7 +1757,9 @@ module Doing
|
|
1743
1757
|
times: times,
|
1744
1758
|
today: true,
|
1745
1759
|
totals: opt[:totals],
|
1746
|
-
wrap_width: cfg['wrap_width']
|
1760
|
+
wrap_width: cfg['wrap_width'],
|
1761
|
+
tags_color: cfg['tags_color'],
|
1762
|
+
config_template: 'today'
|
1747
1763
|
}
|
1748
1764
|
list_section(options)
|
1749
1765
|
end
|
@@ -1765,7 +1781,7 @@ module Doing
|
|
1765
1781
|
dates = [dates, dates] if dates.instance_of?(String)
|
1766
1782
|
|
1767
1783
|
list_section({ section: section, count: 0, order: 'asc', date_filter: dates, times: times,
|
1768
|
-
output: output, totals: opt[:totals], sort_tags: opt[:sort_tags] })
|
1784
|
+
output: output, totals: opt[:totals], sort_tags: opt[:sort_tags], config_template: 'default' })
|
1769
1785
|
end
|
1770
1786
|
|
1771
1787
|
##
|
@@ -1795,7 +1811,8 @@ module Doing
|
|
1795
1811
|
tag_order: opt[:tag_order],
|
1796
1812
|
times: times,
|
1797
1813
|
totals: opt[:totals],
|
1798
|
-
yesterday: true
|
1814
|
+
yesterday: true,
|
1815
|
+
config_template: 'today'
|
1799
1816
|
}
|
1800
1817
|
|
1801
1818
|
list_section(options)
|
@@ -1813,14 +1830,19 @@ module Doing
|
|
1813
1830
|
opt[:totals] ||= false
|
1814
1831
|
opt[:sort_tags] ||= false
|
1815
1832
|
|
1816
|
-
cfg = @config['templates']['recent']
|
1833
|
+
cfg = @config['templates']['recent'].deep_merge(@config['templates']['default']).deep_merge({
|
1834
|
+
'wrap_width' => @config['wrap_width'] || 0,
|
1835
|
+
'date_format' => @config['default_date_format'],
|
1836
|
+
'order' => @config['order'] || 'asc',
|
1837
|
+
'tags_color' => @config['tags_color']
|
1838
|
+
})
|
1817
1839
|
section ||= @config['current_section']
|
1818
1840
|
section = guess_section(section)
|
1819
1841
|
|
1820
1842
|
list_section({ section: section, wrap_width: cfg['wrap_width'], count: count,
|
1821
1843
|
format: cfg['date_format'], template: cfg['template'],
|
1822
1844
|
order: 'asc', times: times, totals: opt[:totals],
|
1823
|
-
sort_tags: opt[:sort_tags], tags_color: opt[:tags_color] })
|
1845
|
+
sort_tags: opt[:sort_tags], tags_color: opt[:tags_color], config_template: 'recent' })
|
1824
1846
|
end
|
1825
1847
|
|
1826
1848
|
##
|
@@ -1831,7 +1853,12 @@ module Doing
|
|
1831
1853
|
##
|
1832
1854
|
def last(times: true, section: nil, options: {})
|
1833
1855
|
section = section.nil? || section =~ /all/i ? 'All' : guess_section(section)
|
1834
|
-
cfg = @config['templates']['last']
|
1856
|
+
cfg = @config['templates']['last'].deep_merge(@config['templates']['default']).deep_merge({
|
1857
|
+
'wrap_width' => @config['wrap_width'] || 0,
|
1858
|
+
'date_format' => @config['default_date_format'],
|
1859
|
+
'order' => @config['order'] || 'asc',
|
1860
|
+
'tags_color' => @config['tags_color']
|
1861
|
+
})
|
1835
1862
|
|
1836
1863
|
opts = {
|
1837
1864
|
section: section,
|
@@ -1852,6 +1879,7 @@ module Doing
|
|
1852
1879
|
opts[:search] = options[:search] if options[:search]
|
1853
1880
|
opts[:case] = options[:case]
|
1854
1881
|
opts[:not] = options[:negate]
|
1882
|
+
opts[:config_template] = 'last'
|
1855
1883
|
list_section(opts)
|
1856
1884
|
end
|
1857
1885
|
|
@@ -2156,7 +2184,7 @@ EOS
|
|
2156
2184
|
|
2157
2185
|
@content.each do |title, section|
|
2158
2186
|
output += "#{section[:original]}\n"
|
2159
|
-
output += list_section({ section: title, template: "\t- %date | %title%t2note", highlight: false, wrap_width: 0 })
|
2187
|
+
output += list_section({ section: title, template: "\t- %date | %title%t2note", highlight: false, wrap_width: 0, tags_color: false })
|
2160
2188
|
end
|
2161
2189
|
|
2162
2190
|
output + @other_content_bottom.join("\n") unless @other_content_bottom.nil?
|
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.0.
|
4
|
+
version: 2.0.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Terpstra
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-11-
|
11
|
+
date: 2021-11-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: safe_yaml
|