doing 2.1.39 → 2.1.42
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/.yardopts +1 -1
- data/CHANGELOG.md +67 -0
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/Rakefile +4 -4
- data/bin/commands/again.rb +1 -3
- data/bin/commands/changes.rb +50 -34
- data/bin/commands/commands.rb +77 -52
- data/bin/commands/commands_accepting.rb +57 -53
- data/bin/commands/config.rb +45 -36
- data/bin/commands/done.rb +1 -18
- data/bin/commands/finish.rb +90 -59
- data/bin/commands/flag.rb +5 -1
- data/bin/commands/grep.rb +3 -14
- data/bin/commands/last.rb +2 -8
- data/bin/commands/meanwhile.rb +13 -6
- data/bin/commands/now.rb +151 -107
- data/bin/commands/on.rb +8 -18
- data/bin/commands/recent.rb +2 -8
- data/bin/commands/reset.rb +24 -1
- data/bin/commands/select.rb +1 -1
- data/bin/commands/show.rb +6 -17
- data/bin/commands/since.rb +1 -12
- data/bin/commands/tag_dir.rb +49 -15
- data/bin/commands/today.rb +2 -13
- data/bin/commands/undo.rb +4 -6
- data/bin/commands/view.rb +1 -1
- data/bin/commands/yesterday.rb +2 -13
- data/bin/doing +15 -8
- data/{Dockerfile → docker/Dockerfile} +3 -1
- data/{Dockerfile-2.6 → docker/Dockerfile-2.6} +2 -2
- data/{Dockerfile-2.7 → docker/Dockerfile-2.7} +2 -2
- data/{Dockerfile-3.0 → docker/Dockerfile-3.0} +2 -2
- data/{bash_profile → docker/bash_profile} +0 -0
- data/{inputrc → docker/inputrc} +0 -0
- data/docs/doc/Array.html +85 -2
- data/docs/doc/BooleanTermParser/Clause.html +1 -1
- data/docs/doc/BooleanTermParser/Operator.html +1 -1
- data/docs/doc/BooleanTermParser/Query.html +1 -1
- data/docs/doc/BooleanTermParser/QueryParser.html +1 -1
- data/docs/doc/BooleanTermParser/QueryTransformer.html +1 -1
- data/docs/doc/BooleanTermParser.html +1 -1
- data/docs/doc/Doing/ArrayNestedHash.html +198 -0
- data/docs/doc/Doing/ArrayTags.html +424 -0
- data/docs/doc/Doing/CSVExport.html +266 -0
- data/docs/doc/Doing/CalendarImport.html +232 -0
- data/docs/doc/Doing/Change.html +617 -0
- data/docs/doc/Doing/Changes.html +468 -0
- data/docs/doc/Doing/ChronifyArray.html +347 -0
- data/docs/doc/Doing/ChronifyNumeric.html +271 -0
- data/docs/doc/Doing/ChronifyString.html +682 -0
- data/docs/doc/Doing/Color.html +167 -21
- data/docs/doc/Doing/Completion/BashCompletions.html +445 -0
- data/docs/doc/Doing/Completion/FishCompletions.html +445 -0
- data/docs/doc/Doing/Completion/StringUtils.html +229 -0
- data/docs/doc/Doing/Completion/ZshCompletions.html +445 -0
- data/docs/doc/Doing/Completion.html +17 -3
- data/docs/doc/Doing/Configuration.html +3 -2
- data/docs/doc/Doing/DayOneRenderer.html +383 -0
- data/docs/doc/Doing/DayoneExport.html +290 -0
- data/docs/doc/Doing/DoingImport.html +391 -0
- data/docs/doc/Doing/Entry.html +381 -0
- data/docs/doc/Doing/Errors/DoingNoTraceError.html +7 -3
- data/docs/doc/Doing/Errors/DoingRuntimeError.html +7 -3
- data/docs/doc/Doing/Errors/DoingStandardError.html +1 -1
- data/docs/doc/Doing/Errors/EmptyInput.html +10 -2
- data/docs/doc/Doing/Errors/HistoryLimitError.html +194 -0
- data/docs/doc/Doing/Errors/InvalidPlugin.html +194 -0
- data/docs/doc/Doing/Errors/MissingBackupFile.html +194 -0
- data/docs/doc/Doing/Errors/NoResults.html +10 -2
- data/docs/doc/Doing/Errors/PluginException.html +1 -1
- data/docs/doc/Doing/Errors/UserCancelled.html +10 -2
- data/docs/doc/Doing/Errors/WrongCommand.html +10 -2
- data/docs/doc/Doing/Errors.html +9 -9
- data/docs/doc/Doing/HTMLExport.html +256 -0
- data/docs/doc/Doing/Hooks.html +1 -1
- data/docs/doc/Doing/Item.html +179 -1660
- data/docs/doc/Doing/ItemDates.html +564 -0
- data/docs/doc/Doing/ItemQuery.html +614 -0
- data/docs/doc/Doing/ItemState.html +387 -0
- data/docs/doc/Doing/ItemTags.html +498 -0
- data/docs/doc/Doing/Items.html +581 -15
- data/docs/doc/Doing/JSONExport.html +222 -0
- data/docs/doc/Doing/Logger.html +1 -1
- data/docs/doc/Doing/MarkdownExport.html +266 -0
- data/docs/doc/Doing/MarkdownRenderer.html +383 -0
- data/docs/doc/Doing/Note.html +18 -4
- data/docs/doc/Doing/Pager.html +1 -1
- data/docs/doc/Doing/Plugins.html +181 -76
- data/docs/doc/Doing/Prompt.html +32 -683
- data/docs/doc/Doing/PromptChoose.html +484 -0
- data/docs/doc/Doing/PromptFZF.html +391 -0
- data/docs/doc/Doing/PromptInput.html +572 -0
- data/docs/doc/Doing/PromptSTD.html +293 -0
- data/docs/doc/Doing/PromptYN.html +237 -0
- data/docs/doc/Doing/Section.html +58 -2
- data/docs/doc/Doing/StringHighlight.html +533 -0
- data/docs/doc/Doing/StringNormalize.html +929 -0
- data/docs/doc/Doing/StringQuery.html +725 -0
- data/docs/doc/Doing/StringTags.html +884 -0
- data/docs/doc/Doing/StringTransform.html +599 -0
- data/docs/doc/Doing/StringTruncate.html +448 -0
- data/docs/doc/Doing/StringURL.html +409 -0
- data/docs/doc/Doing/SymbolNormalize.html +341 -0
- data/docs/doc/Doing/TaskPaperExport.html +222 -0
- data/docs/doc/Doing/TemplateExport.html +249 -0
- data/docs/doc/Doing/TemplateString.html +102 -3
- data/docs/doc/Doing/TimingImport.html +285 -0
- data/docs/doc/Doing/Types.html +1 -1
- data/docs/doc/Doing/Util/Backup.html +11 -163
- data/docs/doc/Doing/Util.html +67 -10
- data/docs/doc/Doing/Version.html +523 -0
- data/docs/doc/Doing/WWID/WWIDUtil.html +510 -0
- data/docs/doc/Doing/WWID.html +476 -139
- data/docs/doc/Doing/WWIDDisplay.html +865 -0
- data/docs/doc/Doing/WWIDEditor.html +466 -0
- data/docs/doc/Doing/WWIDFileTools.html +359 -0
- data/docs/doc/Doing/WWIDFilter.html +466 -0
- data/docs/doc/Doing/WWIDGuess.html +299 -0
- data/docs/doc/Doing/WWIDInteractive.html +752 -0
- data/docs/doc/Doing/WWIDModify.html +1078 -0
- data/docs/doc/Doing/WWIDTags.html +302 -0
- data/docs/doc/Doing/WWIDTimers.html +359 -0
- data/docs/doc/Doing/WWIDUtil.html +510 -0
- data/docs/doc/Doing.html +9 -6
- data/docs/doc/FalseClass.html +1 -1
- data/docs/doc/GLI/Commands/Help.html +1 -1
- data/docs/doc/GLI/Commands/MarkdownDocumentListener.html +1 -1
- data/docs/doc/GLI/Commands.html +1 -1
- data/docs/doc/GLI.html +1 -1
- data/docs/doc/Hash.html +1 -1
- data/docs/doc/Numeric.html +23 -78
- data/docs/doc/Object.html +1 -1
- data/docs/doc/PhraseParser/Operator.html +1 -1
- data/docs/doc/PhraseParser/PhraseClause.html +1 -1
- data/docs/doc/PhraseParser/Query.html +1 -1
- data/docs/doc/PhraseParser/QueryParser.html +1 -1
- data/docs/doc/PhraseParser/QueryTransformer.html +1 -1
- data/docs/doc/PhraseParser/TermClause.html +1 -1
- data/docs/doc/PhraseParser.html +1 -1
- data/docs/doc/Status.html +1 -1
- data/docs/doc/String.html +58 -633
- data/docs/doc/Symbol.html +9 -224
- data/docs/doc/Time.html +119 -13
- data/docs/doc/TrueClass.html +1 -1
- data/docs/doc/_index.html +348 -4
- 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 +1904 -592
- data/docs/doc/top-level-namespace.html +12 -4
- data/docs/index.md +1 -1
- data/doing.rdoc +67 -15
- data/lib/completion/_doing.zsh +6 -6
- data/lib/completion/doing.bash +10 -10
- data/lib/completion/doing.fish +10 -3
- data/lib/doing/add_options.rb +39 -1
- data/lib/doing/array/array.rb +18 -12
- data/lib/doing/array/cleanup.rb +31 -0
- data/lib/doing/array/nested_hash.rb +1 -1
- data/lib/doing/array/tags.rb +6 -5
- data/lib/doing/changelog/changelog.rb +6 -0
- data/lib/doing/chronify/array.rb +65 -25
- data/lib/doing/chronify/chronify.rb +12 -0
- data/lib/doing/chronify/numeric.rb +3 -2
- data/lib/doing/chronify/string.rb +1 -1
- data/lib/doing/colors.rb +77 -30
- data/lib/doing/completion/completion_string.rb +25 -0
- data/lib/doing/completion.rb +4 -5
- data/lib/doing/configuration.rb +7 -3
- data/lib/doing/errors.rb +51 -35
- data/lib/doing/good.rb +8 -0
- data/lib/doing/hooks.rb +3 -3
- data/lib/doing/item/dates.rb +112 -0
- data/lib/doing/item/item.rb +128 -0
- data/lib/doing/{item.rb → item/query.rb} +2 -353
- data/lib/doing/item/state.rb +59 -0
- data/lib/doing/item/tags.rb +87 -0
- data/lib/doing/items/filter.rb +67 -0
- data/lib/doing/items/items.rb +57 -0
- data/lib/doing/items/modify.rb +36 -0
- data/lib/doing/items/sections.rb +83 -0
- data/lib/doing/items/util.rb +74 -0
- data/lib/doing/normalize.rb +10 -2
- data/lib/doing/note.rb +1 -1
- data/lib/doing/pager.rb +9 -3
- data/lib/doing/plugin_manager.rb +33 -8
- data/lib/doing/plugins/export/markdown_export.rb +4 -2
- data/lib/doing/plugins/export/template_export.rb +4 -4
- data/lib/doing/plugins/import/cal_to_json.scpt +0 -0
- data/lib/doing/plugins/import/doing_import.rb +1 -1
- data/lib/doing/prompt/choose.rb +118 -0
- data/lib/doing/prompt/fzf.rb +84 -0
- data/lib/doing/prompt/input.rb +129 -0
- data/lib/doing/prompt/prompt.rb +41 -0
- data/lib/doing/prompt/std.rb +32 -0
- data/lib/doing/prompt/yn.rb +64 -0
- data/lib/doing/section.rb +4 -0
- data/lib/doing/string/highlight.rb +1 -1
- data/lib/doing/string/query.rb +1 -1
- data/lib/doing/string/string.rb +18 -7
- data/lib/doing/string/tags.rb +14 -3
- data/lib/doing/string/transform.rb +7 -1
- data/lib/doing/string/truncate.rb +1 -1
- data/lib/doing/string/url.rb +1 -1
- data/lib/doing/time.rb +19 -1
- data/lib/doing/util.rb +12 -6
- data/lib/doing/util_backup.rb +62 -57
- data/lib/doing/version.rb +1 -1
- data/lib/doing/wwid/display.rb +396 -0
- data/lib/doing/wwid/editor.rb +214 -0
- data/lib/doing/wwid/filetools.rb +183 -0
- data/lib/doing/wwid/filter.rb +226 -0
- data/lib/doing/wwid/guess.rb +85 -0
- data/lib/doing/wwid/interactive.rb +377 -0
- data/lib/doing/wwid/modify.rb +617 -0
- data/lib/doing/wwid/tags.rb +51 -0
- data/lib/doing/wwid/timers.rb +342 -0
- data/lib/doing/wwid/wwid.rb +121 -0
- data/lib/doing/wwid/wwidutil.rb +101 -0
- data/lib/doing.rb +7 -7
- data/lib/helpers/threaded_tests.rb +1 -0
- metadata +94 -14
- data/lib/doing/changelog.rb +0 -6
- data/lib/doing/completion/string.rb +0 -17
- data/lib/doing/items.rb +0 -196
- data/lib/doing/prompt.rb +0 -330
- data/lib/doing/wwid.rb +0 -2398
data/lib/doing/array/tags.rb
CHANGED
|
@@ -4,12 +4,14 @@ module Doing
|
|
|
4
4
|
##
|
|
5
5
|
## Array helpers
|
|
6
6
|
##
|
|
7
|
-
|
|
7
|
+
module ArrayTags
|
|
8
8
|
##
|
|
9
9
|
## Convert an array of @tags to plain strings
|
|
10
10
|
##
|
|
11
|
-
## @return [Array] array of strings
|
|
11
|
+
## @return [Array] array of strings without @ symbols
|
|
12
12
|
##
|
|
13
|
+
## @example Convert an array of tags to strings
|
|
14
|
+
## ['@one', '@two', 'three'].to_tags => ['one', 'two', 'three']
|
|
13
15
|
def tags_to_array
|
|
14
16
|
map(&:remove_at).map(&:strip)
|
|
15
17
|
end
|
|
@@ -18,9 +20,8 @@ module Doing
|
|
|
18
20
|
#
|
|
19
21
|
# @return [Array] Array of @tags
|
|
20
22
|
#
|
|
21
|
-
# @example
|
|
22
|
-
# ['one', '@two', 'three'].to_tags
|
|
23
|
-
# # => ['@one', '@two', '@three']
|
|
23
|
+
# @example Convert an array of strings with or without @ symbols
|
|
24
|
+
# ['one', '@two', 'three'].to_tags => ['@one', '@two', '@three']
|
|
24
25
|
def to_tags
|
|
25
26
|
map(&:add_at)
|
|
26
27
|
end
|
data/lib/doing/chronify/array.rb
CHANGED
|
@@ -2,12 +2,60 @@
|
|
|
2
2
|
|
|
3
3
|
module Doing
|
|
4
4
|
# Chronify array helpers
|
|
5
|
-
|
|
5
|
+
module ChronifyArray
|
|
6
|
+
# Convert [d, h, m] to [y, d, h, m]
|
|
7
|
+
def to_years
|
|
8
|
+
d, h, m = self
|
|
9
|
+
|
|
10
|
+
if d.zero? && h > 24
|
|
11
|
+
d = (h / 24).floor
|
|
12
|
+
h = h % 24
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
if d > 365
|
|
16
|
+
y = (d / 365).floor
|
|
17
|
+
d = d % 365
|
|
18
|
+
else
|
|
19
|
+
y = 0
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
[y, d, h, m]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def to_natural
|
|
26
|
+
y, d, h, m = to_years
|
|
27
|
+
human = []
|
|
28
|
+
human.push(format('%<y>d %<s>s', y: y, s: 'year'.to_p(y))) if y.positive?
|
|
29
|
+
human.push(format('%<d>d %<s>s', d: d, s: 'day'.to_p(d))) if d.positive?
|
|
30
|
+
human.push(format('%<h>d %<s>s', h: h, s: 'hour'.to_p(h))) if h.positive?
|
|
31
|
+
human.push(format('%<m>d %<s>s', m: m, s: 'minute'.to_p(m))) if m.positive?
|
|
32
|
+
human
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def to_abbr(years: false, separator: '')
|
|
36
|
+
if years
|
|
37
|
+
y, d, h, m = to_years
|
|
38
|
+
else
|
|
39
|
+
y = 0
|
|
40
|
+
d, h, m = self
|
|
41
|
+
|
|
42
|
+
if d.zero? && h > 24
|
|
43
|
+
d = (h / 24).floor
|
|
44
|
+
h = h % 24
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
output = []
|
|
49
|
+
output.push(format('%<y>dy', y: y)) if y.positive?
|
|
50
|
+
output.push(format('%<d>dd', d: d)) if d.positive?
|
|
51
|
+
output.push(format('%<h>dh', h: h)) if h.positive?
|
|
52
|
+
output.push(format('%<m>dm', m: m)) if m.positive?
|
|
53
|
+
output.join(separator)
|
|
54
|
+
end
|
|
55
|
+
|
|
6
56
|
##
|
|
7
57
|
## Format [d, h, m] as string
|
|
8
58
|
##
|
|
9
|
-
## @accept [Array] Array of [days, hours, minutes]
|
|
10
|
-
##
|
|
11
59
|
## @param format [Symbol] The format, :dhm, :hm,
|
|
12
60
|
## :m, :clock, :natural
|
|
13
61
|
## @return [String] formatted string
|
|
@@ -23,16 +71,13 @@ module Doing
|
|
|
23
71
|
h = h % 24
|
|
24
72
|
end
|
|
25
73
|
format('%<d>02d:%<h>02d:%<m>02d', d: d, h: h, m: m)
|
|
74
|
+
when :hmclock
|
|
75
|
+
h += d * 24 if d.positive?
|
|
76
|
+
format('%<h>02d:%<m>02d', h: h, m: m)
|
|
77
|
+
when :ydhm
|
|
78
|
+
to_abbr(years: true, separator: ' ')
|
|
26
79
|
when :dhm
|
|
27
|
-
|
|
28
|
-
d = (h / 24).floor
|
|
29
|
-
h = h % 24
|
|
30
|
-
end
|
|
31
|
-
output = []
|
|
32
|
-
output.push(format('%<d>dd', d: d)) if d.positive?
|
|
33
|
-
output.push(format('%<h>dh', h: h)) if h.positive?
|
|
34
|
-
output.push(format('%<m>dm', m: m)) if m.positive?
|
|
35
|
-
output.join(' ')
|
|
80
|
+
to_abbr(years: false, separator: ' ')
|
|
36
81
|
when :hm
|
|
37
82
|
h += d * 24 if d.positive?
|
|
38
83
|
format('%<h> 4dh %<m>02dm', h: h, m: m)
|
|
@@ -40,25 +85,20 @@ module Doing
|
|
|
40
85
|
h += d * 24 if d.positive?
|
|
41
86
|
m += h * 60 if h.positive?
|
|
42
87
|
format('%<m> 4dm', m: m)
|
|
88
|
+
when :tight
|
|
89
|
+
to_abbr(years: true, separator: '')
|
|
43
90
|
when :natural
|
|
44
|
-
|
|
45
|
-
human.push(format('%<d>d %<s>s', d: d, s: 'day'.to_p(d))) if d.positive?
|
|
46
|
-
human.push(format('%<h>d %<s>s', h: h, s: 'hour'.to_p(h))) if h.positive?
|
|
47
|
-
human.push(format('%<m>d %<s>s', m: m, s: 'minute'.to_p(m))) if m.positive?
|
|
48
|
-
human.join(', ')
|
|
91
|
+
to_natural.join(', ')
|
|
49
92
|
when :speech
|
|
50
|
-
human =
|
|
51
|
-
human.push(format('%<d>d %<s>s', d: d, s: 'day'.to_p(d))) if d.positive?
|
|
52
|
-
human.push(format('%<h>d %<s>s', h: h, s: 'hour'.to_p(h))) if h.positive?
|
|
53
|
-
human.push(format('%<m>d %<s>s', m: m, s: 'minute'.to_p(m))) if m.positive?
|
|
93
|
+
human = to_natural
|
|
54
94
|
last = human.pop
|
|
55
95
|
case human.count
|
|
56
|
-
when 2
|
|
57
|
-
human.join(', ') + ", and #{last}"
|
|
58
|
-
when 1
|
|
59
|
-
"#{human[0]} and #{last}"
|
|
60
96
|
when 0
|
|
61
97
|
last
|
|
98
|
+
when 1
|
|
99
|
+
"#{human[0]} and #{last}"
|
|
100
|
+
else
|
|
101
|
+
human.join(', ') + ", and #{last}"
|
|
62
102
|
end
|
|
63
103
|
end
|
|
64
104
|
end
|
|
@@ -3,3 +3,15 @@
|
|
|
3
3
|
require_relative 'array'
|
|
4
4
|
require_relative 'numeric'
|
|
5
5
|
require_relative 'string'
|
|
6
|
+
|
|
7
|
+
class ::String
|
|
8
|
+
include Doing::ChronifyString
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class ::Array
|
|
12
|
+
include Doing::ChronifyArray
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class ::Numeric
|
|
16
|
+
include Doing::ChronifyNumeric
|
|
17
|
+
end
|
|
@@ -4,11 +4,12 @@ module Doing
|
|
|
4
4
|
##
|
|
5
5
|
## Number helpers
|
|
6
6
|
##
|
|
7
|
-
|
|
7
|
+
module ChronifyNumeric
|
|
8
8
|
##
|
|
9
9
|
## Format human readable time from seconds
|
|
10
10
|
##
|
|
11
|
-
## @param
|
|
11
|
+
## @param human [Boolean] if True, don't convert
|
|
12
|
+
## hours into days
|
|
12
13
|
##
|
|
13
14
|
def format_time(human: false)
|
|
14
15
|
return [0, 0, 0] if nil?
|
data/lib/doing/colors.rb
CHANGED
|
@@ -2,9 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
# Cribbed from <https://github.com/flori/term-ansicolor>
|
|
4
4
|
module Doing
|
|
5
|
-
# Terminal color functions
|
|
5
|
+
# Terminal output color functions.
|
|
6
6
|
module Color
|
|
7
|
-
#
|
|
7
|
+
# All available color names. Available as methods and string extensions.
|
|
8
|
+
#
|
|
9
|
+
# @example Use a color as a method. Color reset will be added to end of string.
|
|
10
|
+
# Color.yellow('This text is yellow') => "\e[33mThis text is yellow\e[0m"
|
|
11
|
+
#
|
|
12
|
+
# @example Use a color as a string extension. Color reset added automatically.
|
|
13
|
+
# 'This text is green'.green => "\e[1;32mThis text is green\e[0m"
|
|
14
|
+
#
|
|
15
|
+
# @example Send a text string as a color
|
|
16
|
+
# Color.send('red') => "\e[31m"
|
|
8
17
|
ATTRIBUTES = [
|
|
9
18
|
[:clear, 0], # String#clear is already used to empty string in Ruby 1.9
|
|
10
19
|
[:reset, 0], # synonym for :clear
|
|
@@ -66,7 +75,7 @@ module Doing
|
|
|
66
75
|
[:redacted, '0;30;40'],
|
|
67
76
|
[:alert, '1;31;43'],
|
|
68
77
|
[:error, '1;37;41'],
|
|
69
|
-
[:default,
|
|
78
|
+
[:default, '0;39']
|
|
70
79
|
].map(&:freeze).freeze
|
|
71
80
|
|
|
72
81
|
ATTRIBUTE_NAMES = ATTRIBUTES.transpose.first
|
|
@@ -119,24 +128,60 @@ module Doing
|
|
|
119
128
|
end
|
|
120
129
|
|
|
121
130
|
class << self
|
|
122
|
-
# Returns true
|
|
131
|
+
# Returns true if the coloring function of this module
|
|
123
132
|
# is switched on, false otherwise.
|
|
124
133
|
def coloring?
|
|
125
134
|
@coloring
|
|
126
135
|
end
|
|
127
136
|
|
|
128
|
-
# Turns the coloring on or off globally, so you can easily do
|
|
129
|
-
# this for example:
|
|
130
|
-
# Doing::Color::coloring = STDOUT.isatty
|
|
131
137
|
attr_writer :coloring
|
|
132
138
|
|
|
139
|
+
##
|
|
140
|
+
## Enables colored output
|
|
141
|
+
##
|
|
142
|
+
## @example Turn color on or off based on TTY
|
|
143
|
+
## Doing::Color.coloring = STDOUT.isatty
|
|
133
144
|
def coloring
|
|
134
145
|
@coloring ||= true
|
|
135
146
|
end
|
|
147
|
+
|
|
148
|
+
##
|
|
149
|
+
## Convert a template string to a colored string.
|
|
150
|
+
## Colors are specified with single letters inside
|
|
151
|
+
## curly braces. Uppercase changes background color.
|
|
152
|
+
##
|
|
153
|
+
## w: white, k: black, g: green, l: blue, y: yellow, c: cyan,
|
|
154
|
+
## m: magenta, r: red, b: bold, u: underline, i: italic,
|
|
155
|
+
## x: reset (remove background, color, emphasis)
|
|
156
|
+
##
|
|
157
|
+
## @example Convert a templated string
|
|
158
|
+
## Color.template('{Rwb}Warning:{x} {w}you look a little {g}ill{x}')
|
|
159
|
+
##
|
|
160
|
+
## @param input [String, Array] The template
|
|
161
|
+
## string. If this is an array, the
|
|
162
|
+
## elements will be joined with a
|
|
163
|
+
## space.
|
|
164
|
+
##
|
|
165
|
+
## @return [String] Colorized string
|
|
166
|
+
##
|
|
167
|
+
def template(input)
|
|
168
|
+
input = input.join(' ') if input.is_a? Array
|
|
169
|
+
fmt = input.gsub(/\{(\w+)\}/) do
|
|
170
|
+
Regexp.last_match(1).split('').map { |c| "%<#{c}>s" }.join('')
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
colors = { w: white, k: black, g: green, l: blue,
|
|
174
|
+
y: yellow, c: cyan, m: magenta, r: red,
|
|
175
|
+
W: bgwhite, K: bgblack, G: bggreen, L: bgblue,
|
|
176
|
+
Y: bgyellow, C: bgcyan, M: bgmagenta, R: bgred,
|
|
177
|
+
b: bold, u: underline, i: italic, x: reset }
|
|
178
|
+
|
|
179
|
+
format(fmt, colors)
|
|
180
|
+
end
|
|
136
181
|
end
|
|
137
182
|
|
|
138
183
|
ATTRIBUTES.each do |c, v|
|
|
139
|
-
|
|
184
|
+
new_method = <<-EOSCRIPT
|
|
140
185
|
def #{c}(string = nil)
|
|
141
186
|
result = ''
|
|
142
187
|
result << "\e[#{v}m" if Doing::Color.coloring?
|
|
@@ -152,33 +197,37 @@ module Doing
|
|
|
152
197
|
result << "\e[0m" if Doing::Color.coloring?
|
|
153
198
|
result
|
|
154
199
|
end
|
|
155
|
-
|
|
200
|
+
EOSCRIPT
|
|
201
|
+
|
|
202
|
+
module_eval(new_method)
|
|
203
|
+
|
|
204
|
+
next unless c =~ /bold/
|
|
156
205
|
|
|
157
206
|
# Accept brightwhite in addition to boldwhite
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
return result #only switch on
|
|
171
|
-
end
|
|
172
|
-
result << "\e[0m" if Doing::Color.coloring?
|
|
173
|
-
result
|
|
207
|
+
new_method = <<-EOSCRIPT
|
|
208
|
+
def #{c.to_s.sub(/bold/, 'bright')}(string = nil)
|
|
209
|
+
result = ''
|
|
210
|
+
result << "\e[#{v}m" if Doing::Color.coloring?
|
|
211
|
+
if block_given?
|
|
212
|
+
result << yield
|
|
213
|
+
elsif string.respond_to?(:to_str)
|
|
214
|
+
result << string.to_str
|
|
215
|
+
elsif respond_to?(:to_str)
|
|
216
|
+
result << to_str
|
|
217
|
+
else
|
|
218
|
+
return result #only switch on
|
|
174
219
|
end
|
|
175
|
-
|
|
176
|
-
|
|
220
|
+
result << "\e[0m" if Doing::Color.coloring?
|
|
221
|
+
result
|
|
222
|
+
end
|
|
223
|
+
EOSCRIPT
|
|
224
|
+
|
|
225
|
+
module_eval(new_method)
|
|
177
226
|
end
|
|
178
227
|
|
|
179
228
|
# Regular expression that is used to scan for ANSI-sequences while
|
|
180
229
|
# uncoloring strings.
|
|
181
|
-
COLORED_REGEXP = /\e\[(?:(?:[349]|10)[0-7]|[0-9])?m
|
|
230
|
+
COLORED_REGEXP = /\e\[(?:(?:[349]|10)[0-7]|[0-9])?m/.freeze
|
|
182
231
|
|
|
183
232
|
# Returns an uncolored version of the string, that is all
|
|
184
233
|
# ANSI-sequences are stripped from the string.
|
|
@@ -194,8 +243,6 @@ module Doing
|
|
|
194
243
|
end
|
|
195
244
|
end
|
|
196
245
|
|
|
197
|
-
module_function
|
|
198
|
-
|
|
199
246
|
# Returns an array of all Doing::Color attributes as symbols.
|
|
200
247
|
def attributes
|
|
201
248
|
ATTRIBUTE_NAMES
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Doing
|
|
2
|
+
module Completion
|
|
3
|
+
module StringUtils
|
|
4
|
+
def short_desc
|
|
5
|
+
split(/[,.]/)[0].sub(/ \(.*?\)?$/, '').strip
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def ltrunc(max)
|
|
9
|
+
if length > max
|
|
10
|
+
sub(/^.*?(.{#{max - 3}})$/, '...\1')
|
|
11
|
+
else
|
|
12
|
+
self
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def ltrunc!(max)
|
|
17
|
+
replace ltrunc(max)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class ::String
|
|
24
|
+
include Doing::Completion::StringUtils
|
|
25
|
+
end
|
data/lib/doing/completion.rb
CHANGED
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
require 'tty-progressbar'
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
require 'bash_completion'
|
|
5
|
+
require_relative 'completion/completion_string'
|
|
6
|
+
require_relative 'completion/fish_completion'
|
|
7
|
+
require_relative 'completion/zsh_completion'
|
|
8
|
+
require_relative 'completion/bash_completion'
|
|
10
9
|
|
|
11
10
|
module Doing
|
|
12
11
|
# Completion script generator
|
data/lib/doing/configuration.rb
CHANGED
|
@@ -23,7 +23,8 @@ module Doing
|
|
|
23
23
|
'editors' => {
|
|
24
24
|
'default' => ENV['DOING_EDITOR'] || ENV['GIT_EDITOR'] || ENV['EDITOR'],
|
|
25
25
|
'doing_file' => nil,
|
|
26
|
-
'config' => nil
|
|
26
|
+
'config' => nil,
|
|
27
|
+
'pager' => nil
|
|
27
28
|
},
|
|
28
29
|
'plugins' => {
|
|
29
30
|
'plugin_path' => File.join(Util.user_home, '.config', 'doing', 'plugins'),
|
|
@@ -204,6 +205,7 @@ module Doing
|
|
|
204
205
|
real_path = []
|
|
205
206
|
unless keypath =~ /^[.*]?$/
|
|
206
207
|
paths = keypath.split(/[:.]/)
|
|
208
|
+
element_count = paths.count
|
|
207
209
|
while paths.length.positive? && !cfg.nil?
|
|
208
210
|
path = paths.shift
|
|
209
211
|
new_cfg = nil
|
|
@@ -220,6 +222,8 @@ module Doing
|
|
|
220
222
|
end
|
|
221
223
|
|
|
222
224
|
if new_cfg.nil?
|
|
225
|
+
return real_path if real_path[-1] == path && real_path.count == element_count
|
|
226
|
+
|
|
223
227
|
if distance < 5 && !create
|
|
224
228
|
return resolve_key_path(keypath, create: false, distance: distance + 1)
|
|
225
229
|
else
|
|
@@ -228,12 +232,12 @@ module Doing
|
|
|
228
232
|
|
|
229
233
|
resolved = real_path.count.positive? ? "Resolved #{real_path.join('.')}, but " : ''
|
|
230
234
|
Doing.logger.log_now(:warn, "#{resolved}#{path} is unknown")
|
|
231
|
-
new_path = [*real_path, path, *paths].join('.')
|
|
235
|
+
new_path = [*real_path, path, *paths].compact.join('.')
|
|
232
236
|
Doing.logger.log_now(:warn, "Continuing will create the path #{new_path}")
|
|
233
237
|
res = Prompt.yn('Key path not found, create it?', default_response: true)
|
|
234
238
|
raise InvalidArgument, 'Invalid key path' unless res
|
|
235
239
|
|
|
236
|
-
real_path.push(path).concat(paths)
|
|
240
|
+
real_path.push(path).concat(paths).compact!
|
|
237
241
|
Doing.logger.debug('Config:', "translated key path #{keypath} to #{real_path.join('.')}")
|
|
238
242
|
return real_path
|
|
239
243
|
end
|
data/lib/doing/errors.rb
CHANGED
|
@@ -2,19 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
module Doing
|
|
4
4
|
module Errors
|
|
5
|
-
class
|
|
6
|
-
def initialize(msg =
|
|
5
|
+
class DoingNoTraceError < ::StandardError
|
|
6
|
+
def initialize(msg = nil, level: nil, topic: 'Error:', exit_code: 1)
|
|
7
|
+
level ||= :error
|
|
7
8
|
Doing.logger.output_results
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
if msg
|
|
10
|
+
Doing.logger.log_now(level, topic, msg)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
Process.exit exit_code
|
|
10
14
|
end
|
|
11
15
|
end
|
|
12
16
|
|
|
13
|
-
class
|
|
17
|
+
class UserCancelled < DoingNoTraceError
|
|
18
|
+
def initialize(msg = 'Cancelled', topic = 'Exited:')
|
|
19
|
+
super(msg, level: :warn, topic: topic, exit_code: 1)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class EmptyInput < DoingNoTraceError
|
|
14
24
|
def initialize(msg = 'No input', topic = 'Exited:')
|
|
15
|
-
|
|
16
|
-
Doing.logger.log_now(:warn, topic, msg)
|
|
17
|
-
Process.exit 1
|
|
25
|
+
super(msg, level: :warn, topic: topic, exit_code: 6)
|
|
18
26
|
end
|
|
19
27
|
end
|
|
20
28
|
|
|
@@ -22,44 +30,47 @@ module Doing
|
|
|
22
30
|
def initialize(msg = '')
|
|
23
31
|
Doing.logger.output_results
|
|
24
32
|
|
|
25
|
-
super
|
|
33
|
+
super(msg)
|
|
26
34
|
end
|
|
27
35
|
end
|
|
28
36
|
|
|
29
|
-
class WrongCommand <
|
|
37
|
+
class WrongCommand < DoingNoTraceError
|
|
30
38
|
def initialize(msg = 'wrong command', topic: 'Error:')
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
super(msg)
|
|
39
|
+
super(msg, level: :warn, topic: topic, exit_code: 2)
|
|
34
40
|
end
|
|
35
41
|
end
|
|
36
42
|
|
|
37
43
|
class DoingRuntimeError < ::RuntimeError
|
|
38
|
-
def initialize(msg = 'Runtime Error', topic: 'Error:')
|
|
44
|
+
def initialize(msg = 'Runtime Error', exit_code = nil, topic: 'Error:')
|
|
39
45
|
Doing.logger.output_results
|
|
40
46
|
Doing.logger.log_now(:error, topic, msg)
|
|
41
|
-
|
|
47
|
+
|
|
48
|
+
Process.exit exit_code if exit_code
|
|
42
49
|
end
|
|
43
50
|
end
|
|
44
51
|
|
|
45
|
-
class NoResults <
|
|
52
|
+
class NoResults < DoingNoTraceError
|
|
46
53
|
def initialize(msg = 'No results', topic = 'Exited:')
|
|
47
|
-
|
|
48
|
-
Doing.logger.log_now(:warn, topic, msg)
|
|
49
|
-
Process.exit 0
|
|
54
|
+
super(msg, level: :warn, topic: topic, exit_code: 0)
|
|
50
55
|
|
|
51
56
|
end
|
|
52
57
|
end
|
|
53
58
|
|
|
54
|
-
class
|
|
55
|
-
def initialize(msg
|
|
56
|
-
level
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
Doing.logger.log_now(level, topic, msg)
|
|
60
|
-
end
|
|
59
|
+
class HistoryLimitError < DoingNoTraceError
|
|
60
|
+
def initialize(msg, exit_code = 24)
|
|
61
|
+
super(msg, level: :error, topic: 'History:', exit_code: exit_code)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
61
64
|
|
|
62
|
-
|
|
65
|
+
class MissingBackupFile < DoingNoTraceError
|
|
66
|
+
def initialize(msg, exit_code = 26)
|
|
67
|
+
super(msg, level: :error, topic: 'History:', exit_code: exit_code)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
class InvalidPlugin < DoingRuntimeError
|
|
72
|
+
def initialize(kind = 'output', msg = nil)
|
|
73
|
+
super(%(Invalid #{kind} type (#{msg})), 128, topic: 'Invalid:')
|
|
63
74
|
end
|
|
64
75
|
end
|
|
65
76
|
|
|
@@ -75,6 +86,10 @@ module Doing
|
|
|
75
86
|
'Import plugin'
|
|
76
87
|
when /^e/
|
|
77
88
|
'Export plugin'
|
|
89
|
+
when /^h/
|
|
90
|
+
'Hook'
|
|
91
|
+
when /^u/
|
|
92
|
+
'Unrecognized'
|
|
78
93
|
else
|
|
79
94
|
type.to_s
|
|
80
95
|
end
|
|
@@ -82,7 +97,8 @@ module Doing
|
|
|
82
97
|
msg = "(#{@type}: #{@plugin}) #{msg}"
|
|
83
98
|
|
|
84
99
|
Doing.logger.log_now(:error, 'Plugin:', msg)
|
|
85
|
-
|
|
100
|
+
|
|
101
|
+
super(msg)
|
|
86
102
|
end
|
|
87
103
|
end
|
|
88
104
|
|
|
@@ -90,17 +106,17 @@ module Doing
|
|
|
90
106
|
InvalidPluginType = Class.new(PluginException)
|
|
91
107
|
PluginUncallable = Class.new(PluginException)
|
|
92
108
|
|
|
93
|
-
InvalidArgument = Class.new(
|
|
94
|
-
MissingArgument = Class.new(
|
|
95
|
-
MissingFile = Class.new(
|
|
96
|
-
MissingEditor = Class.new(
|
|
109
|
+
InvalidArgument = Class.new(DoingNoTraceError)
|
|
110
|
+
MissingArgument = Class.new(DoingNoTraceError)
|
|
111
|
+
MissingFile = Class.new(DoingNoTraceError)
|
|
112
|
+
MissingEditor = Class.new(DoingNoTraceError)
|
|
97
113
|
NonInteractive = Class.new(StandardError)
|
|
98
114
|
|
|
99
|
-
NoEntryError = Class.new(
|
|
115
|
+
NoEntryError = Class.new(DoingNoTraceError)
|
|
100
116
|
|
|
101
117
|
InvalidTimeExpression = Class.new(DoingRuntimeError)
|
|
102
|
-
InvalidSection = Class.new(
|
|
103
|
-
InvalidView = Class.new(
|
|
118
|
+
InvalidSection = Class.new(DoingNoTraceError)
|
|
119
|
+
InvalidView = Class.new(DoingNoTraceError)
|
|
104
120
|
|
|
105
121
|
ItemNotFound = Class.new(DoingRuntimeError)
|
|
106
122
|
# FatalException = Class.new(::RuntimeError)
|
data/lib/doing/good.rb
CHANGED
data/lib/doing/hooks.rb
CHANGED
|
@@ -15,7 +15,7 @@ module Doing
|
|
|
15
15
|
post_entry_removed: [], # wwid, entry.dup
|
|
16
16
|
pre_export: [], # wwid, format, entries
|
|
17
17
|
pre_write: [], # wwid, file
|
|
18
|
-
post_write: [] #
|
|
18
|
+
post_write: [] # file
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
# map of all hooks and their priorities
|
|
@@ -40,10 +40,10 @@ module Doing
|
|
|
40
40
|
# register a single hook to be called later, internal API
|
|
41
41
|
def self.register_one(event, priority, &block)
|
|
42
42
|
unless @registry[event]
|
|
43
|
-
raise Doing::Errors::HookUnavailable
|
|
43
|
+
raise Doing::Errors::HookUnavailable.new("Invalid hook. Doing only supports #{@registry.keys.inspect}", 'hook', event)
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
-
raise Doing::Errors::PluginUncallable
|
|
46
|
+
raise Doing::Errors::PluginUncallable.new('Hooks must respond to :call', 'hook', event) unless block.respond_to? :call
|
|
47
47
|
|
|
48
48
|
Doing.logger.debug('Hook Manager:', "Registered #{event} hook") if ENV['DOING_PLUGIN_DEBUG']
|
|
49
49
|
|