doing 2.1.42 → 2.1.45
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +53 -0
- data/Gemfile.lock +4 -4
- data/README.md +1 -1
- data/bin/commands/changes.rb +11 -1
- data/bin/commands/flag.rb +1 -1
- data/bin/commands/grep.rb +12 -2
- data/bin/commands/last.rb +2 -0
- data/bin/commands/on.rb +13 -1
- data/bin/commands/recent.rb +4 -1
- data/bin/commands/show.rb +8 -0
- data/bin/commands/since.rb +6 -2
- data/bin/commands/template.rb +14 -25
- data/bin/commands/today.rb +4 -1
- data/bin/commands/view.rb +36 -73
- data/bin/commands/views.rb +102 -5
- data/bin/commands/yesterday.rb +3 -1
- data/bin/doing +31 -4
- data/docs/doc/Array.html +12 -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/ArrayCleanup.html +316 -0
- data/docs/doc/Doing/ArrayNestedHash.html +1 -1
- data/docs/doc/Doing/ArrayTags.html +1 -1
- data/docs/doc/Doing/CSVExport.html +1 -1
- data/docs/doc/Doing/CalendarImport.html +1 -1
- data/docs/doc/Doing/Change.html +74 -3
- data/docs/doc/Doing/Changes.html +3 -3
- data/docs/doc/Doing/ChronifyArray.html +1 -1
- data/docs/doc/Doing/ChronifyNumeric.html +1 -1
- data/docs/doc/Doing/ChronifyString.html +1 -1
- data/docs/doc/Doing/Color.html +1 -1
- data/docs/doc/Doing/Completion/BashCompletions.html +1 -1
- data/docs/doc/Doing/Completion/FishCompletions.html +1 -1
- data/docs/doc/Doing/Completion/StringUtils.html +1 -1
- data/docs/doc/Doing/Completion/ZshCompletions.html +1 -1
- data/docs/doc/Doing/Completion.html +1 -1
- data/docs/doc/Doing/Configuration.html +80 -1
- data/docs/doc/Doing/DayOneRenderer.html +1 -1
- data/docs/doc/Doing/DayoneExport.html +1 -1
- data/docs/doc/Doing/DoingImport.html +1 -1
- data/docs/doc/Doing/Entry.html +109 -4
- data/docs/doc/Doing/Errors/DoingNoTraceError.html +1 -1
- data/docs/doc/Doing/Errors/DoingRuntimeError.html +1 -1
- data/docs/doc/Doing/Errors/DoingStandardError.html +1 -1
- data/docs/doc/Doing/Errors/EmptyInput.html +1 -1
- data/docs/doc/Doing/Errors/HistoryLimitError.html +1 -1
- data/docs/doc/Doing/Errors/InvalidPlugin.html +1 -1
- data/docs/doc/Doing/Errors/MissingBackupFile.html +1 -1
- data/docs/doc/Doing/Errors/NoResults.html +1 -1
- data/docs/doc/Doing/Errors/PluginException.html +1 -1
- data/docs/doc/Doing/Errors/UserCancelled.html +1 -1
- data/docs/doc/Doing/Errors/WrongCommand.html +1 -1
- data/docs/doc/Doing/Errors.html +1 -1
- data/docs/doc/Doing/HTMLExport.html +1 -1
- data/docs/doc/Doing/Hooks.html +1 -1
- data/docs/doc/Doing/Item.html +1 -1
- data/docs/doc/Doing/ItemDates.html +1 -1
- data/docs/doc/Doing/ItemQuery.html +1 -1
- data/docs/doc/Doing/ItemState.html +1 -1
- data/docs/doc/Doing/ItemTags.html +1 -1
- data/docs/doc/Doing/Items.html +1 -1
- data/docs/doc/Doing/JSONExport.html +1 -1
- data/docs/doc/Doing/Logger.html +1 -1
- data/docs/doc/Doing/MarkdownExport.html +1 -1
- data/docs/doc/Doing/Note.html +1 -1
- data/docs/doc/Doing/Pager.html +1 -1
- data/docs/doc/Doing/Plugins.html +1 -1
- data/docs/doc/Doing/Prompt.html +1 -1
- data/docs/doc/Doing/PromptChoose.html +1 -1
- data/docs/doc/Doing/PromptFZF.html +1 -1
- data/docs/doc/Doing/PromptInput.html +1 -1
- data/docs/doc/Doing/PromptSTD.html +1 -1
- data/docs/doc/Doing/PromptYN.html +1 -1
- data/docs/doc/Doing/Section.html +1 -1
- data/docs/doc/Doing/StringHighlight.html +1 -1
- data/docs/doc/Doing/StringNormalize.html +35 -1
- data/docs/doc/Doing/StringQuery.html +1 -1
- data/docs/doc/Doing/StringTags.html +1 -1
- data/docs/doc/Doing/StringTransform.html +1 -1
- data/docs/doc/Doing/StringTruncate.html +1 -1
- data/docs/doc/Doing/StringURL.html +1 -1
- data/docs/doc/Doing/SymbolNormalize.html +1 -1
- data/docs/doc/Doing/TaskPaperExport.html +1 -1
- data/docs/doc/Doing/TemplateExport.html +1 -1
- data/docs/doc/Doing/TemplateString.html +2 -2
- data/docs/doc/Doing/TimingImport.html +1 -1
- data/docs/doc/Doing/Types.html +23 -18
- data/docs/doc/Doing/Util/Backup.html +1 -1
- data/docs/doc/Doing/Util.html +1 -1
- data/docs/doc/Doing/Version.html +1 -1
- data/docs/doc/Doing/WWID.html +71 -3
- data/docs/doc/Doing.html +2 -2
- data/docs/doc/FalseClass.html +11 -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 +461 -6
- data/docs/doc/Numeric.html +1 -1
- 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 +4 -4
- data/docs/doc/Symbol.html +1 -1
- data/docs/doc/Time.html +68 -3
- data/docs/doc/TrueClass.html +11 -1
- data/docs/doc/_index.html +1 -1
- data/docs/doc/file.README.html +2 -2
- data/docs/doc/index.html +2 -2
- data/docs/doc/method_list.html +511 -407
- data/docs/doc/top-level-namespace.html +3 -1
- data/doing.rdoc +163 -7
- data/lib/completion/_doing.zsh +13 -13
- data/lib/completion/doing.bash +22 -22
- data/lib/completion/doing.fish +24 -1
- data/lib/doing/add_options.rb +40 -1
- data/lib/doing/changelog/change.rb +13 -5
- data/lib/doing/changelog/changes.rb +11 -2
- data/lib/doing/changelog/entry.rb +9 -2
- data/lib/doing/configuration.rb +21 -0
- data/lib/doing/good.rb +18 -1
- data/lib/doing/hash.rb +126 -22
- data/lib/doing/normalize.rb +13 -0
- data/lib/doing/pager.rb +1 -1
- data/lib/doing/types.rb +9 -8
- data/lib/doing/version.rb +1 -1
- data/lib/doing/wwid/display.rb +4 -1
- data/lib/doing/wwid/filter.rb +6 -3
- data/lib/doing/wwid/wwid.rb +21 -3
- data/lib/doing.rb +9 -0
- metadata +3 -2
data/lib/doing/hash.rb
CHANGED
@@ -40,14 +40,46 @@ module Doing
|
|
40
40
|
|
41
41
|
# Turn all keys into string
|
42
42
|
#
|
43
|
-
#
|
43
|
+
# If the hash has both a string and a symbol for key,
|
44
|
+
# keep the string value, discarding the symnbol value
|
45
|
+
#
|
46
|
+
# @return [Hash] a copy of the hash where all its
|
47
|
+
# keys are strings
|
48
|
+
#
|
44
49
|
def stringify_keys
|
45
|
-
each_with_object({})
|
50
|
+
each_with_object({}) do |(k, v), hsh|
|
51
|
+
next if k.is_a?(Symbol) && key?(k.to_s)
|
52
|
+
|
53
|
+
hsh[k.to_s] = v.is_a?(Hash) ? v.stringify_keys : v
|
54
|
+
end
|
46
55
|
end
|
47
56
|
|
48
57
|
# Turn all keys into symbols
|
58
|
+
#
|
59
|
+
# If the hash has both a string and a symbol for a key,
|
60
|
+
# keep the symbol value and discard the string value
|
61
|
+
#
|
62
|
+
# @return [Hash] a copy of the hash where all its
|
63
|
+
# keys are symbols
|
64
|
+
#
|
49
65
|
def symbolize_keys
|
50
|
-
each_with_object({})
|
66
|
+
each_with_object({}) do |(k, v), hsh|
|
67
|
+
next if k.is_a?(String) && key?(k.to_sym)
|
68
|
+
|
69
|
+
hsh[k.to_sym] = v.is_a?(Hash) ? v.symbolize_keys : v
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def stringify_values
|
74
|
+
transform_values do |v|
|
75
|
+
if v.is_a?(Hash)
|
76
|
+
v.stringify_values
|
77
|
+
elsif v.is_a?(Symbol)
|
78
|
+
v.to_s
|
79
|
+
else
|
80
|
+
v
|
81
|
+
end
|
82
|
+
end
|
51
83
|
end
|
52
84
|
|
53
85
|
# Set a nested hash value using an array
|
@@ -61,30 +93,102 @@ module Doing
|
|
61
93
|
#
|
62
94
|
def deep_set(path, value)
|
63
95
|
if path.count == 1
|
64
|
-
|
65
|
-
self[path[0]] = value
|
66
|
-
else
|
96
|
+
if value.nil? || value =~ /^ *$/
|
67
97
|
delete(path[0])
|
98
|
+
else
|
99
|
+
self[path[0]] = value
|
68
100
|
end
|
101
|
+
elsif value
|
102
|
+
self.default_proc = ->(h, k) { h[k] = Hash.new(&h.default_proc) }
|
103
|
+
dig(*path[0..-2])[path.fetch(-1)] = value
|
69
104
|
else
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
path.each do |key|
|
80
|
-
if cleaned[key].empty?
|
81
|
-
cleaned.delete(key)
|
82
|
-
break
|
83
|
-
end
|
84
|
-
cleaned = cleaned[key]
|
105
|
+
return self unless dig(*path)
|
106
|
+
|
107
|
+
dig(*path[0..-2]).delete(path.fetch(-1))
|
108
|
+
path.pop
|
109
|
+
cleaned = self
|
110
|
+
path.each do |key|
|
111
|
+
if cleaned[key].empty?
|
112
|
+
cleaned.delete(key)
|
113
|
+
break
|
85
114
|
end
|
86
|
-
|
115
|
+
cleaned = cleaned[key]
|
87
116
|
end
|
117
|
+
empty? ? nil : self
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
##
|
122
|
+
## Rename a key, deleting old key
|
123
|
+
##
|
124
|
+
## @param old_key The original key
|
125
|
+
## @param new_key The new key
|
126
|
+
## @param keep [Boolean] if true, keep old key
|
127
|
+
## in addition to new key
|
128
|
+
##
|
129
|
+
def rename_key(old_key, new_key, keep: false)
|
130
|
+
return unless key?(old_key)
|
131
|
+
|
132
|
+
self[new_key] = self[old_key]
|
133
|
+
self[new_key.to_s] = self[old_key] if key?(new_key.to_s)
|
134
|
+
delete(old_key) unless keep
|
135
|
+
end
|
136
|
+
|
137
|
+
##
|
138
|
+
## Rename keys in batch
|
139
|
+
##
|
140
|
+
## @param pairs [Array] pairs of old and new keys
|
141
|
+
##
|
142
|
+
def rename_keys(*pairs)
|
143
|
+
pairs.each { |p| rename_key(p[0], p[1]) }
|
144
|
+
end
|
145
|
+
|
146
|
+
##
|
147
|
+
## Remove keys with empty values
|
148
|
+
##
|
149
|
+
def remove_empty
|
150
|
+
delete_if { |k, v| !v.is_a?(FalseClass) && !v.good? }
|
151
|
+
end
|
152
|
+
|
153
|
+
def tag_filter_to_options
|
154
|
+
hsh = dup
|
155
|
+
if hsh.key?(:tag_filter)
|
156
|
+
hsh[:tags] = hsh[:tag_filter][:tags]
|
157
|
+
hsh[:bool] = hsh[:tag_filter][:bool]
|
158
|
+
hsh.delete(:tag_filter)
|
159
|
+
end
|
160
|
+
replace hsh
|
161
|
+
end
|
162
|
+
|
163
|
+
##
|
164
|
+
## Convert an options hash to a view config
|
165
|
+
##
|
166
|
+
## @return [Hash] View representation of the object.
|
167
|
+
##
|
168
|
+
def to_view
|
169
|
+
hsh = symbolize_keys
|
170
|
+
%w[x save c a s o h e editor m menu i interactive d delete t fuzzy time_filter sort_tags].each do |key|
|
171
|
+
hsh.delete(key.to_sym) if hsh.key?(key.to_sym)
|
172
|
+
end
|
173
|
+
|
174
|
+
hsh.delete_unless_key(:tag, %i[bool])
|
175
|
+
hsh.delete_unless_key(:search, %i[exact case])
|
176
|
+
hsh.rename_keys(%i[not negate], %i[tag tags])
|
177
|
+
hsh.tag_filter_to_options
|
178
|
+
|
179
|
+
hsh = hsh.remove_empty.stringify_keys.stringify_values
|
180
|
+
hsh.keys.sort.each_with_object({}) { |k, out| out[k] = hsh[k] }
|
181
|
+
end
|
182
|
+
|
183
|
+
##
|
184
|
+
## Delete array of keys unless key exists
|
185
|
+
##
|
186
|
+
## @param key The key to verify
|
187
|
+
## @param to_delete [Array] the keys to delete if key doesn't exist
|
188
|
+
##
|
189
|
+
def delete_unless_key(key, to_delete)
|
190
|
+
unless key?(key)
|
191
|
+
to_delete.each { |k| delete(k) }
|
88
192
|
end
|
89
193
|
end
|
90
194
|
end
|
data/lib/doing/normalize.rb
CHANGED
@@ -155,6 +155,19 @@ module Doing
|
|
155
155
|
def normalize_trigger!
|
156
156
|
replace normalize_trigger
|
157
157
|
end
|
158
|
+
|
159
|
+
def normalize_change_type
|
160
|
+
case self
|
161
|
+
when /^c/i
|
162
|
+
:changed
|
163
|
+
when /^i/i
|
164
|
+
:improved
|
165
|
+
when /^f/i
|
166
|
+
:fixed
|
167
|
+
when /^n/i
|
168
|
+
:new
|
169
|
+
end
|
170
|
+
end
|
158
171
|
end
|
159
172
|
|
160
173
|
##
|
data/lib/doing/pager.rb
CHANGED
data/lib/doing/types.rb
CHANGED
@@ -17,18 +17,19 @@ module Doing
|
|
17
17
|
InvalidExportType = Class.new(RuntimeError)
|
18
18
|
MissingConfigFile = Class.new(RuntimeError)
|
19
19
|
|
20
|
-
|
21
|
-
|
20
|
+
AgeSymbol = Class.new(String)
|
21
|
+
BooleanSymbol = Class.new(Symbol)
|
22
|
+
CaseSymbol = Class.new(Symbol)
|
22
23
|
DateBeginString = Class.new(DateTime)
|
23
24
|
DateEndString = Class.new(DateTime)
|
24
|
-
DateRangeString = Class.new(Array)
|
25
|
-
DateRangeOptionalString = Class.new(Array)
|
26
25
|
DateIntervalString = Class.new(DateTime)
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
DateRangeOptionalString = Class.new(Array)
|
27
|
+
DateRangeString = Class.new(Array)
|
28
|
+
ExportTemplate = Class.new(String)
|
29
|
+
MatchingSymbol = Class.new(Symbol)
|
30
30
|
OrderSymbol = Class.new(Symbol)
|
31
|
+
TagArray = Class.new(Array)
|
31
32
|
TagSortSymbol = Class.new(Symbol)
|
32
|
-
|
33
|
+
TemplateName = Class.new(String)
|
33
34
|
end
|
34
35
|
end
|
data/lib/doing/version.rb
CHANGED
data/lib/doing/wwid/display.rb
CHANGED
@@ -357,7 +357,10 @@ module Doing
|
|
357
357
|
opt ||= {}
|
358
358
|
out = nil
|
359
359
|
|
360
|
-
|
360
|
+
unless opt[:output] =~ Plugins.plugin_regex(type: :export)
|
361
|
+
raise InvalidPlugin.new('Unknown output format', opt[:output])
|
362
|
+
|
363
|
+
end
|
361
364
|
|
362
365
|
export_options = { page_title: title, is_single: is_single, options: opt }
|
363
366
|
|
data/lib/doing/wwid/filter.rb
CHANGED
@@ -146,21 +146,24 @@ module Doing
|
|
146
146
|
end
|
147
147
|
|
148
148
|
if keep && opt[:time_filter][0] || opt[:time_filter][1]
|
149
|
+
opt[:time_filter][0] = '00:00' if opt[:time_filter][0] =~ /12 *am/i
|
150
|
+
opt[:time_filter][1] = '00:00' if opt[:time_filter][1] =~ /12 *am/i
|
149
151
|
start_string = if opt[:time_filter][0].nil?
|
150
|
-
"#{item.date.strftime('%Y-%m-%d')}
|
152
|
+
"#{item.date.strftime('%Y-%m-%d')} 00:00"
|
151
153
|
else
|
152
154
|
"#{item.date.strftime('%Y-%m-%d')} #{opt[:time_filter][0]}"
|
153
155
|
end
|
154
156
|
start_time = start_string.chronify(guess: :begin)
|
155
157
|
|
156
158
|
end_string = if opt[:time_filter][1].nil?
|
157
|
-
"#{item.date.to_datetime.next_day.strftime('%Y-%m-%d')}
|
159
|
+
"#{item.date.to_datetime.next_day.strftime('%Y-%m-%d')} 00:00"
|
158
160
|
else
|
159
161
|
"#{item.date.strftime('%Y-%m-%d')} #{opt[:time_filter][1]}"
|
160
162
|
end
|
161
|
-
end_time = end_string.chronify(guess: :end)
|
163
|
+
end_time = end_string.chronify(guess: :end) || Time.now
|
162
164
|
|
163
165
|
in_time_range = item.date >= start_time && item.date <= end_time
|
166
|
+
|
164
167
|
keep = false unless in_time_range
|
165
168
|
keep = opt[:not] ? !keep : keep
|
166
169
|
end
|
data/lib/doing/wwid/wwid.rb
CHANGED
@@ -100,10 +100,28 @@ module Doing
|
|
100
100
|
##
|
101
101
|
## @param title [String] The title of the view to retrieve
|
102
102
|
##
|
103
|
-
def get_view(title)
|
104
|
-
|
103
|
+
def get_view(title, fallback: nil)
|
104
|
+
Doing.setting(['views', title], fallback)
|
105
|
+
end
|
106
|
+
|
107
|
+
def rename_view_keys(view)
|
108
|
+
options = view.symbolize_keys
|
109
|
+
# options.rename_key(:tags, :tag, keep: true)
|
110
|
+
options.rename_key(:output_format, :output)
|
111
|
+
options.rename_key(:tags_bool, :bool)
|
112
|
+
options.rename_key(:tag_sort, :sort_tags)
|
113
|
+
options.rename_key(:negate, :not)
|
114
|
+
options.rename_key(:order, :sort)
|
115
|
+
|
116
|
+
options
|
117
|
+
end
|
105
118
|
|
106
|
-
|
119
|
+
def view_to_options(title)
|
120
|
+
view = rename_view_keys(get_view(guess_view(title)))
|
121
|
+
view.deep_merge(rename_view_keys(get_view(guess_view(view[:parent]), fallback: {}))) if view.key?(:parent)
|
122
|
+
view.deep_merge(rename_view_keys(get_view(view[:config_template], fallback: {}))) if view.key?(:config_template)
|
123
|
+
view.deep_merge(Doing.setting('templates.default').symbolize_keys)
|
124
|
+
view
|
107
125
|
end
|
108
126
|
|
109
127
|
private
|
data/lib/doing.rb
CHANGED
@@ -85,6 +85,15 @@ module Doing
|
|
85
85
|
config.settings
|
86
86
|
end
|
87
87
|
|
88
|
+
def original_options
|
89
|
+
@original_options ||= {
|
90
|
+
date_begin: nil,
|
91
|
+
date_end: nil,
|
92
|
+
date_range: nil,
|
93
|
+
date_interval: nil
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
88
97
|
##
|
89
98
|
## Fetch a config setting using a dot-separated keypath
|
90
99
|
## or array of keys
|
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.45
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Terpstra
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-03-
|
11
|
+
date: 2022-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: github-markup
|
@@ -489,6 +489,7 @@ files:
|
|
489
489
|
- docs/doc/BooleanTermParser/QueryParser.html
|
490
490
|
- docs/doc/BooleanTermParser/QueryTransformer.html
|
491
491
|
- docs/doc/Doing.html
|
492
|
+
- docs/doc/Doing/ArrayCleanup.html
|
492
493
|
- docs/doc/Doing/ArrayNestedHash.html
|
493
494
|
- docs/doc/Doing/ArrayTags.html
|
494
495
|
- docs/doc/Doing/CLIFormat.html
|