doing 2.1.26 → 2.1.30
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/.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/last.rb
CHANGED
|
@@ -21,18 +21,6 @@ command :last do |c|
|
|
|
21
21
|
c.desc "Delete the last entry"
|
|
22
22
|
c.switch %i[d delete], negatable: false, default_value: false
|
|
23
23
|
|
|
24
|
-
c.desc 'Tag filter, combine multiple tags with a comma. Wildcards allowed (*, ?)'
|
|
25
|
-
c.arg_name 'TAG'
|
|
26
|
-
c.flag [:tag], type: TagArray
|
|
27
|
-
|
|
28
|
-
c.desc 'Tag boolean (AND|OR|NOT). Use PATTERN to parse + and - as booleans'
|
|
29
|
-
c.arg_name 'BOOLEAN'
|
|
30
|
-
c.flag [:bool], must_match: REGEX_BOOL, default_value: 'PATTERN'
|
|
31
|
-
|
|
32
|
-
c.desc 'Search filter, surround with slashes for regex (/query/), start with single quote for exact match ("\'query")'
|
|
33
|
-
c.arg_name 'QUERY'
|
|
34
|
-
c.flag [:search]
|
|
35
|
-
|
|
36
24
|
c.desc "Output using a template from configuration"
|
|
37
25
|
c.arg_name 'TEMPLATE_KEY'
|
|
38
26
|
c.flag [:config_template], type: TemplateName, default_value: 'last'
|
|
@@ -44,38 +32,17 @@ command :last do |c|
|
|
|
44
32
|
c.desc "Highlight search matches in output. Only affects command line output"
|
|
45
33
|
c.switch %i[h hilite], default_value: @settings.dig('search', 'highlight')
|
|
46
34
|
|
|
47
|
-
c.desc 'Perform a tag value query ("@done > two hours ago" or "@progress < 50"). May be used multiple times, combined with --bool'
|
|
48
|
-
c.arg_name 'QUERY'
|
|
49
|
-
c.flag [:val], multiple: true, must_match: REGEX_VALUE_QUERY
|
|
50
|
-
|
|
51
35
|
c.desc 'Show elapsed time if entry is not tagged @done'
|
|
52
36
|
c.switch [:duration]
|
|
53
37
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
c.desc 'Force exact search string matching (case sensitive)'
|
|
58
|
-
c.switch %i[x exact], default_value: @config.exact_match?, negatable: @config.exact_match?
|
|
59
|
-
|
|
60
|
-
c.desc 'Show items that *don\'t* match search string or tag filter'
|
|
61
|
-
c.switch [:not], default_value: false, negatable: false
|
|
62
|
-
|
|
63
|
-
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
|
64
|
-
c.arg_name 'TYPE'
|
|
65
|
-
c.flag [:case], must_match: /^[csi]/, default_value: @settings.dig('search', 'case')
|
|
38
|
+
add_options(:search, c)
|
|
39
|
+
add_options(:tag_filter, c)
|
|
66
40
|
|
|
67
41
|
c.action do |global_options, options, _args|
|
|
68
42
|
options[:fuzzy] = false
|
|
69
43
|
raise InvalidArgument, '--tag and --search can not be used together' if options[:tag] && options[:search]
|
|
70
44
|
|
|
71
|
-
|
|
72
|
-
options[:tag] = []
|
|
73
|
-
else
|
|
74
|
-
options[:tag] = options[:tag]
|
|
75
|
-
options[:bool] = options[:bool].normalize_bool
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
options[:case] = options[:case].normalize_case
|
|
45
|
+
options[:tag] ||= []
|
|
79
46
|
|
|
80
47
|
options[:search] = options[:search].sub(/^'?/, "'") if options[:search] && options[:exact]
|
|
81
48
|
|
data/bin/commands/meanwhile.rb
CHANGED
|
@@ -15,24 +15,14 @@ command :meanwhile do |c|
|
|
|
15
15
|
c.arg_name 'NAME'
|
|
16
16
|
c.flag %i[s section]
|
|
17
17
|
|
|
18
|
-
c.desc "Edit entry with #{Doing::Util.default_editor}"
|
|
19
|
-
c.switch %i[e editor], negatable: false, default_value: false
|
|
20
|
-
|
|
21
18
|
c.desc 'Archive previous @meanwhile entry'
|
|
22
19
|
c.switch %i[a archive], negatable: false, default_value: false
|
|
23
20
|
|
|
24
|
-
c
|
|
25
|
-
c.arg_name 'DATE_STRING'
|
|
26
|
-
c.flag %i[b back started], type: DateBeginString
|
|
27
|
-
|
|
28
|
-
c.desc 'Note'
|
|
29
|
-
c.arg_name 'TEXT'
|
|
30
|
-
c.flag %i[n note]
|
|
31
|
-
|
|
32
|
-
c.desc 'Prompt for note via multi-line input'
|
|
33
|
-
c.switch %i[ask], negatable: false, default_value: false
|
|
21
|
+
add_options(:add_entry, c)
|
|
34
22
|
|
|
35
23
|
c.action do |_global_options, options, args|
|
|
24
|
+
@wwid.auto_tag = !options[:noauto]
|
|
25
|
+
|
|
36
26
|
if options[:back]
|
|
37
27
|
date = options[:back]
|
|
38
28
|
|
data/bin/commands/note.rb
CHANGED
|
@@ -24,50 +24,19 @@ command :note do |c|
|
|
|
24
24
|
c.desc "Replace/Remove last entry's note (default append)"
|
|
25
25
|
c.switch %i[r remove], negatable: false, default_value: false
|
|
26
26
|
|
|
27
|
-
c.desc 'Add/remove note from last entry matching tag. Wildcards allowed (*, ?)'
|
|
28
|
-
c.arg_name 'TAG'
|
|
29
|
-
c.flag [:tag], type: TagArray
|
|
30
|
-
|
|
31
|
-
c.desc 'Add/remove note from last entry matching search filter, surround with slashes for regex (e.g. "/query.*/"), start with single quote for exact match ("\'query")'
|
|
32
|
-
c.arg_name 'QUERY'
|
|
33
|
-
c.flag [:search]
|
|
34
|
-
|
|
35
|
-
c.desc 'Perform a tag value query ("@done > two hours ago" or "@progress < 50"). May be used multiple times, combined with --bool'
|
|
36
|
-
c.arg_name 'QUERY'
|
|
37
|
-
c.flag [:val], multiple: true, must_match: REGEX_VALUE_QUERY
|
|
38
|
-
|
|
39
|
-
# c.desc '[DEPRECATED] Use alternative fuzzy matching for search string'
|
|
40
|
-
# c.switch [:fuzzy], default_value: false, negatable: false
|
|
41
|
-
|
|
42
|
-
c.desc 'Force exact search string matching (case sensitive)'
|
|
43
|
-
c.switch %i[x exact], default_value: @config.exact_match?, negatable: @config.exact_match?
|
|
44
|
-
|
|
45
|
-
c.desc 'Add note to item that *doesn\'t* match search/tag filters'
|
|
46
|
-
c.switch [:not], default_value: false, negatable: false
|
|
47
|
-
|
|
48
|
-
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
|
49
|
-
c.arg_name 'TYPE'
|
|
50
|
-
c.flag [:case], must_match: /^[csi]/, default_value: @settings.dig('search', 'case')
|
|
51
|
-
|
|
52
|
-
c.desc 'Boolean (AND|OR|NOT) with which to combine multiple tag filters. Use PATTERN to parse + and - as booleans'
|
|
53
|
-
c.arg_name 'BOOLEAN'
|
|
54
|
-
c.flag [:bool], must_match: REGEX_BOOL, default_value: 'PATTERN'
|
|
55
|
-
|
|
56
27
|
c.desc 'Select item for new note from a menu of matching entries'
|
|
57
28
|
c.switch %i[i interactive], negatable: false, default_value: false
|
|
58
29
|
|
|
59
30
|
c.desc 'Prompt for note via multi-line input'
|
|
60
31
|
c.switch %i[ask], negatable: false, default_value: false
|
|
61
32
|
|
|
33
|
+
add_options(:search, c)
|
|
34
|
+
add_options(:tag_filter, c)
|
|
35
|
+
|
|
62
36
|
c.action do |_global_options, options, args|
|
|
63
37
|
options[:fuzzy] = false
|
|
64
|
-
if options[:section]
|
|
65
|
-
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
options[:tag_bool] = options[:bool].normalize_bool
|
|
69
|
-
|
|
70
|
-
options[:case] = options[:case].normalize_case
|
|
38
|
+
options[:section] = @wwid.guess_section(options[:section]) || options[:section].cap_first if options[:section]
|
|
39
|
+
options[:tag_bool] = options[:bool]
|
|
71
40
|
|
|
72
41
|
if options[:search]
|
|
73
42
|
search = options[:search]
|
|
@@ -78,30 +47,22 @@ command :note do |c|
|
|
|
78
47
|
last_entry = @wwid.last_entry(options)
|
|
79
48
|
old_entry = last_entry.clone
|
|
80
49
|
|
|
81
|
-
unless last_entry
|
|
82
|
-
Doing.logger.warn('Not found:', 'No entry matching parameters was found.')
|
|
83
|
-
return
|
|
84
|
-
end
|
|
50
|
+
raise NoResults, 'No entry matching parameters was found.' unless last_entry
|
|
85
51
|
|
|
86
52
|
last_note = last_entry.note || Doing::Note.new
|
|
87
53
|
new_note = Doing::Note.new
|
|
88
54
|
|
|
89
|
-
if $stdin.stat.size.positive?
|
|
90
|
-
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
unless args.empty?
|
|
94
|
-
new_note.add(args.join(' '))
|
|
95
|
-
end
|
|
55
|
+
new_note.add($stdin.read.strip) if $stdin.stat.size.positive?
|
|
56
|
+
new_note.add(args.join(' ')) unless args.empty?
|
|
96
57
|
|
|
97
58
|
if options[:editor]
|
|
98
59
|
raise MissingEditor, 'No EDITOR variable defined in environment' if Doing::Util.default_editor.nil?
|
|
99
60
|
|
|
100
|
-
if options[:remove]
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
61
|
+
input = if options[:remove]
|
|
62
|
+
Doing::Note.new
|
|
63
|
+
else
|
|
64
|
+
last_entry.note || Doing::Note.new
|
|
65
|
+
end
|
|
105
66
|
|
|
106
67
|
input.add(new_note)
|
|
107
68
|
|
data/bin/commands/now.rb
CHANGED
|
@@ -20,13 +20,6 @@ command %i[now next] do |c|
|
|
|
20
20
|
c.arg_name 'NAME'
|
|
21
21
|
c.flag %i[s section]
|
|
22
22
|
|
|
23
|
-
c.desc "Edit entry with #{Doing::Util.default_editor}"
|
|
24
|
-
c.switch %i[e editor], negatable: false, default_value: false
|
|
25
|
-
|
|
26
|
-
c.desc 'Backdate start time [4pm|20m|2h|"yesterday noon"]'
|
|
27
|
-
c.arg_name 'DATE_STRING'
|
|
28
|
-
c.flag %i[b back started], type: DateBeginString
|
|
29
|
-
|
|
30
23
|
c.desc %(
|
|
31
24
|
Set a start and optionally end time as a date range ("from 1pm to 2:30pm").
|
|
32
25
|
If an end time is provided, a dated @done tag will be added
|
|
@@ -37,19 +30,16 @@ command %i[now next] do |c|
|
|
|
37
30
|
c.desc 'Timed entry, marks last entry in section as @done'
|
|
38
31
|
c.switch %i[f finish_last], negatable: false, default_value: false
|
|
39
32
|
|
|
40
|
-
c
|
|
41
|
-
c.arg_name 'TEXT'
|
|
42
|
-
c.flag %i[n note]
|
|
43
|
-
|
|
44
|
-
c.desc 'Prompt for note via multi-line input'
|
|
45
|
-
c.switch %i[ask], negatable: false, default_value: false
|
|
33
|
+
add_options(:add_entry, c)
|
|
46
34
|
|
|
47
35
|
# c.desc "Edit entry with specified app"
|
|
48
36
|
# c.arg_name 'editor_app'
|
|
49
37
|
# # c.flag [:a, :app]
|
|
50
38
|
|
|
51
39
|
c.action do |_global_options, options, args|
|
|
52
|
-
|
|
40
|
+
@wwid.auto_tag = !options[:noauto]
|
|
41
|
+
|
|
42
|
+
raise InvalidArgument, '--back and --from cannot be used together' if options[:back] && options[:from]
|
|
53
43
|
|
|
54
44
|
if options[:back]
|
|
55
45
|
date = options[:back]
|
|
@@ -61,13 +51,17 @@ command %i[now next] do |c|
|
|
|
61
51
|
end
|
|
62
52
|
raise InvalidTimeExpression.new('unable to parse date string', topic: 'Parser:') if date.nil?
|
|
63
53
|
|
|
64
|
-
if options[:section]
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
ask_note = options[:ask] && !options[:editor] && args.count.positive?
|
|
54
|
+
section = if options[:section]
|
|
55
|
+
@wwid.guess_section(options[:section]) || options[:section].cap_first
|
|
56
|
+
else
|
|
57
|
+
@settings['current_section']
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
ask_note = if options[:ask] && !options[:editor] && args.count.positive?
|
|
61
|
+
Doing::Prompt.read_lines(prompt: 'Add a note')
|
|
62
|
+
else
|
|
63
|
+
''
|
|
64
|
+
end
|
|
71
65
|
|
|
72
66
|
if options[:editor]
|
|
73
67
|
raise MissingEditor, 'No EDITOR variable defined in environment' if Doing::Util.default_editor.nil?
|
data/bin/commands/on.rb
CHANGED
|
@@ -23,10 +23,9 @@ command :on do |c|
|
|
|
23
23
|
c.switch [:totals], default_value: false, negatable: false
|
|
24
24
|
|
|
25
25
|
c.desc 'Sort tags by (name|time)'
|
|
26
|
-
default = '
|
|
27
|
-
default = @settings['tag_sort'] || 'name'
|
|
26
|
+
default = @settings['tag_sort'].normalize_tag_sort || :name
|
|
28
27
|
c.arg_name 'KEY'
|
|
29
|
-
c.flag [:tag_sort], must_match:
|
|
28
|
+
c.flag [:tag_sort], must_match: REGEX_TAG_SORT, default_value: default, type: TagSortSymbol
|
|
30
29
|
|
|
31
30
|
c.desc "Output to export format (#{Doing::Plugins.plugin_names(type: :export)})"
|
|
32
31
|
c.arg_name 'FORMAT'
|
|
@@ -58,7 +57,7 @@ command :on do |c|
|
|
|
58
57
|
Doing.logger.debug('Interpreter:', message)
|
|
59
58
|
|
|
60
59
|
options[:times] = true if options[:totals]
|
|
61
|
-
options[:sort_tags] = options[:tag_sort]
|
|
60
|
+
options[:sort_tags] = options[:tag_sort]
|
|
62
61
|
|
|
63
62
|
Doing::Pager.page @wwid.list_date([start, finish], options[:section], options[:times], options[:output],
|
|
64
63
|
{ template: options[:template], config_template: options[:config_template], duration: options[:duration], totals: options[:totals], sort_tags: options[:sort_tags] }).chomp
|
data/bin/commands/open.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @@open
|
|
2
2
|
desc 'Open the "doing" file in an editor'
|
|
3
|
-
long_desc "`doing open` defaults to using the editors
|
|
3
|
+
long_desc "`doing open` defaults to using the editors.doing_file setting
|
|
4
4
|
in #{@config.config_file} (#{Doing::Util.find_default_editor('doing_file')})."
|
|
5
5
|
command :open do |c|
|
|
6
6
|
c.example 'doing open', desc: 'Open the doing file in the default editor'
|
|
@@ -8,7 +8,7 @@ command :open do |c|
|
|
|
8
8
|
c.arg_name 'COMMAND'
|
|
9
9
|
c.flag %i[e editor]
|
|
10
10
|
|
|
11
|
-
if
|
|
11
|
+
if Sys::Platform.mac?
|
|
12
12
|
c.desc 'Open with app name'
|
|
13
13
|
c.arg_name 'APP_NAME'
|
|
14
14
|
c.flag %i[a app]
|
|
@@ -29,7 +29,7 @@ command :open do |c|
|
|
|
29
29
|
|
|
30
30
|
editor = TTY::Which.which(options[:editor])
|
|
31
31
|
system %(#{editor} "#{File.expand_path(@wwid.doing_file)}")
|
|
32
|
-
elsif
|
|
32
|
+
elsif Sys::Platform.mac?
|
|
33
33
|
if options[:app]
|
|
34
34
|
system %(open -a "#{options[:app]}" "#{File.expand_path(@wwid.doing_file)}")
|
|
35
35
|
elsif options[:bundle_id]
|
data/bin/commands/recent.rb
CHANGED
|
@@ -30,10 +30,9 @@ command :recent do |c|
|
|
|
30
30
|
c.switch [:totals], default_value: false, negatable: false
|
|
31
31
|
|
|
32
32
|
c.desc 'Sort tags by (name|time)'
|
|
33
|
-
default = '
|
|
34
|
-
default = @settings['tag_sort'] || 'name'
|
|
33
|
+
default = @settings['tag_sort'].normalize_tag_sort || :name
|
|
35
34
|
c.arg_name 'KEY'
|
|
36
|
-
c.flag [:tag_sort], must_match:
|
|
35
|
+
c.flag [:tag_sort], must_match: REGEX_TAG_SORT, default_value: default, type: TagSortSymbol
|
|
37
36
|
|
|
38
37
|
c.desc 'Select from a menu of matching entries to perform additional operations'
|
|
39
38
|
c.switch %i[i interactive], negatable: false, default_value: false
|
|
@@ -55,7 +54,7 @@ command :recent do |c|
|
|
|
55
54
|
end
|
|
56
55
|
|
|
57
56
|
options[:times] = true if options[:totals]
|
|
58
|
-
options[:sort_tags] = options[:tag_sort]
|
|
57
|
+
options[:sort_tags] = options[:tag_sort]
|
|
59
58
|
|
|
60
59
|
template = @settings['templates']['recent'].deep_merge(@settings['templates']['default'])
|
|
61
60
|
tags_color = template.key?('tags_color') ? template['tags_color'] : nil
|
data/bin/commands/redo.rb
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# @@redo
|
|
2
|
-
|
|
4
|
+
desc 'Redo an undo command'
|
|
5
|
+
long_desc 'Shortcut for `doing undo -r`, reverses the last undo command. Specify a count to redo multiple undos'
|
|
3
6
|
arg_name 'COUNT'
|
|
4
7
|
command :redo do |c|
|
|
5
8
|
c.desc 'Specify alternate doing file'
|
|
@@ -12,7 +15,8 @@ command :redo do |c|
|
|
|
12
15
|
c.action do |_global, options, args|
|
|
13
16
|
file = options[:file] || @wwid.doing_file
|
|
14
17
|
count = args.empty? ? 1 : args[0].to_i
|
|
15
|
-
raise InvalidArgument,
|
|
18
|
+
raise InvalidArgument, 'Invalid count specified for redo' unless count&.positive?
|
|
19
|
+
|
|
16
20
|
if options[:interactive]
|
|
17
21
|
Doing::Util::Backup.select_redo(file)
|
|
18
22
|
else
|
data/bin/commands/reset.rb
CHANGED
|
@@ -20,54 +20,24 @@ command %i[reset begin] do |c|
|
|
|
20
20
|
c.desc 'Change start date but do not remove @done (shortcut for --no-resume)'
|
|
21
21
|
c.switch [:n]
|
|
22
22
|
|
|
23
|
-
c.desc 'Reset last entry matching tag. Wildcards allowed (*, ?)'
|
|
24
|
-
c.arg_name 'TAG'
|
|
25
|
-
c.flag [:tag]
|
|
26
|
-
|
|
27
|
-
c.desc 'Reset last entry matching search filter, surround with slashes for regex (e.g. "/query.*/"), start with single quote for exact match ("\'query")'
|
|
28
|
-
c.arg_name 'QUERY'
|
|
29
|
-
c.flag [:search]
|
|
30
|
-
|
|
31
|
-
c.desc 'Perform a tag value query ("@done > two hours ago" or "@progress < 50"). May be used multiple times, combined with --bool'
|
|
32
|
-
c.arg_name 'QUERY'
|
|
33
|
-
c.flag [:val], multiple: true, must_match: REGEX_VALUE_QUERY
|
|
34
|
-
|
|
35
|
-
# c.desc '[DEPRECATED] Use alternative fuzzy matching for search string'
|
|
36
|
-
# c.switch [:fuzzy], default_value: false, negatable: false
|
|
37
|
-
|
|
38
|
-
c.desc 'Force exact search string matching (case sensitive)'
|
|
39
|
-
c.switch %i[x exact], default_value: @config.exact_match?, negatable: @config.exact_match?
|
|
40
|
-
|
|
41
|
-
c.desc 'Reset items that *don\'t* match search/tag filters'
|
|
42
|
-
c.switch [:not], default_value: false, negatable: false
|
|
43
|
-
|
|
44
|
-
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
|
45
|
-
c.arg_name 'TYPE'
|
|
46
|
-
c.flag [:case], must_match: /^[csi]/, default_value: @settings.dig('search', 'case')
|
|
47
|
-
|
|
48
|
-
c.desc 'Boolean (AND|OR|NOT) with which to combine multiple tag filters. Use PATTERN to parse + and - as booleans'
|
|
49
|
-
c.arg_name 'BOOLEAN'
|
|
50
|
-
c.flag [:bool], must_match: REGEX_BOOL, default_value: 'PATTERN'
|
|
51
|
-
|
|
52
23
|
c.desc 'Select from a menu of matching entries'
|
|
53
24
|
c.switch %i[i interactive], negatable: false, default_value: false
|
|
54
25
|
|
|
26
|
+
add_options(:search, c)
|
|
27
|
+
add_options(:tag_filter, c)
|
|
28
|
+
|
|
55
29
|
c.action do |global_options, options, args|
|
|
56
|
-
if args.count
|
|
30
|
+
if args.count.positive?
|
|
57
31
|
reset_date = args.join(' ').chronify(guess: :begin)
|
|
58
32
|
raise InvalidArgument, 'Invalid date string' unless reset_date
|
|
33
|
+
|
|
59
34
|
else
|
|
60
35
|
reset_date = Time.now
|
|
61
36
|
end
|
|
62
37
|
|
|
63
38
|
options[:fuzzy] = false
|
|
64
|
-
if options[:section]
|
|
65
|
-
options[:section] = @wwid.guess_section(options[:section]) || options[:section].cap_first
|
|
66
|
-
end
|
|
67
39
|
|
|
68
|
-
options[:
|
|
69
|
-
|
|
70
|
-
options[:case] = options[:case].normalize_case
|
|
40
|
+
options[:section] = @wwid.guess_section(options[:section]) || options[:section].cap_first if options[:section]
|
|
71
41
|
|
|
72
42
|
if options[:search]
|
|
73
43
|
search = options[:search]
|
|
@@ -75,25 +45,22 @@ command %i[reset begin] do |c|
|
|
|
75
45
|
options[:search] = search
|
|
76
46
|
end
|
|
77
47
|
|
|
78
|
-
|
|
79
48
|
items = @wwid.filter_items([], opt: options)
|
|
80
49
|
|
|
81
|
-
if options[:interactive]
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
50
|
+
last_entry = if options[:interactive]
|
|
51
|
+
Doing::Prompt.choose_from_items(items, include_section: options[:section].nil?,
|
|
52
|
+
menu: true,
|
|
53
|
+
header: '',
|
|
54
|
+
prompt: 'Select an entry to start/reset > ',
|
|
55
|
+
multiple: false,
|
|
56
|
+
sort: false,
|
|
57
|
+
show_if_single: true)
|
|
58
|
+
else
|
|
59
|
+
items.reverse.last
|
|
60
|
+
end
|
|
92
61
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return
|
|
96
|
-
end
|
|
62
|
+
|
|
63
|
+
raise NoResults, 'No entry matching parameters was found.' unless last_entry
|
|
97
64
|
|
|
98
65
|
old_item = last_entry.clone
|
|
99
66
|
|
data/bin/commands/rotate.rb
CHANGED
|
@@ -16,49 +16,18 @@ command :rotate do |c|
|
|
|
16
16
|
c.arg_name 'SECTION_NAME'
|
|
17
17
|
c.flag %i[s section], default_value: 'All'
|
|
18
18
|
|
|
19
|
-
c.desc 'Tag filter, combine multiple tags with a comma. Wildcards allowed (*, ?). Added for compatibility with other commands'
|
|
20
|
-
c.arg_name 'TAG'
|
|
21
|
-
c.flag [:tag]
|
|
22
|
-
|
|
23
|
-
c.desc 'Tag boolean (AND|OR|NOT). Use PATTERN to parse + and - as booleans'
|
|
24
|
-
c.arg_name 'BOOLEAN'
|
|
25
|
-
c.flag [:bool], must_match: REGEX_BOOL, default_value: 'PATTERN'
|
|
26
|
-
|
|
27
|
-
c.desc 'Search filter'
|
|
28
|
-
c.arg_name 'QUERY'
|
|
29
|
-
c.flag [:search]
|
|
30
|
-
|
|
31
|
-
c.desc 'Perform a tag value query ("@done > two hours ago" or "@progress < 50"). May be used multiple times, combined with --bool'
|
|
32
|
-
c.arg_name 'QUERY'
|
|
33
|
-
c.flag [:val], multiple: true, must_match: REGEX_VALUE_QUERY
|
|
34
|
-
|
|
35
|
-
# c.desc '[DEPRECATED] Use alternative fuzzy matching for search string'
|
|
36
|
-
# c.switch [:fuzzy], default_value: false, negatable: false
|
|
37
|
-
|
|
38
|
-
c.desc 'Force exact search string matching (case sensitive)'
|
|
39
|
-
c.switch %i[x exact], default_value: @config.exact_match?, negatable: @config.exact_match?
|
|
40
|
-
|
|
41
|
-
c.desc 'Rotate items that *don\'t* match search string or tag filter'
|
|
42
|
-
c.switch [:not], default_value: false, negatable: false
|
|
43
|
-
|
|
44
|
-
c.desc 'Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]'
|
|
45
|
-
c.arg_name 'TYPE'
|
|
46
|
-
c.flag [:case], must_match: /^[csi]/, default_value: @settings.dig('search', 'case')
|
|
47
|
-
|
|
48
19
|
c.desc 'Rotate entries older than date
|
|
49
20
|
(Flexible date format, e.g. 1/27/2021, 2020-07-19, or Monday 3pm)'
|
|
50
21
|
c.arg_name 'DATE_STRING'
|
|
51
22
|
c.flag [:before]
|
|
52
23
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if options[:section] && options[:section] !~ /^all$/i
|
|
56
|
-
options[:section] = @wwid.guess_section(options[:section])
|
|
57
|
-
end
|
|
24
|
+
add_options(:search, c)
|
|
25
|
+
add_options(:tag_filter, c)
|
|
58
26
|
|
|
59
|
-
|
|
27
|
+
c.action do |_global_options, options, _args|
|
|
28
|
+
options[:fuzzy] = false
|
|
60
29
|
|
|
61
|
-
options[:
|
|
30
|
+
options[:section] = @wwid.guess_section(options[:section]) if options[:section] && options[:section] !~ /^all$/i
|
|
62
31
|
|
|
63
32
|
search = nil
|
|
64
33
|
|
data/bin/commands/select.rb
CHANGED
|
@@ -14,9 +14,13 @@ sbtrkt fuzzy-match Items that match s*b*t*r*k*t
|
|
|
14
14
|
|
|
15
15
|
!fire inverse-exact-match Items that do not include fire'
|
|
16
16
|
command :select do |c|
|
|
17
|
-
c.example 'doing select',
|
|
18
|
-
|
|
19
|
-
c.example 'doing select --
|
|
17
|
+
c.example 'doing select',
|
|
18
|
+
desc: 'Select from all entries. A menu of actions will be presented after confirming the selection.'
|
|
19
|
+
c.example 'doing select --editor',
|
|
20
|
+
desc: 'Select entries from a menu and batch edit them in your default editor'
|
|
21
|
+
c.example 'doing select --after "yesterday 12pm" --tag project1',
|
|
22
|
+
desc: 'Display a menu of entries created after noon yesterday, add @project1 to selected entries'
|
|
23
|
+
|
|
20
24
|
c.desc 'Select from a specific section'
|
|
21
25
|
c.arg_name 'SECTION'
|
|
22
26
|
c.flag %i[s section]
|
|
@@ -38,48 +42,21 @@ command :select do |c|
|
|
|
38
42
|
c.arg_name 'SECTION'
|
|
39
43
|
c.flag %i[m move]
|
|
40
44
|
|
|
41
|
-
c.desc 'Initial search query for filtering. Matching is fuzzy. For exact matching, start query with a single quote,
|
|
45
|
+
c.desc 'Initial search query for filtering. Matching is fuzzy. For exact matching, start query with a single quote,
|
|
46
|
+
e.g. `--query "\'search"'
|
|
42
47
|
c.arg_name 'QUERY'
|
|
43
48
|
c.flag %i[q query]
|
|
44
49
|
|
|
45
|
-
c.desc '
|
|
46
|
-
|
|
47
|
-
c.flag [:search]
|
|
48
|
-
|
|
49
|
-
c.desc 'Perform a tag value query ("@done > two hours ago" or "@progress < 50"). May be used multiple times, combined with --bool'
|
|
50
|
+
c.desc 'Perform a tag value query ("@done > two hours ago" or "@progress < 50").
|
|
51
|
+
May be used multiple times, combined with --bool'
|
|
50
52
|
c.arg_name 'QUERY'
|
|
51
53
|
c.flag [:val], multiple: true, must_match: REGEX_VALUE_QUERY
|
|
52
54
|
|
|
53
|
-
c.desc 'Select from 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'
|
|
54
|
-
c.arg_name 'DATE_STRING'
|
|
55
|
-
c.flag [:before], type: DateBeginString
|
|
56
|
-
|
|
57
|
-
c.desc 'Select from 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'
|
|
58
|
-
c.arg_name 'DATE_STRING'
|
|
59
|
-
c.flag [:after], type: DateEndString
|
|
60
|
-
|
|
61
|
-
c.desc %(
|
|
62
|
-
Date range to show, or a single day to filter date on.
|
|
63
|
-
Date range argument should be quoted. Date specifications can be natural language.
|
|
64
|
-
To specify a range, use "to" or "through": `doing select --from "monday 8am to friday 5pm"`.
|
|
65
|
-
|
|
66
|
-
If values are only time(s) (6am to noon) all dates will be included, but entries will be filtered
|
|
67
|
-
by time of day.
|
|
68
|
-
)
|
|
69
|
-
c.arg_name 'DATE_OR_RANGE'
|
|
70
|
-
c.flag [:from], type: DateRangeString
|
|
71
|
-
|
|
72
|
-
c.desc 'Force exact search string matching (case sensitive)'
|
|
73
|
-
c.switch %i[x exact], default_value: @config.exact_match?, negatable: @config.exact_match?
|
|
74
|
-
|
|
75
55
|
c.desc 'Select items that *don\'t* match search/tag filters'
|
|
76
56
|
c.switch [:not], default_value: false, negatable: false
|
|
77
57
|
|
|
78
|
-
c.desc '
|
|
79
|
-
|
|
80
|
-
c.flag [:case], must_match: /^[csi]/, default_value: @settings.dig('search', 'case')
|
|
81
|
-
|
|
82
|
-
c.desc 'Use --no-menu to skip the interactive menu. Use with --query to filter items and act on results automatically. Test with `--output doing` to preview matches'
|
|
58
|
+
c.desc 'Use --no-menu to skip the interactive menu. Use with --query to filter items and act on results automatically.
|
|
59
|
+
Test with `--output doing` to preview matches'
|
|
83
60
|
c.switch %i[menu], negatable: true, default_value: true
|
|
84
61
|
|
|
85
62
|
c.desc 'Cancel selected items (add @done without timestamp)'
|
|
@@ -108,15 +85,20 @@ command :select do |c|
|
|
|
108
85
|
c.arg_name 'FORMAT'
|
|
109
86
|
c.flag %i[o output]
|
|
110
87
|
|
|
111
|
-
c.desc
|
|
88
|
+
c.desc 'Copy selection as a new entry with current time and no @done tag.
|
|
89
|
+
Only works with single selections. Can be combined with --editor.'
|
|
112
90
|
c.switch %i[again resume], negatable: false, default_value: false
|
|
113
91
|
|
|
114
|
-
|
|
115
|
-
|
|
92
|
+
add_options(:search, c)
|
|
93
|
+
add_options(:date_filter, c)
|
|
116
94
|
|
|
117
|
-
|
|
95
|
+
c.action do |_global_options, options, _args|
|
|
96
|
+
if options[:output] && options[:output] !~ Doing::Plugins.plugin_regex(type: :export)
|
|
97
|
+
raise DoingRuntimeError, %(Invalid output type "#{options[:output]}")
|
|
98
|
+
|
|
99
|
+
end
|
|
118
100
|
|
|
119
|
-
options[:
|
|
101
|
+
raise InvalidArgument, '--no-menu requires --query' if !options[:menu] && !options[:query]
|
|
120
102
|
|
|
121
103
|
@wwid.interactive(options) # hooked
|
|
122
104
|
end
|