doing 2.1.26 → 2.1.30
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardoc/checksums +15 -20
- data/.yardoc/object_types +0 -0
- data/.yardoc/objects/root.dat +0 -0
- data/CHANGELOG.md +52 -0
- data/Dockerfile +5 -5
- data/Dockerfile-2.6 +5 -5
- data/Dockerfile-2.7 +5 -4
- data/Dockerfile-3.0 +5 -4
- data/Gemfile.lock +2 -1
- data/README.md +1 -1
- data/Rakefile +2 -3
- data/bin/commands/add_section.rb +2 -0
- data/bin/commands/again.rb +23 -65
- data/bin/commands/archive.rb +20 -61
- data/bin/commands/cancel.rb +27 -69
- data/bin/commands/changes.rb +53 -12
- data/bin/commands/colors.rb +4 -2
- data/bin/commands/commands.rb +4 -2
- data/bin/commands/commands_accepting.rb +62 -11
- data/bin/commands/completion.rb +10 -7
- data/bin/commands/config.rb +8 -8
- data/bin/commands/done.rb +3 -17
- data/bin/commands/finish.rb +7 -30
- data/bin/commands/flag.rb +15 -51
- data/bin/commands/grep.rb +12 -28
- data/bin/commands/import.rb +3 -33
- data/bin/commands/last.rb +3 -36
- data/bin/commands/meanwhile.rb +3 -13
- data/bin/commands/note.rb +13 -52
- data/bin/commands/now.rb +15 -21
- data/bin/commands/on.rb +3 -4
- data/bin/commands/open.rb +3 -3
- data/bin/commands/recent.rb +3 -4
- data/bin/commands/redo.rb +6 -2
- data/bin/commands/reset.rb +19 -52
- data/bin/commands/rotate.rb +5 -36
- data/bin/commands/select.rb +23 -41
- data/bin/commands/show.rb +28 -74
- data/bin/commands/since.rb +3 -4
- data/bin/commands/tag.rb +4 -34
- data/bin/commands/tags.rb +5 -32
- data/bin/commands/today.rb +3 -4
- data/bin/commands/view.rb +36 -73
- data/bin/commands/yesterday.rb +4 -5
- data/bin/doing +150 -13
- data/docs/doc/Array.html +3 -502
- 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 +62 -56
- data/docs/doc/Doing/Completion.html +1 -1
- data/docs/doc/Doing/Configuration.html +35 -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 +1 -1
- data/docs/doc/Doing/Items.html +2 -2
- data/docs/doc/Doing/LogAdapter.html +1 -1
- data/docs/doc/Doing/Note.html +2 -2
- 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 +2 -2
- data/docs/doc/Doing/Types.html +41 -1
- data/docs/doc/Doing/Util/Backup.html +1 -1
- data/docs/doc/Doing/Util.html +1 -1
- data/docs/doc/Doing/WWID.html +10 -10
- data/docs/doc/Doing.html +3 -3
- data/docs/doc/FalseClass.html +35 -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 +287 -3155
- data/docs/doc/Symbol.html +40 -6
- data/docs/doc/Time.html +1 -1
- data/docs/doc/TrueClass.html +35 -1
- data/docs/doc/_index.html +5 -10
- 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 +278 -678
- data/docs/doc/top-level-namespace.html +2 -2
- data/doing.gemspec +1 -0
- data/doing.rdoc +297 -206
- data/lib/completion/_doing.zsh +32 -32
- data/lib/completion/doing.bash +30 -30
- data/lib/completion/doing.fish +87 -77
- data/lib/doing/array/array.rb +4 -0
- data/lib/doing/array/nested_hash.rb +17 -0
- data/lib/doing/{array.rb → array/tags.rb} +7 -25
- data/lib/doing/changelog/change.rb +26 -11
- data/lib/doing/changelog/changes.rb +37 -8
- data/lib/doing/changelog/version.rb +11 -3
- data/lib/doing/{array_chronify.rb → chronify/array.rb} +0 -0
- data/lib/doing/chronify/chronify.rb +5 -0
- data/lib/doing/{numeric_chronify.rb → chronify/numeric.rb} +0 -0
- data/lib/doing/{string_chronify.rb → chronify/string.rb} +0 -0
- data/lib/doing/colors.rb +115 -54
- data/lib/doing/completion/zsh_completion.rb +5 -0
- data/lib/doing/configuration.rb +9 -5
- data/lib/doing/good.rb +8 -0
- data/lib/doing/help_monkey_patch.rb +6 -5
- data/lib/doing/item.rb +5 -5
- data/lib/doing/items.rb +2 -2
- data/lib/doing/log_adapter.rb +35 -2
- data/lib/doing/normalize.rb +188 -0
- data/lib/doing/plugins/export/dayone_export.rb +1 -1
- data/lib/doing/plugins/export/html_export.rb +1 -1
- data/lib/doing/plugins/export/json_export.rb +1 -1
- data/lib/doing/plugins/export/markdown_export.rb +1 -1
- data/lib/doing/plugins/export/template_export.rb +3 -1
- data/lib/doing/prompt.rb +1 -3
- data/lib/doing/section.rb +1 -1
- data/lib/doing/string/highlight.rb +95 -0
- data/lib/doing/string/query.rb +129 -0
- data/lib/doing/string/string.rb +12 -0
- data/lib/doing/string/tags.rb +164 -0
- data/lib/doing/string/transform.rb +168 -0
- data/lib/doing/string/truncate.rb +75 -0
- data/lib/doing/string/url.rb +82 -0
- data/lib/doing/template_string.rb +0 -22
- data/lib/doing/types.rb +8 -0
- data/lib/doing/util.rb +13 -9
- data/lib/doing/version.rb +1 -1
- data/lib/doing/wwid.rb +54 -36
- data/lib/doing.rb +5 -6
- data/lib/examples/plugins/wiki_export/wiki_export.rb +1 -1
- data/lib/helpers/threaded_tests.rb +15 -2
- data/scripts/deploy.rb +107 -0
- data/scripts/runtests.sh +4 -0
- metadata +39 -8
- data/lib/doing/string.rb +0 -765
- data/lib/doing/symbol.rb +0 -28
data/bin/commands/changes.rb
CHANGED
@@ -1,4 +1,21 @@
|
|
1
1
|
# @@changelog @@changes
|
2
|
+
|
3
|
+
MARKDOWN_THEME = {
|
4
|
+
em: %i[white dark],
|
5
|
+
header: %i[cyan bold],
|
6
|
+
hr: :yellow,
|
7
|
+
link: %i[bright_cyan underline],
|
8
|
+
list: :yellow,
|
9
|
+
strong: %i[yellow bold],
|
10
|
+
table: :yellow,
|
11
|
+
quote: :yellow,
|
12
|
+
image: :bright_black,
|
13
|
+
note: :yellow,
|
14
|
+
comment: :bright_black
|
15
|
+
}.deep_freeze
|
16
|
+
|
17
|
+
CHANGE_RX = /^(?:(?:(?:[<>=]+|p(?:rior)|b(?:efore)|o(?:lder)|s(?:ince)|a(?:fter)|n(?:ewer))? *[0-9.*?]+ *)+|(?:[\d.]+ *(?:-|to)+ *[0-9.]+))$/
|
18
|
+
|
2
19
|
desc 'List recent changes in Doing'
|
3
20
|
long_desc %(Display a formatted list of changes in recent versions.
|
4
21
|
|
@@ -10,14 +27,30 @@ command %i[changes changelog] do |c|
|
|
10
27
|
|
11
28
|
c.desc %(Look up a specific version. Specify versions as "MAJ.MIN.PATCH", MIN
|
12
29
|
and PATCH are optional. Use > or < to see all changes since or prior
|
13
|
-
to a version.)
|
30
|
+
to a version. Wildcards (*?) accepted unless using < or >.)
|
14
31
|
c.arg_name 'VERSION'
|
15
|
-
c.flag %i[l lookup], must_match:
|
32
|
+
c.flag %i[l lookup], must_match: CHANGE_RX
|
16
33
|
|
17
34
|
c.desc %(Show changelogs matching search terms (uses pattern-based searching).
|
18
35
|
Add slashes to search with regular expressions, e.g. `--search "/output.*flag/"`)
|
19
36
|
c.flag %i[s search]
|
20
37
|
|
38
|
+
c.desc 'Sort order (asc/desc)'
|
39
|
+
c.arg_name 'ORDER'
|
40
|
+
c.flag %i[sort], must_match: REGEX_SORT_ORDER, default_value: :desc, type: OrderSymbol
|
41
|
+
|
42
|
+
c.desc 'Only output changes, no version numbers, headers, or dates'
|
43
|
+
c.switch %i[C changes], default_value: false, negatable: false
|
44
|
+
|
45
|
+
c.desc 'Output raw Markdown'
|
46
|
+
c.switch %i[m md markdown], default_value: false, negatable: false
|
47
|
+
|
48
|
+
c.desc 'Force rendered output'
|
49
|
+
c.switch %i[render], default_value: false, negatable: false
|
50
|
+
|
51
|
+
c.desc 'Open changelog in interactive viewer'
|
52
|
+
c.switch %i[i interactive], default_value: false, negatable: false
|
53
|
+
|
21
54
|
c.example 'doing changes', desc: 'View changes in the current version'
|
22
55
|
c.example 'doing changes --all', desc: 'See the entire changelog'
|
23
56
|
c.example 'doing changes --lookup 2.0.21', desc: 'See changes from version 2.0.21'
|
@@ -25,18 +58,26 @@ command %i[changes changelog] do |c|
|
|
25
58
|
c.example 'doing changes --search "tags +bool"', desc: 'See all changes containing "tags" and "bool"'
|
26
59
|
c.example 'doing changes -l "> 2.1" -s "pattern"', desc: 'Lookup and search can be combined'
|
27
60
|
|
61
|
+
c.action do |_global_options, options, _args|
|
62
|
+
cl = Doing::Changes.new(lookup: options[:lookup], search: options[:search], changes: options[:changes], sort: options[:sort])
|
28
63
|
|
29
|
-
|
30
|
-
|
64
|
+
if options[:interactive]
|
65
|
+
cl.interactive
|
66
|
+
else
|
67
|
+
content = if options[:all] || options[:search] || options[:lookup]
|
68
|
+
cl.to_s
|
69
|
+
else
|
70
|
+
cl.latest
|
71
|
+
end
|
31
72
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
73
|
+
parsed = if (options[:markdown] || !$stdout.isatty) && !options[:render]
|
74
|
+
content
|
75
|
+
else
|
76
|
+
TTY::Markdown.parse(content, width: 80, theme: MARKDOWN_THEME, symbols: { override: { bullet: '•' } })
|
77
|
+
end
|
37
78
|
|
38
|
-
|
39
|
-
|
40
|
-
|
79
|
+
Doing::Pager.paginate = true
|
80
|
+
Doing::Pager.page parsed
|
81
|
+
end
|
41
82
|
end
|
42
83
|
end
|
data/bin/commands/colors.rb
CHANGED
@@ -5,10 +5,12 @@ command :colors do |c|
|
|
5
5
|
bgs = []
|
6
6
|
fgs = []
|
7
7
|
@colors::attributes.each do |color|
|
8
|
+
colname = color.to_s
|
9
|
+
colname << " (#{color.to_s.sub(/bold/, 'bright')})" if colname =~ /bold/
|
8
10
|
if color.to_s =~ /bg/
|
9
|
-
bgs.push("#{@colors.send(color, " ")}#{@colors.default} <-- #{
|
11
|
+
bgs.push("#{@colors.send(color, " ")}#{@colors.default} <-- #{colname}")
|
10
12
|
else
|
11
|
-
fgs.push("#{@colors.send(color, "XXXX")}#{@colors.default} <-- #{
|
13
|
+
fgs.push("#{@colors.send(color, "XXXX")}#{@colors.default} <-- #{colname}")
|
12
14
|
end
|
13
15
|
end
|
14
16
|
out = []
|
data/bin/commands/commands.rb
CHANGED
@@ -27,9 +27,11 @@ command :commands do |c|
|
|
27
27
|
Doing::Prompt.choose_from(available,
|
28
28
|
prompt: 'Select commands to enable',
|
29
29
|
multiple: true,
|
30
|
-
sorted: true)
|
30
|
+
sorted: true)
|
31
31
|
end
|
32
|
-
|
32
|
+
raise UserCancelled unless to_enable
|
33
|
+
|
34
|
+
to_enable.strip.split("\n").each do |cmd|
|
33
35
|
default_command = File.join(File.dirname(__FILE__), "#{cmd}.rb")
|
34
36
|
custom_command = File.join(File.expand_path(custom_dir), "#{cmd}.rb")
|
35
37
|
unless File.exist?(default_command) || File.exist?(custom_command)
|
@@ -1,25 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# @@commands_accepting
|
2
4
|
arg_name 'OPTION'
|
3
5
|
command :commands_accepting do |c|
|
4
6
|
c.desc 'Output in single column for completion'
|
5
7
|
c.switch %i[c column]
|
6
8
|
|
9
|
+
c.desc 'Join multiple arguments using boolean (AND|OR|NOT)'
|
10
|
+
c.flag [:bool], must_match: REGEX_BOOL,
|
11
|
+
default_value: :and,
|
12
|
+
type: BooleanSymbol
|
13
|
+
|
7
14
|
c.action do |g, o, a|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
+
cmds = []
|
16
|
+
commands.each { |cmd, v| cmds.push(cmd) if has_flags?(v, a, o[:bool]) }
|
17
|
+
|
18
|
+
if o[:column]
|
19
|
+
puts cmds.sort
|
20
|
+
else
|
21
|
+
description = "Commands "
|
22
|
+
description += "not " if o[:bool] == :not
|
23
|
+
description += "accepting "
|
24
|
+
description += a.map { |arg| "--#{arg}" }.join(o[:bool] == :and ? ' and ' : ' or ')
|
25
|
+
puts "#{description}: #{cmds.sort.join(', ')}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def has_flags?(options, args, bool)
|
30
|
+
case bool
|
31
|
+
when :and
|
32
|
+
all_flags?(options, args)
|
33
|
+
when :not
|
34
|
+
no_flags?(options, args)
|
35
|
+
else
|
36
|
+
any_flags?(options, args)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def all_flags?(options, args)
|
41
|
+
args.each do |arg|
|
42
|
+
has_flag = false
|
43
|
+
options.flags.merge(options.switches).each do |_, flag|
|
44
|
+
if flag.name == arg.to_sym || flag.aliases&.include?(arg.to_sym)
|
45
|
+
has_flag = true
|
46
|
+
break
|
15
47
|
end
|
16
48
|
end
|
49
|
+
return false unless has_flag
|
50
|
+
end
|
51
|
+
|
52
|
+
true
|
53
|
+
end
|
54
|
+
|
55
|
+
def any_flags?(options, args)
|
56
|
+
args.each do |option|
|
57
|
+
options.flags.merge(options.switches).each do |_, flag|
|
58
|
+
return true if flag.name == option.to_sym || flag.aliases&.include?(option.to_sym)
|
59
|
+
end
|
60
|
+
end
|
17
61
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
62
|
+
false
|
63
|
+
end
|
64
|
+
|
65
|
+
def no_flags?(options, args)
|
66
|
+
args.each do |option|
|
67
|
+
options.flags.merge(options.switches).each do |_, flag|
|
68
|
+
return false if flag.name == option.to_sym || flag.aliases&.include?(option.to_sym)
|
22
69
|
end
|
23
70
|
end
|
71
|
+
|
72
|
+
true
|
24
73
|
end
|
25
74
|
end
|
75
|
+
|
76
|
+
|
data/bin/commands/completion.rb
CHANGED
@@ -1,12 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# @@completion
|
2
4
|
desc 'Generate shell completion scripts'
|
3
|
-
long_desc 'Generates the necessary scripts to add command line completion to various shells,
|
4
|
-
tab will offer completions of subcommands and their options.'
|
5
|
+
long_desc 'Generates the necessary scripts to add command line completion to various shells,
|
6
|
+
so typing \'doing\' and hitting tab will offer completions of subcommands and their options.'
|
5
7
|
command :completion do |c|
|
6
8
|
c.example 'doing completion', desc: 'Output zsh (default) to STDOUT'
|
7
|
-
c.example 'doing completion --type zsh --file ~/.zsh-completions/_doing.zsh',
|
8
|
-
|
9
|
-
c.example 'doing completion --type
|
9
|
+
c.example 'doing completion --type zsh --file ~/.zsh-completions/_doing.zsh',
|
10
|
+
desc: 'Output zsh completions to file'
|
11
|
+
c.example 'doing completion --type fish --file ~/.config/fish/completions/doing.fish',
|
12
|
+
desc: 'Output fish completions to file'
|
13
|
+
c.example 'doing completion --type bash --file ~/.bash_it/completion/enabled/doing.bash',
|
14
|
+
desc: 'Output bash completions to file'
|
10
15
|
|
11
16
|
c.desc 'Shell to generate for (bash, zsh, fish)'
|
12
17
|
c.arg_name 'SHELL'
|
@@ -17,8 +22,6 @@ command :completion do |c|
|
|
17
22
|
c.flag %i[f file], default_value: 'STDOUT'
|
18
23
|
|
19
24
|
c.action do |_global_options, options, _args|
|
20
|
-
script_dir = File.join(File.dirname(__FILE__), '..', 'scripts')
|
21
|
-
|
22
25
|
Doing::Completion.generate_completion(type: options[:type], file: options[:file])
|
23
26
|
end
|
24
27
|
end
|
data/bin/commands/config.rb
CHANGED
@@ -45,7 +45,7 @@ command :config do |c|
|
|
45
45
|
edit.arg_name 'EDITOR'
|
46
46
|
edit.flag %i[e editor], default_value: nil
|
47
47
|
|
48
|
-
if
|
48
|
+
if Sys::Platform.mac?
|
49
49
|
edit.desc 'Application to use'
|
50
50
|
edit.arg_name 'APP_NAME'
|
51
51
|
edit.flag %i[a app]
|
@@ -76,7 +76,7 @@ command :config do |c|
|
|
76
76
|
|
77
77
|
config_file = @config.choose_config
|
78
78
|
|
79
|
-
if
|
79
|
+
if Sys::Platform.mac?
|
80
80
|
if options[:default]
|
81
81
|
editor = Doing::Util.find_default_editor('config')
|
82
82
|
if editor
|
@@ -139,7 +139,7 @@ command :config do |c|
|
|
139
139
|
dump.example 'doing config get', desc: 'Output the entire configuration'
|
140
140
|
dump.example 'doing config get timer_format --output raw', desc: 'Output the value of timer_format as a plain string'
|
141
141
|
dump.example 'doing config get doing_file', desc: 'Output the value of the doing_file setting, respecting local configurations'
|
142
|
-
dump.example 'doing config get -o json plug.plugpath', desc: 'Key path is fuzzy matched: output the value of plugins
|
142
|
+
dump.example 'doing config get -o json plug.plugpath', desc: 'Key path is fuzzy matched: output the value of plugins.plugin_path as JSON'
|
143
143
|
|
144
144
|
dump.desc 'Format for output (json|yaml|raw)'
|
145
145
|
dump.arg_name 'FORMAT'
|
@@ -188,7 +188,7 @@ command :config do |c|
|
|
188
188
|
c.arg 'KEY VALUE'
|
189
189
|
c.command :set do |set|
|
190
190
|
set.example 'doing config set timer_format human', desc: 'Set the value of timer_format to "human"'
|
191
|
-
set.example 'doing config set plug.plugpath ~/my_plugins', desc: 'Key path is fuzzy matched: set the value of plugins
|
191
|
+
set.example 'doing config set plug.plugpath ~/my_plugins', desc: 'Key path is fuzzy matched: set the value of plugins.plugin_path'
|
192
192
|
|
193
193
|
set.desc 'Delete specified key'
|
194
194
|
set.switch %i[r remove], default_value: false, negatable: false
|
@@ -206,7 +206,7 @@ command :config do |c|
|
|
206
206
|
old_type = old_value&.class.to_s || nil
|
207
207
|
|
208
208
|
if old_value.is_a?(Hash) && !options[:remove]
|
209
|
-
Doing.logger.log_now(:warn, 'Config:', "Config key must point to a single value, #{real_path.join('
|
209
|
+
Doing.logger.log_now(:warn, 'Config:', "Config key must point to a single value, #{real_path.join('.').boldwhite} is a mapping")
|
210
210
|
didyou = 'Did you mean:'
|
211
211
|
old_value.keys.each do |k|
|
212
212
|
Doing.logger.log_now(:warn, "#{didyou}", "#{keypath}.#{k}?")
|
@@ -218,17 +218,17 @@ command :config do |c|
|
|
218
218
|
|
219
219
|
config_file = @config.choose_config(create: true)
|
220
220
|
|
221
|
-
cfg =
|
221
|
+
cfg = Doing::Util.safe_load_file(config_file) || {}
|
222
222
|
|
223
223
|
$stderr.puts "Updating #{config_file}".yellow
|
224
224
|
|
225
225
|
if options[:remove]
|
226
226
|
cfg.deep_set(real_path, nil)
|
227
|
-
$stderr.puts "#{'Deleting key:'.yellow} #{real_path.join('
|
227
|
+
$stderr.puts "#{'Deleting key:'.yellow} #{real_path.join('.').boldwhite}"
|
228
228
|
else
|
229
229
|
current_value = cfg.dig(*real_path)
|
230
230
|
cfg.deep_set(real_path, value.set_type(old_type))
|
231
|
-
$stderr.puts "#{' Key path:'.yellow} #{real_path.join('
|
231
|
+
$stderr.puts "#{' Key path:'.yellow} #{real_path.join('.').boldwhite}"
|
232
232
|
$stderr.puts "#{'Inherited:'.yellow} #{(old_value ? old_value.to_s : 'empty').boldwhite}"
|
233
233
|
$stderr.puts "#{' Current:'.yellow} #{ (current_value ? current_value.to_s : 'empty').boldwhite }"
|
234
234
|
$stderr.puts "#{' New:'.yellow} #{value.set_type(old_type).to_s.boldwhite}"
|
data/bin/commands/done.rb
CHANGED
@@ -24,10 +24,6 @@ command %i[done did] do |c|
|
|
24
24
|
c.arg_name 'DATE_STRING'
|
25
25
|
c.flag %i[at finished], type: DateEndString
|
26
26
|
|
27
|
-
c.desc 'Backdate start date by interval or set to time [4pm|20m|2h|"yesterday noon"]'
|
28
|
-
c.arg_name 'DATE_STRING'
|
29
|
-
c.flag %i[b back started], type: DateBeginString
|
30
|
-
|
31
27
|
c.desc %(
|
32
28
|
Start and end times as a date/time range `doing done --from "1am to 8am"`.
|
33
29
|
Overrides other date flags.
|
@@ -45,24 +41,14 @@ command %i[done did] do |c|
|
|
45
41
|
c.arg_name 'NAME'
|
46
42
|
c.flag %i[s section]
|
47
43
|
|
48
|
-
c.desc "Edit entry with #{Doing::Util.default_editor} (with no arguments, edits the last entry)"
|
49
|
-
c.switch %i[e editor], negatable: false, default_value: false
|
50
|
-
|
51
|
-
c.desc 'Include a note'
|
52
|
-
c.arg_name 'TEXT'
|
53
|
-
c.flag %i[n note]
|
54
|
-
|
55
|
-
c.desc 'Prompt for note via multi-line input'
|
56
|
-
c.switch %i[ask], negatable: false, default_value: false
|
57
|
-
|
58
44
|
c.desc 'Finish last entry not already marked @done'
|
59
45
|
c.switch %i[u unfinished], negatable: false, default_value: false
|
60
46
|
|
61
|
-
|
62
|
-
# c.arg_name 'editor_app'
|
63
|
-
# # c.flag [:a, :app]
|
47
|
+
add_options(:add_entry, c)
|
64
48
|
|
65
49
|
c.action do |_global_options, options, args|
|
50
|
+
@wwid.auto_tag = !options[:noauto]
|
51
|
+
|
66
52
|
took = 0
|
67
53
|
donedate = nil
|
68
54
|
|
data/bin/commands/finish.rb
CHANGED
@@ -22,37 +22,10 @@ command :finish do |c|
|
|
22
22
|
c.arg_name 'DATE_STRING'
|
23
23
|
c.flag %i[at finished], type: DateEndString
|
24
24
|
|
25
|
-
c.desc '
|
26
|
-
|
27
|
-
c.arg_name 'TAG'
|
28
|
-
c.flag [:tag], type: TagArray
|
25
|
+
c.desc 'Overwrite existing @done tag with new date'
|
26
|
+
c.switch %i[update], negatable: false, default_value: false
|
29
27
|
|
30
|
-
c.desc '
|
31
|
-
c.arg_name 'QUERY'
|
32
|
-
c.flag [:search]
|
33
|
-
|
34
|
-
c.desc 'Perform a tag value query ("@done > two hours ago" or "@progress < 50"). May be used multiple times, combined with --bool'
|
35
|
-
c.arg_name 'QUERY'
|
36
|
-
c.flag [:val], multiple: true, must_match: REGEX_VALUE_QUERY
|
37
|
-
|
38
|
-
# c.desc '[DEPRECATED] Use alternative fuzzy matching for search string'
|
39
|
-
# c.switch [:fuzzy], default_value: false, negatable: false
|
40
|
-
|
41
|
-
c.desc 'Force exact search string matching (case sensitive)'
|
42
|
-
c.switch %i[x exact], default_value: @config.exact_match?, negatable: @config.exact_match?
|
43
|
-
|
44
|
-
c.desc 'Finish items that *don\'t* match search/tag filters'
|
45
|
-
c.switch [:not], default_value: false, negatable: false
|
46
|
-
|
47
|
-
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
48
|
-
c.arg_name 'TYPE'
|
49
|
-
c.flag [:case], must_match: /^[csi]/, default_value: @settings.dig('search', 'case')
|
50
|
-
|
51
|
-
c.desc 'Boolean (AND|OR|NOT) with which to combine multiple tag filters. Use PATTERN to parse + and - as booleans'
|
52
|
-
c.arg_name 'BOOLEAN'
|
53
|
-
c.flag [:bool], must_match: REGEX_BOOL, default_value: 'PATTERN'
|
54
|
-
|
55
|
-
c.desc 'Remove done tag'
|
28
|
+
c.desc 'Remove @done tag'
|
56
29
|
c.switch %i[r remove], negatable: false, default_value: false
|
57
30
|
|
58
31
|
c.desc 'Finish last entry (or entries) not already marked @done'
|
@@ -73,6 +46,9 @@ command :finish do |c|
|
|
73
46
|
c.desc 'Select item(s) to finish from a menu of matching entries'
|
74
47
|
c.switch %i[i interactive], negatable: false, default_value: false
|
75
48
|
|
49
|
+
add_options(:search, c)
|
50
|
+
add_options(:tag_filter, c)
|
51
|
+
|
76
52
|
c.action do |_global_options, options, args|
|
77
53
|
options[:fuzzy] = false
|
78
54
|
unless options[:auto]
|
@@ -141,6 +117,7 @@ command :finish do |c|
|
|
141
117
|
tags: ['done'],
|
142
118
|
took: options[:took],
|
143
119
|
unfinished: options[:unfinished],
|
120
|
+
update: options[:update],
|
144
121
|
val: options[:val]
|
145
122
|
}
|
146
123
|
|
data/bin/commands/flag.rb
CHANGED
@@ -26,39 +26,12 @@ command %i[mark flag] do |c|
|
|
26
26
|
c.desc 'Flag last entry (or entries) not marked @done'
|
27
27
|
c.switch %i[u unfinished], negatable: false, default_value: false
|
28
28
|
|
29
|
-
c.desc 'Flag the last entry containing TAG.
|
30
|
-
Separate multiple tags with comma (--tag=tag1,tag2), combine with --bool. Wildcards allowed (*, ?).'
|
31
|
-
c.arg_name 'TAG'
|
32
|
-
c.flag [:tag], type: TagArray
|
33
|
-
|
34
|
-
c.desc 'Flag the last entry matching search filter, surround with slashes for regex (e.g. "/query.*/"), start with single quote for exact match ("\'query")'
|
35
|
-
c.arg_name 'QUERY'
|
36
|
-
c.flag [:search]
|
37
|
-
|
38
|
-
c.desc 'Perform a tag value query ("@done > two hours ago" or "@progress < 50"). May be used multiple times, combined with --bool'
|
39
|
-
c.arg_name 'QUERY'
|
40
|
-
c.flag [:val], multiple: true, must_match: REGEX_VALUE_QUERY
|
41
|
-
|
42
|
-
# c.desc '[DEPRECATED] Use alternative fuzzy matching for search string'
|
43
|
-
# c.switch [:fuzzy], default_value: false, negatable: false
|
44
|
-
|
45
|
-
c.desc 'Force exact search string matching (case sensitive)'
|
46
|
-
c.switch %i[x exact], default_value: @config.exact_match?, negatable: @config.exact_match?
|
47
|
-
|
48
|
-
c.desc 'Flag items that *don\'t* match search/tag/date filters'
|
49
|
-
c.switch [:not], default_value: false, negatable: false
|
50
|
-
|
51
|
-
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
52
|
-
c.arg_name 'TYPE'
|
53
|
-
c.flag [:case], must_match: /^[csi]/, default_value: @settings.dig('search', 'case')
|
54
|
-
|
55
|
-
c.desc 'Boolean (AND|OR|NOT) with which to combine multiple tag filters. Use PATTERN to parse + and - as booleans'
|
56
|
-
c.arg_name 'BOOLEAN'
|
57
|
-
c.flag [:bool], must_match: REGEX_BOOL, default_value: 'PATTERN'
|
58
|
-
|
59
29
|
c.desc 'Select item(s) to flag from a menu of matching entries'
|
60
30
|
c.switch %i[i interactive], negatable: false, default_value: false
|
61
31
|
|
32
|
+
add_options(:search, c)
|
33
|
+
add_options(:tag_filter, c)
|
34
|
+
|
62
35
|
c.action do |_global_options, options, _args|
|
63
36
|
options[:fuzzy] = false
|
64
37
|
mark = @settings['marker_tag'] || 'flagged'
|
@@ -67,15 +40,9 @@ command %i[mark flag] do |c|
|
|
67
40
|
|
68
41
|
section = 'All'
|
69
42
|
|
70
|
-
if options[:section]
|
71
|
-
section = @wwid.guess_section(options[:section]) || options[:section].cap_first
|
72
|
-
end
|
43
|
+
section = @wwid.guess_section(options[:section]) || options[:section].cap_first if options[:section]
|
73
44
|
|
74
|
-
|
75
|
-
search_tags = []
|
76
|
-
else
|
77
|
-
search_tags = options[:tag]
|
78
|
-
end
|
45
|
+
search_tags = options[:tag].nil? ? [] : options[:tag]
|
79
46
|
|
80
47
|
if options[:interactive]
|
81
48
|
count = 0
|
@@ -84,8 +51,6 @@ command %i[mark flag] do |c|
|
|
84
51
|
count = options[:count].to_i
|
85
52
|
end
|
86
53
|
|
87
|
-
options[:case] = options[:case].normalize_case
|
88
|
-
|
89
54
|
if options[:search]
|
90
55
|
search = options[:search]
|
91
56
|
search.sub!(/^'?/, "'") if options[:exact]
|
@@ -93,16 +58,15 @@ command %i[mark flag] do |c|
|
|
93
58
|
end
|
94
59
|
|
95
60
|
if count.zero? && !options[:force]
|
96
|
-
if options[:search]
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
61
|
+
section_q = if options[:search]
|
62
|
+
' matching your search terms'
|
63
|
+
elsif options[:tag]
|
64
|
+
' matching your tag search'
|
65
|
+
elsif section == 'All'
|
66
|
+
''
|
67
|
+
else
|
68
|
+
" in section #{section}"
|
69
|
+
end
|
106
70
|
|
107
71
|
question = if options[:remove]
|
108
72
|
"Are you sure you want to unflag all entries#{section_q}"
|
@@ -119,7 +83,7 @@ command %i[mark flag] do |c|
|
|
119
83
|
options[:section] = section
|
120
84
|
options[:tag] = search_tags
|
121
85
|
options[:tags] = [mark]
|
122
|
-
options[:tag_bool] = options[:bool]
|
86
|
+
options[:tag_bool] = options[:bool]
|
123
87
|
|
124
88
|
@wwid.tag_last(options)
|
125
89
|
end
|
data/bin/commands/grep.rb
CHANGED
@@ -16,25 +16,6 @@ command %i[grep search] do |c|
|
|
16
16
|
c.arg_name 'NAME'
|
17
17
|
c.flag %i[s section], default_value: 'All'
|
18
18
|
|
19
|
-
c.desc 'Search entries older than date. If this is only a time (8am, 1:30pm, 15:00), all dates will be included, but entries will be filtered by time of day'
|
20
|
-
c.arg_name 'DATE_STRING'
|
21
|
-
c.flag [:before], type: DateBeginString
|
22
|
-
|
23
|
-
c.desc 'Search entries newer than date. If this is only a time (8am, 1:30pm, 15:00), all dates will be included, but entries will be filtered by time of day'
|
24
|
-
c.arg_name 'DATE_STRING'
|
25
|
-
c.flag [:after], type: DateEndString
|
26
|
-
|
27
|
-
c.desc %(
|
28
|
-
Date range to show, or a single day to filter date on.
|
29
|
-
Date range argument should be quoted. Date specifications can be natural language.
|
30
|
-
To specify a range, use "to" or "through": `doing search --from "monday 8am to friday 5pm"`.
|
31
|
-
|
32
|
-
If values are only time(s) (6am to noon) all dates will be included, but entries will be filtered
|
33
|
-
by time of day.
|
34
|
-
)
|
35
|
-
c.arg_name 'DATE_OR_RANGE'
|
36
|
-
c.flag [:from], type: DateRangeString
|
37
|
-
|
38
19
|
c.desc "Output to export format (#{Doing::Plugins.plugin_names(type: :export)})"
|
39
20
|
c.arg_name 'FORMAT'
|
40
21
|
c.flag %i[o output]
|
@@ -57,10 +38,9 @@ command %i[grep search] do |c|
|
|
57
38
|
c.switch [:totals], default_value: false, negatable: false
|
58
39
|
|
59
40
|
c.desc 'Sort tags by (name|time)'
|
60
|
-
default = '
|
61
|
-
default = @settings['tag_sort'] || 'name'
|
41
|
+
default = @settings['tag_sort'].normalize_tag_sort || :name
|
62
42
|
c.arg_name 'KEY'
|
63
|
-
c.flag [:tag_sort], must_match:
|
43
|
+
c.flag [:tag_sort], must_match: REGEX_TAG_SORT, default_value: default, type: TagSortSymbol
|
64
44
|
|
65
45
|
c.desc 'Only show items with recorded time intervals'
|
66
46
|
c.switch [:only_timed], default_value: false, negatable: false
|
@@ -76,7 +56,9 @@ command %i[grep search] do |c|
|
|
76
56
|
|
77
57
|
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
78
58
|
c.arg_name 'TYPE'
|
79
|
-
c.flag [:case], must_match:
|
59
|
+
c.flag [:case], must_match: REGEX_CASE,
|
60
|
+
default_value: @settings.dig('search', 'case').normalize_case,
|
61
|
+
type: CaseSymbol
|
80
62
|
|
81
63
|
c.desc "Highlight search matches in output. Only affects command line output"
|
82
64
|
c.switch %i[h hilite], default_value: @settings.dig('search', 'highlight')
|
@@ -95,7 +77,12 @@ command %i[grep search] do |c|
|
|
95
77
|
c.flag [:val], multiple: true, must_match: REGEX_VALUE_QUERY
|
96
78
|
|
97
79
|
c.desc 'Combine multiple tags or value queries using AND, OR, or NOT'
|
98
|
-
c.
|
80
|
+
c.arg_name 'BOOLEAN'
|
81
|
+
c.flag [:bool], must_match: REGEX_BOOL,
|
82
|
+
default_value: :pattern,
|
83
|
+
type: BooleanSymbol
|
84
|
+
|
85
|
+
add_options(:date_filter, c)
|
99
86
|
|
100
87
|
c.action do |_global_options, options, args|
|
101
88
|
options[:fuzzy] = false
|
@@ -106,14 +93,11 @@ command %i[grep search] do |c|
|
|
106
93
|
|
107
94
|
section = @wwid.guess_section(options[:section]) if options[:section]
|
108
95
|
|
109
|
-
options[:case] = options[:case].normalize_case
|
110
|
-
options[:bool] = options[:bool].normalize_bool
|
111
|
-
|
112
96
|
search = args.join(' ')
|
113
97
|
search.sub!(/^'?/, "'") if options[:exact]
|
114
98
|
|
115
99
|
options[:times] = true if options[:totals]
|
116
|
-
options[:sort_tags] = options[:tag_sort]
|
100
|
+
options[:sort_tags] = options[:tag_sort]
|
117
101
|
options[:highlight] = true
|
118
102
|
options[:search] = search
|
119
103
|
options[:section] = section
|
data/bin/commands/import.rb
CHANGED
@@ -11,23 +11,9 @@ command :import do |c|
|
|
11
11
|
c.arg_name 'TYPE'
|
12
12
|
c.flag :type, default_value: 'doing'
|
13
13
|
|
14
|
-
c.desc 'Only import items matching search. Surround with slashes for regex (/query/), start with single quote for exact match ("\'query")'
|
15
|
-
c.arg_name 'QUERY'
|
16
|
-
c.flag [:search]
|
17
|
-
|
18
|
-
# c.desc '[DEPRECATED] Use alternative fuzzy matching for search string'
|
19
|
-
# c.switch [:fuzzy], default_value: false, negatable: false
|
20
|
-
|
21
|
-
c.desc 'Force exact search string matching (case sensitive)'
|
22
|
-
c.switch %i[x exact], default_value: @config.exact_match?, negatable: @config.exact_match?
|
23
|
-
|
24
14
|
c.desc 'Import items that *don\'t* match search/tag/date filters'
|
25
15
|
c.switch [:not], default_value: false, negatable: false
|
26
16
|
|
27
|
-
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
28
|
-
c.arg_name 'TYPE'
|
29
|
-
c.flag [:case], must_match: /^[csi]/, default_value: @settings.dig('search', 'case')
|
30
|
-
|
31
17
|
c.desc 'Only import items with recorded time intervals'
|
32
18
|
c.switch [:only_timed], default_value: false, negatable: false
|
33
19
|
|
@@ -46,26 +32,12 @@ command :import do |c|
|
|
46
32
|
c.arg_name 'PREFIX'
|
47
33
|
c.flag :prefix
|
48
34
|
|
49
|
-
# TODO: Allow time range filtering
|
50
|
-
c.desc 'Import entries older than date'
|
51
|
-
c.arg_name 'DATE_STRING'
|
52
|
-
c.flag [:before], type: DateBeginString
|
53
|
-
|
54
|
-
c.desc 'Import entries newer than date'
|
55
|
-
c.arg_name 'DATE_STRING'
|
56
|
-
c.flag [:after], type: DateEndString
|
57
|
-
|
58
|
-
c.desc %(
|
59
|
-
Date range to import. Date range argument should be quoted. Date specifications can be natural language.
|
60
|
-
To specify a range, use "to" or "through": `--from "monday to friday"` or `--from 10/1 to 10/31`.
|
61
|
-
Has no effect unless the import plugin has implemented date range filtering.
|
62
|
-
)
|
63
|
-
c.arg_name 'DATE_OR_RANGE'
|
64
|
-
c.flag %i[f from], type: DateRangeString
|
65
|
-
|
66
35
|
c.desc 'Allow entries that overlap existing times'
|
67
36
|
c.switch [:overlap], negatable: true
|
68
37
|
|
38
|
+
add_options(:search, c)
|
39
|
+
add_options(:date_filter, c)
|
40
|
+
|
69
41
|
c.action do |_global_options, options, args|
|
70
42
|
options[:fuzzy] = false
|
71
43
|
if options[:section]
|
@@ -88,8 +60,6 @@ command :import do |c|
|
|
88
60
|
options[:date_filter][0] = options[:after] || Time.now - (1 << 64)
|
89
61
|
end
|
90
62
|
|
91
|
-
options[:case] = options[:case].normalize_case
|
92
|
-
|
93
63
|
if options[:type] =~ Doing::Plugins.plugin_regex(type: :import)
|
94
64
|
options[:no_overlap] = !options[:overlap]
|
95
65
|
@wwid.import(args, options)
|