doing 2.1.23 → 2.1.27
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardoc/checksums +17 -21
- data/.yardoc/object_types +0 -0
- data/.yardoc/objects/root.dat +0 -0
- data/CHANGELOG.md +329 -102
- 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 +1 -1
- data/README.md +1 -1
- data/Rakefile +3 -3
- data/bin/commands/add_section.rb +15 -0
- data/bin/commands/again.rb +57 -0
- data/bin/commands/archive.rb +55 -0
- data/bin/commands/cancel.rb +60 -0
- data/bin/commands/changes.rb +69 -0
- data/bin/commands/choose.rb +9 -0
- data/bin/commands/colors.rb +21 -0
- data/bin/commands/commands.rb +89 -0
- data/bin/commands/commands_accepting.rb +76 -0
- data/bin/commands/completion.rb +27 -0
- data/bin/commands/config.rb +245 -0
- data/bin/commands/done.rb +235 -0
- data/bin/commands/finish.rb +126 -0
- data/bin/commands/flag.rb +90 -0
- data/bin/commands/grep.rb +108 -0
- data/bin/commands/import.rb +71 -0
- data/bin/commands/install_fzf.rb +17 -0
- data/bin/commands/last.rb +81 -0
- data/bin/commands/meanwhile.rb +76 -0
- data/bin/commands/note.rb +91 -0
- data/bin/commands/now.rb +145 -0
- data/bin/commands/on.rb +65 -0
- data/bin/commands/open.rb +53 -0
- data/bin/commands/plugins.rb +23 -0
- data/bin/commands/recent.rb +77 -0
- data/bin/commands/redo.rb +26 -0
- data/bin/commands/reset.rb +73 -0
- data/bin/commands/rotate.rb +42 -0
- data/bin/commands/sections.rb +11 -0
- data/bin/commands/select.rb +105 -0
- data/bin/commands/show.rb +185 -0
- data/bin/commands/since.rb +63 -0
- data/bin/commands/tag.rb +149 -0
- data/bin/commands/tag_dir.rb +29 -0
- data/bin/commands/tags.rb +66 -0
- data/bin/commands/template.rb +61 -0
- data/bin/commands/today.rb +64 -0
- data/bin/commands/undo.rb +49 -0
- data/bin/commands/view.rb +201 -0
- data/bin/commands/views.rb +11 -0
- data/bin/commands/yesterday.rb +72 -0
- data/bin/doing +241 -3662
- data/docs/doc/Array.html +13 -449
- data/docs/doc/BooleanTermParser/Clause.html +5 -5
- data/docs/doc/BooleanTermParser/Operator.html +4 -4
- data/docs/doc/BooleanTermParser/Query.html +8 -8
- data/docs/doc/BooleanTermParser/QueryParser.html +2 -2
- data/docs/doc/BooleanTermParser/QueryTransformer.html +2 -2
- data/docs/doc/BooleanTermParser.html +1 -1
- data/docs/doc/Doing/Color.html +65 -59
- data/docs/doc/Doing/Completion.html +2 -2
- data/docs/doc/Doing/Configuration.html +49 -16
- data/docs/doc/Doing/Errors/DoingNoTraceError.html +2 -2
- data/docs/doc/Doing/Errors/DoingRuntimeError.html +2 -2
- data/docs/doc/Doing/Errors/DoingStandardError.html +2 -2
- data/docs/doc/Doing/Errors/EmptyInput.html +2 -2
- data/docs/doc/Doing/Errors/NoResults.html +2 -2
- data/docs/doc/Doing/Errors/PluginException.html +3 -3
- data/docs/doc/Doing/Errors/UserCancelled.html +2 -2
- data/docs/doc/Doing/Errors/WrongCommand.html +2 -2
- data/docs/doc/Doing/Errors.html +1 -1
- data/docs/doc/Doing/Hooks.html +6 -6
- data/docs/doc/Doing/Item.html +50 -16
- data/docs/doc/Doing/Items.html +10 -10
- data/docs/doc/Doing/LogAdapter.html +24 -24
- data/docs/doc/Doing/Note.html +7 -7
- data/docs/doc/Doing/Pager.html +4 -4
- data/docs/doc/Doing/Plugins.html +7 -7
- data/docs/doc/Doing/Prompt.html +59 -14
- data/docs/doc/Doing/Section.html +6 -6
- data/docs/doc/Doing/TemplateString.html +8 -8
- data/docs/doc/Doing/Types.html +46 -1
- data/docs/doc/Doing/Util/Backup.html +10 -10
- data/docs/doc/Doing/Util.html +15 -15
- data/docs/doc/Doing/WWID.html +73 -61
- data/docs/doc/Doing.html +3 -3
- data/docs/doc/FalseClass.html +235 -0
- data/docs/doc/GLI/Commands/Help.html +3 -3
- data/docs/doc/GLI/Commands/MarkdownDocumentListener.html +17 -17
- data/docs/doc/GLI/Commands.html +1 -1
- data/docs/doc/GLI.html +1 -1
- data/docs/doc/Hash.html +45 -11
- data/docs/doc/Numeric.html +5 -5
- data/docs/doc/Object.html +203 -0
- data/docs/doc/PhraseParser/Operator.html +4 -4
- data/docs/doc/PhraseParser/PhraseClause.html +5 -5
- data/docs/doc/PhraseParser/Query.html +10 -10
- data/docs/doc/PhraseParser/QueryParser.html +2 -2
- data/docs/doc/PhraseParser/QueryTransformer.html +2 -2
- data/docs/doc/PhraseParser/TermClause.html +5 -5
- data/docs/doc/PhraseParser.html +1 -1
- data/docs/doc/Status.html +7 -7
- data/docs/doc/String.html +306 -3111
- data/docs/doc/Symbol.html +45 -11
- data/docs/doc/Time.html +6 -6
- data/docs/doc/TrueClass.html +235 -0
- data/docs/doc/_index.html +37 -19
- 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 +240 -576
- data/docs/doc/top-level-namespace.html +2 -2
- data/doing.rdoc +289 -169
- data/example_plugin.rb +2 -2
- data/lib/completion/_doing.zsh +35 -31
- data/lib/completion/doing.bash +30 -19
- data/lib/completion/doing.fish +81 -67
- 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 +14 -4
- 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/fish_completion.rb +2 -1
- data/lib/doing/configuration.rb +9 -6
- data/lib/doing/good.rb +72 -0
- data/lib/doing/hash.rb +4 -0
- data/lib/doing/help_monkey_patch.rb +6 -5
- data/lib/doing/hooks.rb +3 -3
- data/lib/doing/item.rb +19 -15
- 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/pager.rb +1 -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/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/prompt.rb +9 -3
- 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 +2 -24
- data/lib/doing/types.rb +9 -0
- data/lib/doing/util.rb +20 -16
- data/lib/doing/version.rb +1 -1
- data/lib/doing/wwid.rb +91 -51
- data/lib/doing.rb +5 -6
- data/lib/examples/commands/wiki.rb +6 -7
- data/lib/examples/plugins/wiki_export/wiki_export.rb +1 -1
- data/lib/helpers/threaded_tests.rb +69 -79
- data/lib/helpers/threaded_tests_string.rb +50 -0
- data/scripts/deploy.rb +107 -0
- data/scripts/runtests.sh +4 -0
- metadata +65 -8
- data/lib/doing/string.rb +0 -765
- data/lib/doing/symbol.rb +0 -28
data/Dockerfile
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
FROM ruby:3.0.1
|
2
|
-
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
|
2
|
+
# RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
|
3
3
|
RUN mkdir /doing
|
4
4
|
WORKDIR /doing
|
5
|
-
COPY ./ /doing/
|
5
|
+
# COPY ./ /doing/
|
6
6
|
RUN gem install bundler:2.2.17
|
7
|
-
|
8
|
-
RUN
|
9
|
-
CMD ["
|
7
|
+
RUN apt-get update -y
|
8
|
+
RUN apt-get install -y less
|
9
|
+
CMD ["scripts/runtests.sh"]
|
data/Dockerfile-2.6
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
FROM ruby:2.6
|
2
|
+
# RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
|
2
3
|
RUN mkdir /doing
|
3
4
|
WORKDIR /doing
|
4
|
-
COPY ./ /doing/
|
5
|
+
# COPY ./ /doing/
|
5
6
|
RUN gem install bundler:2.2.17
|
6
|
-
|
7
|
-
RUN
|
8
|
-
|
9
|
-
CMD ["rake", "parallel:test"]
|
7
|
+
RUN apt-get update -y
|
8
|
+
RUN apt-get install -y less
|
9
|
+
CMD ["scripts/runtests.sh"]
|
data/Dockerfile-2.7
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
FROM ruby:2.7
|
2
|
+
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
|
2
3
|
RUN mkdir /doing
|
3
4
|
WORKDIR /doing
|
4
|
-
COPY ./ /doing/
|
5
|
+
# COPY ./ /doing/
|
5
6
|
RUN gem install bundler:2.2.17
|
6
|
-
|
7
|
-
RUN
|
8
|
-
CMD ["
|
7
|
+
RUN apt-get update -y
|
8
|
+
RUN apt-get install -y less
|
9
|
+
CMD ["scripts/runtests.sh"]
|
data/Dockerfile-3.0
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
FROM ruby:3.0.0
|
2
|
+
# RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
|
2
3
|
RUN mkdir /doing
|
3
4
|
WORKDIR /doing
|
4
|
-
COPY ./ /doing/
|
5
|
+
# COPY ./ /doing/
|
5
6
|
RUN gem install bundler:2.2.17
|
6
|
-
|
7
|
-
RUN
|
8
|
-
CMD ["
|
7
|
+
RUN apt-get update -y
|
8
|
+
RUN apt-get install -y less
|
9
|
+
CMD ["scripts/runtests.sh"]
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -8,7 +8,7 @@ _If you're one of the rare people like me who find this useful, feel free to
|
|
8
8
|
|
9
9
|
<!--README-->
|
10
10
|
|
11
|
-
The current version of `doing` is <!--VER-->2.1.
|
11
|
+
The current version of `doing` is <!--VER-->2.1.26<!--END VER-->.
|
12
12
|
|
13
13
|
Find all of the documentation in the [doing wiki][wiki].
|
14
14
|
|
data/Rakefile
CHANGED
@@ -77,14 +77,14 @@ task :dockertest, :version, :login do |_, args|
|
|
77
77
|
file = 'Dockerfile'
|
78
78
|
end
|
79
79
|
|
80
|
-
exec "docker run -it #{img} /bin/bash -l" if args[:login]
|
81
|
-
|
82
80
|
puts `docker build . --file #{file} -t #{img}`
|
83
81
|
|
82
|
+
exec "docker run -v #{File.dirname(__FILE__)}:/doing -it #{img} /bin/bash -l" if args[:login]
|
83
|
+
|
84
84
|
spinner = TTY::Spinner.new('[:spinner] Running tests ...', hide_cursor: true)
|
85
85
|
|
86
86
|
spinner.auto_spin
|
87
|
-
res = `docker run --rm -it #{img}`
|
87
|
+
res = `docker run --rm -v #{File.dirname(__FILE__)}:/doing -it #{img}`
|
88
88
|
# commit = puts `bash -c "docker commit $(docker ps -a|grep #{img}|awk '{print $1}'|head -n 1) #{img}"`.strip
|
89
89
|
spinner.success
|
90
90
|
spinner.stop
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @@add_section
|
4
|
+
desc 'Add a new section to the "doing" file'
|
5
|
+
arg_name 'SECTION_NAME'
|
6
|
+
command :add_section do |c|
|
7
|
+
c.example 'doing add_section Ideas', desc: 'Add a section called Ideas to the doing file'
|
8
|
+
|
9
|
+
c.action do |_global_options, _options, args|
|
10
|
+
raise InvalidArgument, "Section #{args[0]} already exists" if @wwid.sections.include?(args[0])
|
11
|
+
|
12
|
+
@wwid.content.add_section(args.join(' ').cap_first, log: true)
|
13
|
+
@wwid.write(@wwid.doing_file)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @@again @@resume
|
4
|
+
desc 'Repeat last entry as new entry'
|
5
|
+
long_desc 'This command is designed to allow multiple time intervals to be created
|
6
|
+
for an entry by duplicating it with a new start (and end, eventually) time'
|
7
|
+
command %i[again resume] do |c|
|
8
|
+
c.example 'doing resume',
|
9
|
+
desc: 'Duplicate the most recent entry with a new start time, removing any @done tag'
|
10
|
+
c.example 'doing again',
|
11
|
+
desc: 'again is an alias for resume'
|
12
|
+
c.example 'doing resume --editor',
|
13
|
+
desc: 'Repeat the last entry, opening the new entry in the default editor'
|
14
|
+
c.example 'doing resume --tag project1 --in Projects',
|
15
|
+
desc: 'Repeat the last entry tagged @project1, creating the new entry in the Projects section'
|
16
|
+
c.example 'doing resume --interactive', desc: 'Select the entry to repeat from a menu'
|
17
|
+
|
18
|
+
c.desc 'Get last entry from a specific section'
|
19
|
+
c.arg_name 'NAME'
|
20
|
+
c.flag %i[s section], default_value: 'All'
|
21
|
+
|
22
|
+
c.desc 'Add new entry to section (default: same section as repeated entry)'
|
23
|
+
c.arg_name 'SECTION_NAME'
|
24
|
+
c.flag [:in]
|
25
|
+
|
26
|
+
c.desc 'Select item to resume from a menu of matching entries'
|
27
|
+
c.switch %i[i interactive], negatable: false, default_value: false
|
28
|
+
|
29
|
+
add_options(:add_entry, c)
|
30
|
+
add_options(:search, c)
|
31
|
+
add_options(:tag_filter, c)
|
32
|
+
|
33
|
+
c.action do |_global_options, options, _args|
|
34
|
+
options[:fuzzy] = false
|
35
|
+
|
36
|
+
if options[:search]
|
37
|
+
options[:search] = options[:exact] ? options[:search].sub(/^'?/, "'") : options[:search]
|
38
|
+
end
|
39
|
+
|
40
|
+
if options[:back]
|
41
|
+
options[:date] = options[:back]
|
42
|
+
raise InvalidTimeExpression, 'Unable to parse date string for --back' if date.nil?
|
43
|
+
|
44
|
+
else
|
45
|
+
options[:date] = Time.now
|
46
|
+
end
|
47
|
+
|
48
|
+
note = Doing::Note.new(options[:note])
|
49
|
+
note.add(Doing::Prompt.read_lines(prompt: 'Add a note')) if options[:ask]
|
50
|
+
|
51
|
+
options[:note] = note
|
52
|
+
options[:tag] ||= []
|
53
|
+
options[:tag_bool] = options[:bool]
|
54
|
+
|
55
|
+
@wwid.repeat_last(options)
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @@archive @@move
|
4
|
+
desc 'Move entries between sections'
|
5
|
+
long_desc %(Argument can be a section name to move all entries from a section,
|
6
|
+
or start with an "@" to move entries matching a tag.
|
7
|
+
|
8
|
+
Default with no argument moves items from the "#{@settings['current_section']}" section to Archive.)
|
9
|
+
arg_name 'SECTION_OR_TAG'
|
10
|
+
default_value @settings['current_section']
|
11
|
+
command %i[archive move] do |c|
|
12
|
+
c.example 'doing archive Currently', desc: 'Move all entries in the Currently section to Archive section'
|
13
|
+
c.example 'doing archive @done', desc: 'Move all entries tagged @done to Archive'
|
14
|
+
c.example 'doing archive --to Later @project1', desc: 'Move all entries tagged @project1 to Later section'
|
15
|
+
c.example 'doing move Later --tag project1 --to Currently',
|
16
|
+
desc: 'Move entries in Later tagged @project1 to Currently (move is an alias for archive)'
|
17
|
+
|
18
|
+
c.desc 'How many items to keep (ignored if archiving by tag or search)'
|
19
|
+
c.arg_name 'X'
|
20
|
+
c.flag %i[k keep], must_match: /^\d+$/, type: Integer
|
21
|
+
|
22
|
+
c.desc 'Move entries to'
|
23
|
+
c.arg_name 'SECTION_NAME'
|
24
|
+
c.flag %i[t to], default_value: 'Archive'
|
25
|
+
|
26
|
+
c.desc 'Label moved items with @from(SECTION_NAME)'
|
27
|
+
c.switch [:label], default_value: true, negatable: true
|
28
|
+
|
29
|
+
add_options(:search, c)
|
30
|
+
add_options(:tag_filter, c)
|
31
|
+
add_options(:date_filter, c)
|
32
|
+
|
33
|
+
c.action do |_global_options, options, args|
|
34
|
+
options[:fuzzy] = false
|
35
|
+
section, tags = if args.empty?
|
36
|
+
[@settings['current_section'], []]
|
37
|
+
elsif args[0] =~ /^all/i
|
38
|
+
['all', []]
|
39
|
+
elsif args[0] =~ /^@\S+/
|
40
|
+
['all', args.tags_to_array]
|
41
|
+
else
|
42
|
+
[args.shift.cap_first, args.tags_to_array]
|
43
|
+
end
|
44
|
+
|
45
|
+
raise InvalidArgument, '--keep and --count can not be used together' if options[:keep] && options[:count]
|
46
|
+
|
47
|
+
tags.concat(options[:tag]) if options[:tag]
|
48
|
+
|
49
|
+
options[:search] = options[:search].sub(/^'?/, "'") if options[:search] && options[:exact]
|
50
|
+
options[:destination] = options[:to]
|
51
|
+
options[:tags] = tags
|
52
|
+
|
53
|
+
@wwid.archive(section, options)
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @@cancel
|
4
|
+
desc 'End last X entries with no time tracked'
|
5
|
+
long_desc 'Adds @done tag without datestamp so no elapsed time is recorded.
|
6
|
+
Alias for `doing finish --no-date`'
|
7
|
+
arg_name 'COUNT'
|
8
|
+
command :cancel do |c|
|
9
|
+
c.example 'doing cancel', desc: 'Cancel the last entry'
|
10
|
+
c.example 'doing cancel --tag project1 -u 5', desc: 'Cancel the last 5 unfinished entries containing @project1'
|
11
|
+
|
12
|
+
c.desc 'Archive entries'
|
13
|
+
c.switch %i[a archive], negatable: false, default_value: false
|
14
|
+
|
15
|
+
c.desc 'Section'
|
16
|
+
c.arg_name 'NAME'
|
17
|
+
c.flag %i[s section]
|
18
|
+
|
19
|
+
c.desc 'Cancel last entry (or entries) not already marked @done'
|
20
|
+
c.switch %i[u unfinished], negatable: false, default_value: false
|
21
|
+
|
22
|
+
c.desc 'Select item(s) to cancel from a menu of matching entries'
|
23
|
+
c.switch %i[i interactive], negatable: false, default_value: false
|
24
|
+
|
25
|
+
add_options(:search, c)
|
26
|
+
add_options(:tag_filter, c)
|
27
|
+
|
28
|
+
c.action do |_global_options, options, args|
|
29
|
+
options[:fuzzy] = false
|
30
|
+
options[:section] = if options[:section]
|
31
|
+
@wwid.guess_section(options[:section]) || options[:section].cap_first
|
32
|
+
else
|
33
|
+
@settings['current_section']
|
34
|
+
end
|
35
|
+
|
36
|
+
raise InvalidArgument, 'Only one argument allowed' if args.length > 1
|
37
|
+
|
38
|
+
unless args.empty? || args[0] =~ /\d+/
|
39
|
+
raise InvalidArgument, 'Invalid argument (specify number of recent items to mark @done)'
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
options[:count] = if options[:interactive]
|
44
|
+
0
|
45
|
+
else
|
46
|
+
args[0] ? args[0].to_i : 1
|
47
|
+
end
|
48
|
+
|
49
|
+
options[:search] = options[:search].sub(/^'?/, "'") if options[:search] && options[:exact]
|
50
|
+
|
51
|
+
options[:case] = options[:case].normalize_case
|
52
|
+
options[:date] = false
|
53
|
+
options[:sequential] = false
|
54
|
+
options[:tag] ||= []
|
55
|
+
options[:tag_bool] = options[:bool].normalize_bool
|
56
|
+
options[:tags] = ['done']
|
57
|
+
|
58
|
+
@wwid.tag_last(options)
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,69 @@
|
|
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))? *[\d.*?]+ *)+|(?:[\d.]+ *-+ *[\d.]+))$/
|
18
|
+
|
19
|
+
desc 'List recent changes in Doing'
|
20
|
+
long_desc %(Display a formatted list of changes in recent versions.
|
21
|
+
|
22
|
+
Without flags, displays only the most recent version.
|
23
|
+
Use --lookup or --all for history.)
|
24
|
+
command %i[changes changelog] do |c|
|
25
|
+
c.desc 'Display all versions'
|
26
|
+
c.switch %i[a all], default_value: false, negatable: false
|
27
|
+
|
28
|
+
c.desc %(Look up a specific version. Specify versions as "MAJ.MIN.PATCH", MIN
|
29
|
+
and PATCH are optional. Use > or < to see all changes since or prior
|
30
|
+
to a version.)
|
31
|
+
c.arg_name 'VERSION'
|
32
|
+
c.flag %i[l lookup], must_match: CHANGE_RX
|
33
|
+
|
34
|
+
c.desc %(Show changelogs matching search terms (uses pattern-based searching).
|
35
|
+
Add slashes to search with regular expressions, e.g. `--search "/output.*flag/"`)
|
36
|
+
c.flag %i[s search]
|
37
|
+
|
38
|
+
c.desc 'Only output changes, no version numbers, headers, or dates'
|
39
|
+
c.switch %i[C changes], default_value: false, negatable: false
|
40
|
+
|
41
|
+
c.desc 'Output raw Markdown'
|
42
|
+
c.switch %i[m md markdown], default_value: false, negatable: false
|
43
|
+
|
44
|
+
c.example 'doing changes', desc: 'View changes in the current version'
|
45
|
+
c.example 'doing changes --all', desc: 'See the entire changelog'
|
46
|
+
c.example 'doing changes --lookup 2.0.21', desc: 'See changes from version 2.0.21'
|
47
|
+
c.example 'doing changes --lookup "> 2.1"', desc: 'See all changes since 2.1.0'
|
48
|
+
c.example 'doing changes --search "tags +bool"', desc: 'See all changes containing "tags" and "bool"'
|
49
|
+
c.example 'doing changes -l "> 2.1" -s "pattern"', desc: 'Lookup and search can be combined'
|
50
|
+
|
51
|
+
c.action do |_global_options, options, _args|
|
52
|
+
cl = Doing::Changes.new(lookup: options[:lookup], search: options[:search], changes_only: options[:changes])
|
53
|
+
|
54
|
+
content = if options[:all] || options[:search] || options[:lookup]
|
55
|
+
cl.to_s
|
56
|
+
else
|
57
|
+
cl.latest
|
58
|
+
end
|
59
|
+
|
60
|
+
parsed = if options[:markdown] || !$stdout.isatty
|
61
|
+
content
|
62
|
+
else
|
63
|
+
TTY::Markdown.parse(content, width: 80, theme: MARKDOWN_THEME, symbols: { override: { bullet: '•' } })
|
64
|
+
end
|
65
|
+
|
66
|
+
Doing::Pager.paginate = true
|
67
|
+
Doing::Pager.page parsed
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# @@choose
|
2
|
+
desc 'Select a section to display from a menu'
|
3
|
+
command :choose do |c|
|
4
|
+
c.action do |_global_options, _options, _args|
|
5
|
+
section = @wwid.choose_section
|
6
|
+
|
7
|
+
Doing::Pager.page @wwid.list_section({ section: section.cap_first, count: 0 }) if section
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# @@colors
|
2
|
+
desc 'List available color variables for configuration templates and views'
|
3
|
+
command :colors do |c|
|
4
|
+
c.action do |_global_options, _options, _args|
|
5
|
+
bgs = []
|
6
|
+
fgs = []
|
7
|
+
@colors::attributes.each do |color|
|
8
|
+
colname = color.to_s
|
9
|
+
colname << " (#{color.to_s.sub(/bold/, 'bright')})" if colname =~ /bold/
|
10
|
+
if color.to_s =~ /bg/
|
11
|
+
bgs.push("#{@colors.send(color, " ")}#{@colors.default} <-- #{colname}")
|
12
|
+
else
|
13
|
+
fgs.push("#{@colors.send(color, "XXXX")}#{@colors.default} <-- #{colname}")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
out = []
|
17
|
+
out << fgs.join("\n")
|
18
|
+
out << bgs.join("\n")
|
19
|
+
Doing::Pager.page out.join("\n")
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @@commands
|
4
|
+
desc 'Enable and disable Doing commands'
|
5
|
+
command :commands do |c|
|
6
|
+
c.example 'doing commands add', desc: 'Get a menu of available commands'
|
7
|
+
c.example 'doing commands add COMMAND', desc: 'Specify a command to enable'
|
8
|
+
c.example 'doing commands remove COMMAND', desc: 'Specify a command to disable'
|
9
|
+
|
10
|
+
c.default_command :add
|
11
|
+
|
12
|
+
# @@commands.enable
|
13
|
+
c.desc 'Enable Doing commands'
|
14
|
+
c.long_desc 'Run without arguments to select commands from a list.'
|
15
|
+
c.arg_name 'COMMAND [COMMAND...]'
|
16
|
+
c.command %i[add enable] do |add|
|
17
|
+
add.action do |_global, _options, args|
|
18
|
+
cfg = @settings
|
19
|
+
custom_dir = @settings.dig('plugins', 'command_path')
|
20
|
+
|
21
|
+
available = cfg['disabled_commands']
|
22
|
+
raise UserCancelled, 'No commands available to enable' unless args.good? || available.good?
|
23
|
+
|
24
|
+
to_enable = if args.good?
|
25
|
+
args
|
26
|
+
else
|
27
|
+
Doing::Prompt.choose_from(available,
|
28
|
+
prompt: 'Select commands to enable',
|
29
|
+
multiple: true,
|
30
|
+
sorted: true)
|
31
|
+
end
|
32
|
+
raise UserCancelled unless to_enable
|
33
|
+
|
34
|
+
to_enable.strip.split("\n").each do |cmd|
|
35
|
+
default_command = File.join(File.dirname(__FILE__), "#{cmd}.rb")
|
36
|
+
custom_command = File.join(File.expand_path(custom_dir), "#{cmd}.rb")
|
37
|
+
unless File.exist?(default_command) || File.exist?(custom_command)
|
38
|
+
raise InvalidArgument, "Command #{cmd} not found"
|
39
|
+
end
|
40
|
+
|
41
|
+
raise InvalidArgument, "Command #{cmd} is not disabled" unless available.include?(cmd)
|
42
|
+
|
43
|
+
available.delete(cmd)
|
44
|
+
end
|
45
|
+
|
46
|
+
cfg.deep_set(['disabled_commands'], available)
|
47
|
+
|
48
|
+
Doing::Util.write_to_file(@config.config_file, YAML.dump(cfg), backup: true)
|
49
|
+
Doing.logger.warn('Config:', "#{@config.config_file} updated")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# @@commands.disable
|
54
|
+
c.desc 'Disable Doing commands'
|
55
|
+
c.command %i[remove disable] do |remove|
|
56
|
+
remove.action do |_global, _options, args|
|
57
|
+
available = Dir.glob(File.join(File.dirname(__FILE__), '*.rb')).map { |cmd| File.basename(cmd, '.rb') }
|
58
|
+
cfg = @settings
|
59
|
+
custom_dir = @settings.dig('plugins', 'command_path')
|
60
|
+
custom_commands = Dir.glob(File.join(File.expand_path(custom_dir), '*.rb'))
|
61
|
+
available.concat(custom_commands.map { |cmd| File.basename(cmd, '.rb') })
|
62
|
+
disabled = cfg['disabled_commands']
|
63
|
+
disabled.each { |cmd| available.delete(cmd) }
|
64
|
+
to_disable = if args.good?
|
65
|
+
args
|
66
|
+
else
|
67
|
+
Doing::Prompt.choose_from(available,
|
68
|
+
prompt: 'Select commands to enable',
|
69
|
+
multiple: true,
|
70
|
+
sorted: true).strip.split("\n")
|
71
|
+
end
|
72
|
+
to_disable.each do |cmd|
|
73
|
+
default_command = File.join(File.dirname(__FILE__), "#{cmd}.rb")
|
74
|
+
custom_command = File.join(File.expand_path(custom_dir), "#{cmd}.rb")
|
75
|
+
unless File.exist?(default_command) || File.exist?(custom_command)
|
76
|
+
raise InvalidArgument, "Command #{cmd} not found"
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
raise InvalidArgument, "Command #{cmd} is not enabled" unless available.include?(cmd)
|
81
|
+
end
|
82
|
+
|
83
|
+
cfg.deep_set(['disabled_commands'], disabled.concat(to_disable))
|
84
|
+
|
85
|
+
Doing::Util.write_to_file(@config.config_file, YAML.dump(cfg), backup: true)
|
86
|
+
Doing.logger.warn('Config:', "#{@config.config_file} updated")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @@commands_accepting
|
4
|
+
arg_name 'OPTION'
|
5
|
+
command :commands_accepting do |c|
|
6
|
+
c.desc 'Output in single column for completion'
|
7
|
+
c.switch %i[c column]
|
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
|
+
|
14
|
+
c.action do |g, o, a|
|
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
|
47
|
+
end
|
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
|
61
|
+
|
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)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
true
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @@completion
|
4
|
+
desc 'Generate shell completion scripts'
|
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.'
|
7
|
+
command :completion do |c|
|
8
|
+
c.example 'doing completion', desc: 'Output zsh (default) to STDOUT'
|
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'
|
15
|
+
|
16
|
+
c.desc 'Shell to generate for (bash, zsh, fish)'
|
17
|
+
c.arg_name 'SHELL'
|
18
|
+
c.flag %i[t type], must_match: /^(?:[bzf](?:[ai]?sh)?|all)$/i, default_value: 'zsh'
|
19
|
+
|
20
|
+
c.desc 'File to write output to'
|
21
|
+
c.arg_name 'PATH'
|
22
|
+
c.flag %i[f file], default_value: 'STDOUT'
|
23
|
+
|
24
|
+
c.action do |_global_options, options, _args|
|
25
|
+
Doing::Completion.generate_completion(type: options[:type], file: options[:file])
|
26
|
+
end
|
27
|
+
end
|