doing 2.1.30 → 2.1.31pre
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/.irbrc +1 -0
- data/.yardoc/checksums +9 -8
- data/.yardoc/object_types +0 -0
- data/.yardoc/objects/root.dat +0 -0
- data/CHANGELOG.md +4923 -0
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/bin/commands/again.rb +1 -1
- data/bin/commands/archive.rb +3 -3
- data/bin/commands/cancel.rb +1 -1
- data/bin/commands/commands.rb +8 -8
- data/bin/commands/completion.rb +61 -19
- data/bin/commands/config.rb +9 -9
- data/bin/commands/done.rb +1 -1
- data/bin/commands/flag.rb +1 -1
- data/bin/commands/grep.rb +5 -5
- data/bin/commands/last.rb +1 -1
- data/bin/commands/meanwhile.rb +1 -1
- data/bin/commands/now.rb +1 -1
- data/bin/commands/on.rb +1 -1
- data/bin/commands/open.rb +1 -1
- data/bin/commands/recent.rb +4 -4
- data/bin/commands/show.rb +8 -8
- data/bin/commands/since.rb +1 -1
- data/bin/commands/today.rb +1 -1
- data/bin/commands/view.rb +3 -3
- data/bin/commands/yesterday.rb +2 -2
- data/bin/doing +22 -133
- data/docs/doc/Array.html +1 -1
- 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/Color.html +1 -1
- data/docs/doc/Doing/Completion.html +324 -4
- data/docs/doc/Doing/Configuration.html +1 -1
- 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/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/Hooks.html +1 -1
- data/docs/doc/Doing/Item.html +125 -1
- data/docs/doc/Doing/Items.html +1 -1
- data/docs/doc/Doing/LogAdapter.html +1 -1
- data/docs/doc/Doing/Note.html +109 -3
- 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/Section.html +1 -1
- data/docs/doc/Doing/TemplateString.html +1 -1
- data/docs/doc/Doing/Types.html +1 -1
- data/docs/doc/Doing/Util/Backup.html +1 -1
- data/docs/doc/Doing/Util.html +1 -1
- data/docs/doc/Doing/WWID.html +6 -6
- data/docs/doc/Doing.html +2 -2
- 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/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 +1 -1
- data/docs/doc/Symbol.html +1 -1
- data/docs/doc/Time.html +1 -1
- data/docs/doc/TrueClass.html +1 -1
- data/docs/doc/_index.html +3 -1
- data/docs/doc/file.README.html +2 -2
- data/docs/doc/index.html +2 -2
- data/docs/doc/method_list.html +337 -241
- data/docs/doc/top-level-namespace.html +105 -1
- data/doing.rdoc +25 -9
- data/example_plugin.rb +7 -5
- data/lib/completion/_doing.zsh +2 -2
- data/lib/completion/doing.bash +2 -2
- data/lib/completion/doing.fish +2 -3
- data/lib/doing/add_options.rb +117 -0
- data/lib/doing/array/array.rb +16 -0
- data/lib/doing/completion/bash_completion.rb +12 -51
- data/lib/doing/completion/fish_completion.rb +16 -52
- data/lib/doing/completion/zsh_completion.rb +12 -56
- data/lib/doing/completion.rb +203 -17
- data/lib/doing/item.rb +21 -3
- data/lib/doing/items.rb +5 -5
- data/lib/doing/note.rb +24 -8
- data/lib/doing/plugins/export/dayone_export.rb +8 -6
- data/lib/doing/plugins/export/html_export.rb +4 -4
- data/lib/doing/plugins/export/json_export.rb +19 -20
- data/lib/doing/plugins/export/markdown_export.rb +2 -2
- data/lib/doing/plugins/export/template_export.rb +4 -4
- 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/string/highlight.rb +3 -4
- data/lib/doing/string/string.rb +8 -0
- data/lib/doing/util.rb +1 -1
- data/lib/doing/util_backup.rb +12 -12
- data/lib/doing/version.rb +1 -1
- data/lib/doing/wwid.rb +76 -77
- data/lib/doing.rb +57 -0
- data/lib/examples/commands/wiki.rb +27 -19
- data/scripts/setting_replace.rb +11 -0
- metadata +6 -4
|
@@ -24,8 +24,8 @@ module Doing
|
|
|
24
24
|
|
|
25
25
|
out = ''
|
|
26
26
|
items.each do |item|
|
|
27
|
-
if opt[:highlight] && item.title =~ /@#{
|
|
28
|
-
flag = Doing::Color.send(
|
|
27
|
+
if opt[:highlight] && item.title =~ /@#{Doing.setting('marker_tag')}\b/i
|
|
28
|
+
flag = Doing::Color.send(Doing.setting('marker_color'))
|
|
29
29
|
reset = Doing::Color.reset + Doing::Color.default
|
|
30
30
|
else
|
|
31
31
|
flag = ''
|
|
@@ -34,7 +34,7 @@ module Doing
|
|
|
34
34
|
|
|
35
35
|
placeholders = {}
|
|
36
36
|
|
|
37
|
-
if !item.note.empty? &&
|
|
37
|
+
if !item.note.empty? && Doing.setting('include_notes')
|
|
38
38
|
note = item.note.map(&:strip).delete_if(&:empty?)
|
|
39
39
|
note.map! { |line| "#{line.sub(/^\t*/, '')} " }
|
|
40
40
|
|
|
@@ -133,7 +133,7 @@ module Doing
|
|
|
133
133
|
|
|
134
134
|
# Doing.logger.debug('Template Export:', "#{items.count} items output to template #{opt[:template]}")
|
|
135
135
|
if opt[:totals]
|
|
136
|
-
out += wwid.tag_times(format:
|
|
136
|
+
out += wwid.tag_times(format: Doing.setting('timer_format').to_sym,
|
|
137
137
|
sort_by: opt[:sort_tags],
|
|
138
138
|
sort_order: opt[:tag_order])
|
|
139
139
|
end
|
|
@@ -23,7 +23,7 @@ module Doing
|
|
|
23
23
|
limit_start = options[:start].to_i
|
|
24
24
|
limit_end = options[:end].to_i
|
|
25
25
|
|
|
26
|
-
section = options[:section] ||
|
|
26
|
+
section = options[:section] || Doing.setting('current_section')
|
|
27
27
|
options[:no_overlap] ||= false
|
|
28
28
|
options[:autotag] ||= wwid.auto_tag
|
|
29
29
|
|
|
@@ -63,7 +63,7 @@ module Doing
|
|
|
63
63
|
title.gsub!(/ +/, ' ')
|
|
64
64
|
title.strip!
|
|
65
65
|
section = options[:section] || item.section
|
|
66
|
-
section ||=
|
|
66
|
+
section ||= Doing.setting('current_section')
|
|
67
67
|
|
|
68
68
|
new_item = Item.new(item.date, title, section)
|
|
69
69
|
new_item.note = item.note
|
|
@@ -24,7 +24,7 @@ module Doing
|
|
|
24
24
|
##
|
|
25
25
|
def self.import(wwid, path, options: {})
|
|
26
26
|
exit_now! 'Path to JSON report required' if path.nil?
|
|
27
|
-
section = options[:section] ||
|
|
27
|
+
section = options[:section] || Doing.setting('current_section')
|
|
28
28
|
options[:no_overlap] ||= false
|
|
29
29
|
options[:autotag] ||= wwid.auto_tag
|
|
30
30
|
wwid.content.add_section(section) unless wwid.content.section?(section)
|
|
@@ -35,10 +35,9 @@ module Doing
|
|
|
35
35
|
|
|
36
36
|
def highlight_search(search, distance: nil, negate: false, case_type: nil)
|
|
37
37
|
out = dup
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
case_type ||= prefs.fetch('case', 'smart').normalize_case
|
|
38
|
+
matching = Doing.setting('search.matching', 'pattern').normalize_matching
|
|
39
|
+
distance ||= Doing.setting('search.distance', 3).to_i
|
|
40
|
+
case_type ||= Doing.setting('search.case', 'smart').normalize_case
|
|
42
41
|
|
|
43
42
|
if search.rx? || matching == :fuzzy
|
|
44
43
|
rx = search.to_rx(distance: distance, case_type: case_type)
|
data/lib/doing/string/string.rb
CHANGED
data/lib/doing/util.rb
CHANGED
|
@@ -159,7 +159,7 @@ module Doing
|
|
|
159
159
|
|
|
160
160
|
return ENV['EDITOR'] if ENV['DOING_EDITOR_TEST']
|
|
161
161
|
|
|
162
|
-
editor_config = Doing.
|
|
162
|
+
editor_config = Doing.setting('editors')
|
|
163
163
|
|
|
164
164
|
if editor_config.is_a?(String)
|
|
165
165
|
msg = "Please update your configuration, 'editors' should be a mapping."
|
data/lib/doing/util_backup.rb
CHANGED
|
@@ -30,7 +30,7 @@ module Doing
|
|
|
30
30
|
## @param limit Maximum number of backups to retain
|
|
31
31
|
##
|
|
32
32
|
def clear_redo(filename)
|
|
33
|
-
filename ||= Doing.
|
|
33
|
+
filename ||= Doing.setting('doing_file')
|
|
34
34
|
backups = Dir.glob("undone*___#{File.basename(filename)}", base: backup_dir).sort.reverse
|
|
35
35
|
backups.each do |file|
|
|
36
36
|
FileUtils.rm(File.join(backup_dir, file))
|
|
@@ -44,7 +44,7 @@ module Doing
|
|
|
44
44
|
## @return [String] filename
|
|
45
45
|
##
|
|
46
46
|
def last_backup(filename = nil, count: 1)
|
|
47
|
-
filename ||= Doing.
|
|
47
|
+
filename ||= Doing.setting('doing_file')
|
|
48
48
|
|
|
49
49
|
backup = get_backups(filename).slice(count - 1)
|
|
50
50
|
backup.nil? ? nil : File.join(backup_dir, backup)
|
|
@@ -59,7 +59,7 @@ module Doing
|
|
|
59
59
|
##
|
|
60
60
|
def restore_last_backup(filename = nil, count: 1)
|
|
61
61
|
Doing.logger.benchmark(:restore_backup, :start)
|
|
62
|
-
filename ||= Doing.
|
|
62
|
+
filename ||= Doing.setting('doing_file')
|
|
63
63
|
|
|
64
64
|
backup_file = last_backup(filename, count: count)
|
|
65
65
|
raise DoingRuntimeError, 'End of undo history' if backup_file.nil?
|
|
@@ -77,7 +77,7 @@ module Doing
|
|
|
77
77
|
## @param filename The filename
|
|
78
78
|
##
|
|
79
79
|
def redo_backup(filename = nil, count: 1)
|
|
80
|
-
filename ||= Doing.
|
|
80
|
+
filename ||= Doing.setting('doing_file')
|
|
81
81
|
# redo_file = File.join(backup_dir, "undone___#{File.basename(filename)}")
|
|
82
82
|
undones = Dir.glob("undone*#{File.basename(filename)}", base: backup_dir).sort.reverse
|
|
83
83
|
total = undones.count
|
|
@@ -101,7 +101,7 @@ module Doing
|
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
def clear_undone(filename = nil)
|
|
104
|
-
filename ||= Doing.
|
|
104
|
+
filename ||= Doing.setting('doing_file')
|
|
105
105
|
# redo_file = File.join(backup_dir, "undone___#{File.basename(filename)}")
|
|
106
106
|
Dir.glob("undone*#{File.basename(filename)}", base: backup_dir).each do |f|
|
|
107
107
|
FileUtils.rm(File.join(backup_dir, f))
|
|
@@ -115,7 +115,7 @@ module Doing
|
|
|
115
115
|
## @param filename The filename to restore
|
|
116
116
|
##
|
|
117
117
|
def select_redo(filename = nil)
|
|
118
|
-
filename ||= Doing.
|
|
118
|
+
filename ||= Doing.setting('doing_file')
|
|
119
119
|
|
|
120
120
|
undones = Dir.glob("undone*#{File.basename(filename)}", base: backup_dir).sort
|
|
121
121
|
|
|
@@ -155,7 +155,7 @@ module Doing
|
|
|
155
155
|
## @param filename The filename to restore
|
|
156
156
|
##
|
|
157
157
|
def select_backup(filename = nil)
|
|
158
|
-
filename ||= Doing.
|
|
158
|
+
filename ||= Doing.setting('doing_file')
|
|
159
159
|
|
|
160
160
|
options = get_backups(filename).each_with_object([]) do |file, arr|
|
|
161
161
|
d, _base = date_of_backup(file)
|
|
@@ -219,7 +219,7 @@ module Doing
|
|
|
219
219
|
##
|
|
220
220
|
def write_backup(filename = nil)
|
|
221
221
|
Doing.logger.benchmark(:_write_backup, :start)
|
|
222
|
-
filename ||= Doing.
|
|
222
|
+
filename ||= Doing.setting('doing_file')
|
|
223
223
|
|
|
224
224
|
unless File.exist?(filename)
|
|
225
225
|
Doing.logger.debug('Backup:', "original file doesn't exist (#{filename})")
|
|
@@ -234,7 +234,7 @@ module Doing
|
|
|
234
234
|
|
|
235
235
|
FileUtils.cp(filename, backup_file)
|
|
236
236
|
|
|
237
|
-
prune_backups(filename, Doing.
|
|
237
|
+
prune_backups(filename, Doing.setting('history_size').to_i)
|
|
238
238
|
clear_undone(filename)
|
|
239
239
|
Doing.logger.benchmark(:_write_backup, :finish)
|
|
240
240
|
end
|
|
@@ -246,13 +246,13 @@ module Doing
|
|
|
246
246
|
end
|
|
247
247
|
|
|
248
248
|
def get_backups(filename = nil, include_forward: false)
|
|
249
|
-
filename ||= Doing.
|
|
249
|
+
filename ||= Doing.setting('doing_file')
|
|
250
250
|
backups = Dir.glob("*___#{File.basename(filename)}", base: backup_dir).sort.reverse
|
|
251
251
|
backups.delete_if { |f| f =~ /^undone/ } unless include_forward
|
|
252
252
|
end
|
|
253
253
|
|
|
254
254
|
def save_undone(filename = nil)
|
|
255
|
-
filename ||= Doing.
|
|
255
|
+
filename ||= Doing.setting('doing_file')
|
|
256
256
|
undone_file = File.join(backup_dir, "undone#{timestamp_filename}___#{File.basename(filename)}")
|
|
257
257
|
FileUtils.cp(filename, undone_file)
|
|
258
258
|
end
|
|
@@ -279,7 +279,7 @@ module Doing
|
|
|
279
279
|
end
|
|
280
280
|
|
|
281
281
|
def create_backup_dir
|
|
282
|
-
dir = File.expand_path(Doing.
|
|
282
|
+
dir = File.expand_path(Doing.setting('backup_dir')) || File.join(user_home, '.doing_backup')
|
|
283
283
|
if File.exist?(dir) && !File.directory?(dir)
|
|
284
284
|
raise DoingRuntimeError, "Backup error: #{dir} is not a directory"
|
|
285
285
|
|
data/lib/doing/version.rb
CHANGED
data/lib/doing/wwid.rb
CHANGED
|
@@ -48,7 +48,7 @@ module Doing
|
|
|
48
48
|
## @param path [String] Override path to a doing file, optional
|
|
49
49
|
##
|
|
50
50
|
def init_doing_file(path = nil)
|
|
51
|
-
@doing_file = File.expand_path(
|
|
51
|
+
@doing_file = File.expand_path(Doing.setting('doing_file'))
|
|
52
52
|
|
|
53
53
|
if path.nil?
|
|
54
54
|
create(@doing_file) unless File.exist?(@doing_file)
|
|
@@ -77,7 +77,7 @@ module Doing
|
|
|
77
77
|
lines.each do |line|
|
|
78
78
|
next if line =~ /^\s*$/
|
|
79
79
|
|
|
80
|
-
if line =~ /^(\S[\S ]+)
|
|
80
|
+
if line =~ /^(\S[\S ]+):\s*(@\S+\s*)*$/
|
|
81
81
|
section = Regexp.last_match(1)
|
|
82
82
|
@content.add_section(Section.new(section, original: line), log: false)
|
|
83
83
|
elsif line =~ /^\s*- (\d{4}-\d\d-\d\d \d\d:\d\d) \| (.*)/
|
|
@@ -117,7 +117,7 @@ module Doing
|
|
|
117
117
|
FileUtils.mkdir_p(File.dirname(filename)) unless File.directory?(File.dirname(filename))
|
|
118
118
|
|
|
119
119
|
File.open(filename, 'w+') do |f|
|
|
120
|
-
f.puts "#{
|
|
120
|
+
f.puts "#{Doing.setting('current_section')}:"
|
|
121
121
|
end
|
|
122
122
|
end
|
|
123
123
|
|
|
@@ -189,7 +189,7 @@ module Doing
|
|
|
189
189
|
|
|
190
190
|
raise EmptyInput, 'No content' if title.sub(/^.*?\| */, '').strip.empty?
|
|
191
191
|
|
|
192
|
-
title.expand_date_tags(
|
|
192
|
+
title.expand_date_tags(Doing.setting('date_tags'))
|
|
193
193
|
|
|
194
194
|
if title =~ date_rx
|
|
195
195
|
m = title.match(date_rx)
|
|
@@ -236,7 +236,7 @@ module Doing
|
|
|
236
236
|
##
|
|
237
237
|
def guess_section(frag, guessed: false, suggest: false)
|
|
238
238
|
return 'All' if frag =~ /^all$/i
|
|
239
|
-
frag ||=
|
|
239
|
+
frag ||= Doing.setting('current_section')
|
|
240
240
|
|
|
241
241
|
return frag.cap_first if @content.section?(frag)
|
|
242
242
|
|
|
@@ -342,7 +342,7 @@ module Doing
|
|
|
342
342
|
##
|
|
343
343
|
def add_item(title, section = nil, opt)
|
|
344
344
|
opt ||= {}
|
|
345
|
-
section ||=
|
|
345
|
+
section ||= Doing.setting('current_section')
|
|
346
346
|
@content.add_section(section, log: false)
|
|
347
347
|
opt[:back] ||= opt[:date] ? opt[:date] : Time.now
|
|
348
348
|
opt[:date] ||= Time.now
|
|
@@ -356,7 +356,7 @@ module Doing
|
|
|
356
356
|
|
|
357
357
|
if @auto_tag
|
|
358
358
|
title = autotag(title)
|
|
359
|
-
title.add_tags!(
|
|
359
|
+
title.add_tags!(Doing.setting('default_tags')) if Doing.setting('default_tags').good?
|
|
360
360
|
end
|
|
361
361
|
|
|
362
362
|
title.compress!
|
|
@@ -553,7 +553,7 @@ module Doing
|
|
|
553
553
|
def last_entry(opt)
|
|
554
554
|
opt ||= {}
|
|
555
555
|
opt[:tag_bool] ||= :and
|
|
556
|
-
opt[:section] ||=
|
|
556
|
+
opt[:section] ||= Doing.setting('current_section')
|
|
557
557
|
|
|
558
558
|
items = filter_items(Items.new, opt: opt)
|
|
559
559
|
|
|
@@ -1076,7 +1076,7 @@ module Doing
|
|
|
1076
1076
|
end
|
|
1077
1077
|
|
|
1078
1078
|
if opt[:flag]
|
|
1079
|
-
tag =
|
|
1079
|
+
tag = Doing.setting('marker_tag', 'flagged')
|
|
1080
1080
|
items.map! do |i|
|
|
1081
1081
|
old_item = i.clone
|
|
1082
1082
|
i.tag(tag, date: false, remove: opt[:remove], single: single)
|
|
@@ -1117,7 +1117,7 @@ module Doing
|
|
|
1117
1117
|
items.map! do |i|
|
|
1118
1118
|
old_item = i.clone
|
|
1119
1119
|
i.tag(tag, date: false, remove: opt[:remove], single: single)
|
|
1120
|
-
i.expand_date_tags(
|
|
1120
|
+
i.expand_date_tags(Doing.setting('date_tags'))
|
|
1121
1121
|
Hooks.trigger :post_entry_updated, self, i, old_item
|
|
1122
1122
|
end
|
|
1123
1123
|
end
|
|
@@ -1176,7 +1176,7 @@ module Doing
|
|
|
1176
1176
|
end
|
|
1177
1177
|
|
|
1178
1178
|
def verify_duration(date, finish_date, title: nil)
|
|
1179
|
-
max_elapsed =
|
|
1179
|
+
max_elapsed = Doing.setting('interaction.confirm_longer_than', 0)
|
|
1180
1180
|
max_elapsed = max_elapsed.chronify_qty if max_elapsed.is_a?(String)
|
|
1181
1181
|
date = date.chronify(guess: :end, context: :today) if finish_date.is_a?(String)
|
|
1182
1182
|
|
|
@@ -1289,7 +1289,7 @@ module Doing
|
|
|
1289
1289
|
tag = tag.strip
|
|
1290
1290
|
|
|
1291
1291
|
if tag =~ /^done$/ && opt[:date] && item.should_time?
|
|
1292
|
-
max_elapsed =
|
|
1292
|
+
max_elapsed = Doing.setting('interaction.confirm_longer_than', 0)
|
|
1293
1293
|
max_elapsed = max_elapsed.chronify_qty if max_elapsed.is_a?(String)
|
|
1294
1294
|
elapsed = done_date - item.date
|
|
1295
1295
|
|
|
@@ -1344,7 +1344,7 @@ module Doing
|
|
|
1344
1344
|
logger.warn('Skipped:', 'Archiving is skipped when operating on all entries')
|
|
1345
1345
|
end
|
|
1346
1346
|
|
|
1347
|
-
item.expand_date_tags(
|
|
1347
|
+
item.expand_date_tags(Doing.setting('date_tags'))
|
|
1348
1348
|
Hooks.trigger :post_entry_updated, self, item, old_item
|
|
1349
1349
|
end
|
|
1350
1350
|
|
|
@@ -1424,7 +1424,7 @@ module Doing
|
|
|
1424
1424
|
def stop_start(target_tag, opt)
|
|
1425
1425
|
opt ||= {}
|
|
1426
1426
|
tag = target_tag.dup
|
|
1427
|
-
opt[:section] ||=
|
|
1427
|
+
opt[:section] ||= Doing.setting('current_section')
|
|
1428
1428
|
opt[:archive] ||= false
|
|
1429
1429
|
opt[:back] ||= Time.now
|
|
1430
1430
|
opt[:new_item] ||= false
|
|
@@ -1485,7 +1485,7 @@ module Doing
|
|
|
1485
1485
|
$stdout.puts output
|
|
1486
1486
|
else
|
|
1487
1487
|
Util.write_to_file(file, output, backup: backup)
|
|
1488
|
-
run_after if
|
|
1488
|
+
run_after if Doing.setting('run_after')
|
|
1489
1489
|
end
|
|
1490
1490
|
end
|
|
1491
1491
|
|
|
@@ -1593,7 +1593,7 @@ module Doing
|
|
|
1593
1593
|
## @return [Array] View names
|
|
1594
1594
|
##
|
|
1595
1595
|
def views
|
|
1596
|
-
|
|
1596
|
+
Doing.setting('views') ? Doing.setting('views').keys : []
|
|
1597
1597
|
end
|
|
1598
1598
|
|
|
1599
1599
|
##
|
|
@@ -1612,7 +1612,7 @@ module Doing
|
|
|
1612
1612
|
## @param title [String] The title of the view to retrieve
|
|
1613
1613
|
##
|
|
1614
1614
|
def get_view(title)
|
|
1615
|
-
return
|
|
1615
|
+
return Doing.setting(['views', title], nil)
|
|
1616
1616
|
|
|
1617
1617
|
false
|
|
1618
1618
|
end
|
|
@@ -1626,21 +1626,21 @@ module Doing
|
|
|
1626
1626
|
logger.benchmark(:list_section, :start)
|
|
1627
1627
|
opt[:config_template] ||= 'default'
|
|
1628
1628
|
|
|
1629
|
-
tpl_cfg =
|
|
1629
|
+
tpl_cfg = Doing.setting(['templates', opt[:config_template]])
|
|
1630
1630
|
|
|
1631
1631
|
cfg = if opt[:view_template]
|
|
1632
|
-
|
|
1632
|
+
Doing.setting(['views', opt[:view_template]]).deep_merge(tpl_cfg, { extend_existing_arrays: true, sort_merged_arrays: true })
|
|
1633
1633
|
else
|
|
1634
1634
|
tpl_cfg
|
|
1635
1635
|
end
|
|
1636
1636
|
|
|
1637
1637
|
cfg.deep_merge({
|
|
1638
|
-
'wrap_width' =>
|
|
1639
|
-
'date_format' =>
|
|
1640
|
-
'order' =>
|
|
1641
|
-
'tags_color' =>
|
|
1642
|
-
'duration' =>
|
|
1643
|
-
'interval_format' =>
|
|
1638
|
+
'wrap_width' => Doing.setting('wrap_width') || 0,
|
|
1639
|
+
'date_format' => Doing.setting('default_date_format'),
|
|
1640
|
+
'order' => Doing.setting('order') || :asc,
|
|
1641
|
+
'tags_color' => Doing.setting('tags_color'),
|
|
1642
|
+
'duration' => Doing.setting('duration'),
|
|
1643
|
+
'interval_format' => Doing.setting('interval_format')
|
|
1644
1644
|
}, { extend_existing_arrays: true, sort_merged_arrays: true })
|
|
1645
1645
|
|
|
1646
1646
|
opt[:duration] ||= cfg['duration'] || false
|
|
@@ -1697,7 +1697,7 @@ module Doing
|
|
|
1697
1697
|
end
|
|
1698
1698
|
|
|
1699
1699
|
opt[:output] ||= 'template'
|
|
1700
|
-
opt[:wrap_width] ||=
|
|
1700
|
+
opt[:wrap_width] ||= Doing.setting('templates.default.wrap_width', 0)
|
|
1701
1701
|
|
|
1702
1702
|
logger.benchmark(:list_section, :finish)
|
|
1703
1703
|
output(items, title, is_single, opt)
|
|
@@ -1710,7 +1710,7 @@ module Doing
|
|
|
1710
1710
|
## @param section [String] The source section
|
|
1711
1711
|
## @param options [Hash] Options
|
|
1712
1712
|
##
|
|
1713
|
-
def archive(section =
|
|
1713
|
+
def archive(section = Doing.setting('current_section'), options)
|
|
1714
1714
|
options ||= {}
|
|
1715
1715
|
count = options[:keep] || 0
|
|
1716
1716
|
destination = options[:destination] || 'Archive'
|
|
@@ -1746,13 +1746,13 @@ module Doing
|
|
|
1746
1746
|
opt[:totals] ||= false
|
|
1747
1747
|
opt[:sort_tags] ||= false
|
|
1748
1748
|
|
|
1749
|
-
cfg =
|
|
1750
|
-
'wrap_width' =>
|
|
1751
|
-
'date_format' =>
|
|
1752
|
-
'order' =>
|
|
1753
|
-
'tags_color' =>
|
|
1754
|
-
'duration' =>
|
|
1755
|
-
'interval_format' =>
|
|
1749
|
+
cfg = Doing.setting('templates').deep_merge(Doing.setting('templates.default'), { extend_existing_arrays: true, sort_merged_arrays: true }).deep_merge({
|
|
1750
|
+
'wrap_width' => Doing.setting('wrap_width') || 0,
|
|
1751
|
+
'date_format' => Doing.setting('default_date_format'),
|
|
1752
|
+
'order' => Doing.setting('order') || :asc,
|
|
1753
|
+
'tags_color' => Doing.setting('tags_color'),
|
|
1754
|
+
'duration' => Doing.setting('duration'),
|
|
1755
|
+
'interval_format' => Doing.setting('interval_format')
|
|
1756
1756
|
}, { extend_existing_arrays: true, sort_merged_arrays: true })
|
|
1757
1757
|
|
|
1758
1758
|
template = opt[:template] || cfg['template']
|
|
@@ -1866,18 +1866,18 @@ module Doing
|
|
|
1866
1866
|
opt[:totals] ||= false
|
|
1867
1867
|
opt[:sort_tags] ||= false
|
|
1868
1868
|
|
|
1869
|
-
cfg =
|
|
1870
|
-
'wrap_width' =>
|
|
1871
|
-
'date_format' =>
|
|
1872
|
-
'order' =>
|
|
1873
|
-
'tags_color' =>
|
|
1874
|
-
'duration' =>
|
|
1875
|
-
'interval_format' =>
|
|
1869
|
+
cfg = Doing.setting('templates.recent').deep_merge(Doing.setting('templates.default'), { extend_existing_arrays: true, sort_merged_arrays: true }).deep_merge({
|
|
1870
|
+
'wrap_width' => Doing.setting('wrap_width') || 0,
|
|
1871
|
+
'date_format' => Doing.setting('default_date_format'),
|
|
1872
|
+
'order' => Doing.setting('order') || :asc,
|
|
1873
|
+
'tags_color' => Doing.setting('tags_color'),
|
|
1874
|
+
'duration' => Doing.setting('duration'),
|
|
1875
|
+
'interval_format' => Doing.setting('interval_format')
|
|
1876
1876
|
}, { extend_existing_arrays: true, sort_merged_arrays: true })
|
|
1877
1877
|
opt[:duration] ||= cfg['duration'] || false
|
|
1878
1878
|
opt[:interval_format] ||= cfg['interval_format'] || 'text'
|
|
1879
1879
|
|
|
1880
|
-
section ||=
|
|
1880
|
+
section ||= Doing.setting('current_section')
|
|
1881
1881
|
section = guess_section(section)
|
|
1882
1882
|
|
|
1883
1883
|
opt[:section] = section
|
|
@@ -1899,13 +1899,13 @@ module Doing
|
|
|
1899
1899
|
##
|
|
1900
1900
|
def last(times: true, section: nil, options: {})
|
|
1901
1901
|
section = section.nil? || section =~ /all/i ? 'All' : guess_section(section)
|
|
1902
|
-
cfg =
|
|
1903
|
-
'wrap_width' =>
|
|
1904
|
-
'date_format' =>
|
|
1905
|
-
'order' =>
|
|
1906
|
-
'tags_color' =>
|
|
1907
|
-
'duration' =>
|
|
1908
|
-
'interval_format' =>
|
|
1902
|
+
cfg = Doing.setting(['templates', options[:config_template]]).deep_merge(Doing.setting('templates.default'), { extend_existing_arrays: true, sort_merged_arrays: true }).deep_merge({
|
|
1903
|
+
'wrap_width' => Doing.setting('wrap_width', 0),
|
|
1904
|
+
'date_format' => Doing.setting('default_date_format'),
|
|
1905
|
+
'order' => Doing.setting('order', :asc),
|
|
1906
|
+
'tags_color' => Doing.setting('tags_color'),
|
|
1907
|
+
'duration' => Doing.setting('duration'),
|
|
1908
|
+
'interval_format' => Doing.setting('interval_format')
|
|
1909
1909
|
}, { extend_existing_arrays: true, sort_merged_arrays: true })
|
|
1910
1910
|
options[:duration] ||= cfg['duration'] || false
|
|
1911
1911
|
options[:interval_format] ||= cfg['interval_format'] || 'text'
|
|
@@ -1960,7 +1960,7 @@ module Doing
|
|
|
1960
1960
|
replaced: []
|
|
1961
1961
|
}
|
|
1962
1962
|
|
|
1963
|
-
|
|
1963
|
+
Doing.setting('autotag.whitelist').each do |tag|
|
|
1964
1964
|
next if text =~ /@#{tag}\b/i
|
|
1965
1965
|
|
|
1966
1966
|
text.sub!(/(?<= |\A)(#{tag.strip})(?= |\Z)/i) do |m|
|
|
@@ -1970,7 +1970,7 @@ module Doing
|
|
|
1970
1970
|
end
|
|
1971
1971
|
end
|
|
1972
1972
|
|
|
1973
|
-
|
|
1973
|
+
Doing.setting('autotag.synonyms').each do |tag, v|
|
|
1974
1974
|
v.each do |word|
|
|
1975
1975
|
word = word.wildcard_to_rx
|
|
1976
1976
|
next unless text =~ /\b#{word}\b/i
|
|
@@ -1982,8 +1982,8 @@ module Doing
|
|
|
1982
1982
|
end
|
|
1983
1983
|
end
|
|
1984
1984
|
|
|
1985
|
-
if
|
|
1986
|
-
|
|
1985
|
+
if Doing.setting('autotag.transform')
|
|
1986
|
+
Doing.setting('autotag.transform').each do |tag|
|
|
1987
1987
|
next unless tag =~ /\S+:\S+/
|
|
1988
1988
|
|
|
1989
1989
|
if tag =~ /::/
|
|
@@ -2055,11 +2055,11 @@ module Doing
|
|
|
2055
2055
|
def tag_times(format: :text, sort_by: :time, sort_order: :asc)
|
|
2056
2056
|
return '' if @timers.empty?
|
|
2057
2057
|
|
|
2058
|
-
max = @timers.keys.sort_by
|
|
2058
|
+
max = @timers.keys.sort_by(&:length).reverse[0].length + 1
|
|
2059
2059
|
|
|
2060
2060
|
total = @timers.delete('All')
|
|
2061
2061
|
|
|
2062
|
-
tags_data = @timers.delete_if { |_k, v| v
|
|
2062
|
+
tags_data = @timers.delete_if { |_k, v| v.zero? }
|
|
2063
2063
|
sorted_tags_data = if sort_by.normalize_tag_sort == :name
|
|
2064
2064
|
tags_data.sort_by { |k, _v| k }
|
|
2065
2065
|
else
|
|
@@ -2070,7 +2070,7 @@ module Doing
|
|
|
2070
2070
|
case format
|
|
2071
2071
|
when :html
|
|
2072
2072
|
|
|
2073
|
-
output = <<
|
|
2073
|
+
output = <<EOHEAD
|
|
2074
2074
|
<table>
|
|
2075
2075
|
<caption id="tagtotals">Tag Totals</caption>
|
|
2076
2076
|
<colgroup>
|
|
@@ -2084,13 +2084,13 @@ module Doing
|
|
|
2084
2084
|
</tr>
|
|
2085
2085
|
</thead>
|
|
2086
2086
|
<tbody>
|
|
2087
|
-
|
|
2087
|
+
EOHEAD
|
|
2088
2088
|
sorted_tags_data.reverse.each do |k, v|
|
|
2089
|
-
if v
|
|
2089
|
+
if v.positive?
|
|
2090
2090
|
output += "<tr><td style='text-align:left;'>#{k}</td><td style='text-align:left;'>#{v.time_string(format: :clock)}</td></tr>\n"
|
|
2091
2091
|
end
|
|
2092
2092
|
end
|
|
2093
|
-
tail = <<
|
|
2093
|
+
tail = <<EOTAIL
|
|
2094
2094
|
<tr>
|
|
2095
2095
|
<td style="text-align:left;" colspan="2"></td>
|
|
2096
2096
|
</tr>
|
|
@@ -2102,21 +2102,21 @@ EOS
|
|
|
2102
2102
|
</tr>
|
|
2103
2103
|
</tfoot>
|
|
2104
2104
|
</table>
|
|
2105
|
-
|
|
2105
|
+
EOTAIL
|
|
2106
2106
|
output + tail
|
|
2107
2107
|
when :markdown
|
|
2108
|
-
pad = sorted_tags_data.map {|k,
|
|
2108
|
+
pad = sorted_tags_data.map { |k, _| k }.group_by(&:size).max.last[0].length
|
|
2109
2109
|
pad = 7 if pad < 7
|
|
2110
|
-
output = <<~
|
|
2111
|
-
| #{' ' * (pad - 7)
|
|
2110
|
+
output = <<~EOHEADER
|
|
2111
|
+
| #{' ' * (pad - 7)}project | time |
|
|
2112
2112
|
| #{'-' * (pad - 1)}: | :------- |
|
|
2113
|
-
|
|
2113
|
+
EOHEADER
|
|
2114
2114
|
sorted_tags_data.reverse.each do |k, v|
|
|
2115
|
-
if v
|
|
2115
|
+
if v.positive?
|
|
2116
2116
|
output += "| #{' ' * (pad - k.length)}#{k} | #{v.time_string(format: :clock)} |\n"
|
|
2117
2117
|
end
|
|
2118
2118
|
end
|
|
2119
|
-
tail =
|
|
2119
|
+
tail = '[Tag Totals]'
|
|
2120
2120
|
output + tail
|
|
2121
2121
|
when :json
|
|
2122
2122
|
output = []
|
|
@@ -2203,38 +2203,37 @@ EOS
|
|
|
2203
2203
|
end
|
|
2204
2204
|
|
|
2205
2205
|
##
|
|
2206
|
-
## Load configuration files and updated the @
|
|
2206
|
+
## Load configuration files and updated the @settings
|
|
2207
2207
|
## attribute with a Doing::Configuration object
|
|
2208
2208
|
##
|
|
2209
2209
|
## @param filename [String] (optional) path to
|
|
2210
2210
|
## alternative config file
|
|
2211
2211
|
##
|
|
2212
2212
|
def configure(filename = nil)
|
|
2213
|
+
logger.benchmark(:configure, :start)
|
|
2214
|
+
|
|
2213
2215
|
if filename
|
|
2214
2216
|
Doing.config_with(filename, { ignore_local: true })
|
|
2215
2217
|
elsif ENV['DOING_CONFIG']
|
|
2216
2218
|
Doing.config_with(ENV['DOING_CONFIG'], { ignore_local: true })
|
|
2217
2219
|
end
|
|
2218
2220
|
|
|
2219
|
-
logger.benchmark(:configure, :start)
|
|
2220
|
-
config = Doing.config
|
|
2221
2221
|
logger.benchmark(:configure, :finish)
|
|
2222
2222
|
|
|
2223
|
-
|
|
2224
|
-
@config = config.settings
|
|
2223
|
+
Doing.set('backup_dir', ENV['DOING_BACKUP_DIR']) if ENV['DOING_BACKUP_DIR']
|
|
2225
2224
|
end
|
|
2226
2225
|
|
|
2227
2226
|
def get_diff(filename = nil)
|
|
2228
|
-
configure if
|
|
2227
|
+
configure if Doing.settings.nil?
|
|
2229
2228
|
|
|
2230
|
-
filename ||=
|
|
2229
|
+
filename ||= Doing.setting('doing_file')
|
|
2231
2230
|
init_doing_file(filename)
|
|
2232
2231
|
current_content = @content.clone
|
|
2233
2232
|
backup_file = Util::Backup.last_backup(filename, count: 1)
|
|
2234
2233
|
raise DoingRuntimeError, 'No undo history to diff' if backup_file.nil?
|
|
2235
2234
|
|
|
2236
2235
|
backup = WWID.new
|
|
2237
|
-
backup.config =
|
|
2236
|
+
backup.config = Doing.settings
|
|
2238
2237
|
backup.init_doing_file(backup_file)
|
|
2239
2238
|
current_content.diff(backup.content)
|
|
2240
2239
|
end
|
|
@@ -2378,12 +2377,12 @@ EOS
|
|
|
2378
2377
|
end
|
|
2379
2378
|
|
|
2380
2379
|
def run_after
|
|
2381
|
-
return unless
|
|
2380
|
+
return unless Doing.setting('run_after')
|
|
2382
2381
|
|
|
2383
|
-
_, stderr, status = Open3.capture3(
|
|
2382
|
+
_, stderr, status = Open3.capture3(Doing.setting('run_after'))
|
|
2384
2383
|
return unless status.exitstatus.positive?
|
|
2385
2384
|
|
|
2386
|
-
logger.log_now(:error, 'Script error:', "Error running #{
|
|
2385
|
+
logger.log_now(:error, 'Script error:', "Error running #{Doing.setting('run_after')}")
|
|
2387
2386
|
logger.log_now(:error, 'STDERR output:', stderr)
|
|
2388
2387
|
end
|
|
2389
2388
|
end
|