doing 2.0.19 → 2.0.20
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/Gemfile.lock +15 -5
- data/README.md +1 -1
- data/bin/doing +2 -18
- data/doing.gemspec +5 -4
- data/doing.rdoc +2 -2
- data/generate_completions.sh +3 -3
- data/lib/doing/cli_status.rb +6 -2
- data/lib/doing/completion/bash_completion.rb +185 -0
- data/lib/doing/completion/fish_completion.rb +175 -0
- data/lib/doing/completion/string.rb +17 -0
- data/lib/doing/completion/zsh_completion.rb +140 -0
- data/lib/doing/completion.rb +39 -0
- data/lib/doing/version.rb +1 -1
- data/lib/doing/wwid.rb +16 -5
- data/lib/doing.rb +1 -1
- data/scripts/generate_bash_completions.rb +6 -12
- data/scripts/generate_fish_completions.rb +7 -16
- data/scripts/generate_zsh_completions.rb +6 -15
- metadata +58 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 29a3fd2f95b1eb4a02f49bddca32255e0f56b93693a4114d004181d6c309d453
|
4
|
+
data.tar.gz: 696931fdda6f08e136225ceb6e47425f171f86b222a8313cd485a21ab7222ac3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a60c786a031b42be76cc10cacecf7247363369facf8584df5fd7790a9ea0dd6ccd148b460fa121aacada61a9d86a33b6a0827cda20e0b28d9614affe464ccccc
|
7
|
+
data.tar.gz: f47889440ee5ed7e53f227086139705b90b30004bb0c815f1aff3ffc9f6faa35cb47707c330476f73a47d56fd88963430e1ffb6b26e8c2b9f045e6c18685bdff
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
doing (2.0.
|
4
|
+
doing (2.0.20)
|
5
5
|
chronic (~> 0.10, >= 0.10.2)
|
6
6
|
deep_merge (~> 1.2, >= 1.2.1)
|
7
7
|
gli (~> 2.19, >= 2.19.2)
|
8
8
|
haml (~> 5.0.0, >= 5.0.0)
|
9
9
|
safe_yaml (~> 1.0)
|
10
|
+
tty-progressbar (~> 0.18, >= 0.18.2)
|
10
11
|
|
11
12
|
GEM
|
12
13
|
remote: http://rubygems.org/
|
@@ -89,6 +90,7 @@ GEM
|
|
89
90
|
rspec-support (~> 3.10.0)
|
90
91
|
rspec-support (3.10.3)
|
91
92
|
safe_yaml (1.0.5)
|
93
|
+
strings-ansi (0.2.0)
|
92
94
|
sys-uname (1.2.2)
|
93
95
|
ffi (~> 1.1)
|
94
96
|
temple (0.8.2)
|
@@ -97,8 +99,16 @@ GEM
|
|
97
99
|
thor (1.1.0)
|
98
100
|
thread_safe (0.3.6)
|
99
101
|
tilt (2.0.10)
|
102
|
+
tty-cursor (0.7.1)
|
103
|
+
tty-progressbar (0.18.2)
|
104
|
+
strings-ansi (~> 0.2)
|
105
|
+
tty-cursor (~> 0.7)
|
106
|
+
tty-screen (~> 0.8)
|
107
|
+
unicode-display_width (>= 1.6, < 3.0)
|
108
|
+
tty-screen (0.8.1)
|
100
109
|
tzinfo (2.0.4)
|
101
110
|
concurrent-ruby (~> 1.0)
|
111
|
+
unicode-display_width (2.1.0)
|
102
112
|
yard (0.9.26)
|
103
113
|
zeitwerk (2.5.1)
|
104
114
|
|
@@ -108,13 +118,13 @@ PLATFORMS
|
|
108
118
|
DEPENDENCIES
|
109
119
|
aruba (~> 1.0.2)
|
110
120
|
doing!
|
111
|
-
github-markup
|
112
|
-
parallel_tests
|
121
|
+
github-markup (~> 4.0, >= 4.0.0)
|
122
|
+
parallel_tests (~> 3.7, >= 3.7.3)
|
113
123
|
rake (~> 13.0, >= 13.0.1)
|
114
124
|
rdoc (~> 6.3.1)
|
115
|
-
redcarpet
|
125
|
+
redcarpet (~> 3.5, >= 3.5.1)
|
116
126
|
test-unit (~> 3.4.4)
|
117
|
-
yard
|
127
|
+
yard (~> 0.9, >= 0.9.26)
|
118
128
|
|
119
129
|
BUNDLED WITH
|
120
130
|
2.2.17
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@ _If you're one of the rare people like me who find this useful, feel free to [bu
|
|
6
6
|
|
7
7
|
<!--README-->
|
8
8
|
|
9
|
-
The current version of `doing` is <!--VER-->2.0.
|
9
|
+
The current version of `doing` is <!--VER-->2.0.19<!--END VER-->.
|
10
10
|
|
11
11
|
Find all of the documentation in the [doing wiki](https://github.com/ttscoff/doing/wiki).
|
12
12
|
|
data/bin/doing
CHANGED
@@ -2149,28 +2149,12 @@ command :completion do |c|
|
|
2149
2149
|
|
2150
2150
|
c.desc 'File to write output to'
|
2151
2151
|
c.arg_name 'PATH'
|
2152
|
-
c.flag %i[f file], default_value: '
|
2152
|
+
c.flag %i[f file], default_value: 'STDOUT'
|
2153
2153
|
|
2154
2154
|
c.action do |_global_options, options, _args|
|
2155
2155
|
script_dir = File.join(File.dirname(__FILE__), '..', 'scripts')
|
2156
2156
|
|
2157
|
-
|
2158
|
-
when /^b/
|
2159
|
-
result = `ruby #{File.join(script_dir, 'generate_bash_completions.rb')}`
|
2160
|
-
when /^z/
|
2161
|
-
result = `ruby #{File.join(script_dir, 'generate_zsh_completions.rb')}`
|
2162
|
-
when /^f/
|
2163
|
-
result = `ruby #{File.join(script_dir, 'generate_fish_completions.rb')}`
|
2164
|
-
end
|
2165
|
-
|
2166
|
-
if options[:file] =~ /^stdout$/i
|
2167
|
-
$stdout.puts result
|
2168
|
-
else
|
2169
|
-
File.open(File.expand_path(options[:file]), 'w') do |f|
|
2170
|
-
f.puts result
|
2171
|
-
end
|
2172
|
-
Doing.logger.warn('File written:', "#{options[:type]} completions written to #{options[:file]}")
|
2173
|
-
end
|
2157
|
+
Doing::Completion.generate_completion(type: options[:type], file: options[:file])
|
2174
2158
|
end
|
2175
2159
|
end
|
2176
2160
|
|
data/doing.gemspec
CHANGED
@@ -27,10 +27,11 @@ spec = Gem::Specification.new do |s|
|
|
27
27
|
s.add_development_dependency 'rdoc', '~> 6.3.1'
|
28
28
|
s.add_development_dependency 'aruba', '~> 1.0.2'
|
29
29
|
s.add_development_dependency 'test-unit', '~> 3.4.4'
|
30
|
-
s.add_development_dependency 'yard'
|
31
|
-
s.add_development_dependency 'redcarpet'
|
32
|
-
s.add_development_dependency 'github-markup'
|
33
|
-
s.add_development_dependency 'parallel_tests'
|
30
|
+
s.add_development_dependency 'yard', '~> 0.9', '>= 0.9.26'
|
31
|
+
s.add_development_dependency 'redcarpet', '~> 3.5', '>= 3.5.1'
|
32
|
+
s.add_development_dependency 'github-markup', '~> 4.0', '>= 4.0.0'
|
33
|
+
s.add_development_dependency 'parallel_tests', '~> 3.7', '>= 3.7.3'
|
34
|
+
s.add_runtime_dependency('tty-progressbar', '~> 0.18', '>= 0.18.2')
|
34
35
|
s.add_runtime_dependency('gli', '~> 2.19', '>= 2.19.2')
|
35
36
|
s.add_runtime_dependency('haml','~>5.0.0', '>= 5.0.0')
|
36
37
|
s.add_runtime_dependency('chronic','~> 0.10', '>= 0.10.2')
|
data/doing.rdoc
CHANGED
@@ -5,7 +5,7 @@ record of what you've been doing, complete with tag-based time tracking. The
|
|
5
5
|
command line tool allows you to add entries, annotate with tags and notes, and
|
6
6
|
view your entries with myriad options, with a focus on a "natural" language syntax.
|
7
7
|
|
8
|
-
v2.0.
|
8
|
+
v2.0.20
|
9
9
|
|
10
10
|
=== Global Options
|
11
11
|
=== --config_file arg
|
@@ -374,7 +374,7 @@ Generate shell completion scripts
|
|
374
374
|
|
375
375
|
File to write output to
|
376
376
|
|
377
|
-
[Default Value]
|
377
|
+
[Default Value] STDOUT
|
378
378
|
|
379
379
|
|
380
380
|
===== -t|--type SHELL
|
data/generate_completions.sh
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#!/bin/bash
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
bundle exec bin/doing completion --type fish --file lib/completion/doing.fish
|
4
|
+
bundle exec bin/doing completion --type bash --file lib/completion/doing.bash
|
5
|
+
bundle exec bin/doing completion --type zsh --file lib/completion/_doing.zsh
|
data/lib/doing/cli_status.rb
CHANGED
@@ -14,8 +14,12 @@ module Status
|
|
14
14
|
$stderr.print format("#{esc['kill']}#{esc['boldyellow']}> #{esc['boldgreen']}%s #{esc['white']}[#{esc['boldwhite']}%#{@commands.count.to_s.length}d#{esc['boldblack']}/#{esc['boldyellow']}%d#{esc['white']}]: #{esc['boldcyan']}%s#{esc['default']}\r", msg, idx, total, tail)
|
15
15
|
end
|
16
16
|
|
17
|
-
def status(msg, reset: true)
|
18
|
-
$stderr.print format("#{esc['kill']}#{esc['boldyellow']}> #{esc['whiteboard']}%s#{esc['default']}%s", msg, reset ? "\r" :
|
17
|
+
def status(msg, reset: true, end_char: "\n")
|
18
|
+
$stderr.print format("#{esc['kill']}#{esc['boldyellow']}> #{esc['whiteboard']}%s#{esc['default']}%s", msg, reset ? "\r" : end_char)
|
19
|
+
end
|
20
|
+
|
21
|
+
def msg(msg, reset: true, color: 'green', end_char: "\n")
|
22
|
+
$stderr.print format("#{esc['kill']}#{esc[color]}%s#{esc['default']}%s", msg, reset ? "\r" : end_char)
|
19
23
|
end
|
20
24
|
|
21
25
|
def clear
|
@@ -0,0 +1,185 @@
|
|
1
|
+
module Doing
|
2
|
+
module Completion
|
3
|
+
class BashCompletions
|
4
|
+
attr_accessor :commands, :global_options
|
5
|
+
|
6
|
+
def main_function
|
7
|
+
first = true
|
8
|
+
out = []
|
9
|
+
logic = []
|
10
|
+
need_export = []
|
11
|
+
|
12
|
+
@commands.each_with_index do |cmd, i|
|
13
|
+
@bar.advance
|
14
|
+
|
15
|
+
data = get_help_sections(cmd[:commands].first)
|
16
|
+
|
17
|
+
arg = data[:synopsis].join(' ').strip.split(/ /).last
|
18
|
+
case arg
|
19
|
+
when /(path|file)/i
|
20
|
+
type = :file
|
21
|
+
when /sect/i
|
22
|
+
type = 'sections'
|
23
|
+
when /view/i
|
24
|
+
type = 'views'
|
25
|
+
else
|
26
|
+
type = nil
|
27
|
+
end
|
28
|
+
|
29
|
+
if data[:command_options]
|
30
|
+
options = parse_options(data[:command_options])
|
31
|
+
out << command_function(cmd[:commands].first, options, type)
|
32
|
+
|
33
|
+
if first
|
34
|
+
op = 'if'
|
35
|
+
first = false
|
36
|
+
else
|
37
|
+
op = 'elif'
|
38
|
+
end
|
39
|
+
logic << %(#{op} [[ $last =~ (#{cmd[:commands].join('|')}) ]]; then _doing_#{cmd[:commands].first})
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
out << <<~EOFUNC
|
44
|
+
_doing()
|
45
|
+
{
|
46
|
+
local last="${@: -1}"
|
47
|
+
local token=${COMP_WORDS[$COMP_CWORD]}
|
48
|
+
|
49
|
+
#{logic.join("\n ")}
|
50
|
+
else
|
51
|
+
OLD_IFS="$IFS"
|
52
|
+
IFS=$'\n'
|
53
|
+
COMPREPLY=( $(compgen -W "$(doing help -c)" -- $token) )
|
54
|
+
IFS="$OLD_IFS"
|
55
|
+
fi
|
56
|
+
}
|
57
|
+
EOFUNC
|
58
|
+
out.join("\n")
|
59
|
+
end
|
60
|
+
|
61
|
+
def command_function(command, options, type)
|
62
|
+
long_options = []
|
63
|
+
short_options = []
|
64
|
+
|
65
|
+
options.each do |o|
|
66
|
+
next if o.nil?
|
67
|
+
|
68
|
+
long_options << o[:long] if o[:long]
|
69
|
+
short_options << o[:short] if o[:short]
|
70
|
+
end
|
71
|
+
|
72
|
+
long = long_options.map! {|o| "--#{o}"}.join(' ')
|
73
|
+
short = short_options.map! {|o| "-#{o}"}.join(' ')
|
74
|
+
words = ''
|
75
|
+
logic = ''
|
76
|
+
words, logic = get_words(type) if type && type.is_a?(String)
|
77
|
+
|
78
|
+
func = <<~ENDFUNC
|
79
|
+
_doing_#{command}() {
|
80
|
+
#{words}
|
81
|
+
if [[ "$token" == --* ]]; then
|
82
|
+
COMPREPLY=( $( compgen -W '#{long}' -- $token ) )
|
83
|
+
elif [[ "$token" == -* ]]; then
|
84
|
+
COMPREPLY=( $( compgen -W '#{short} #{long}' -- $token ) )
|
85
|
+
#{logic}
|
86
|
+
fi
|
87
|
+
}
|
88
|
+
ENDFUNC
|
89
|
+
|
90
|
+
func
|
91
|
+
end
|
92
|
+
|
93
|
+
def get_words(type)
|
94
|
+
func = <<~EOFUNC
|
95
|
+
OLD_IFS="$IFS"
|
96
|
+
local token=${COMP_WORDS[$COMP_CWORD]}
|
97
|
+
IFS=$'\t'
|
98
|
+
local words=$(doing #{type})
|
99
|
+
IFS="$OLD_IFS"
|
100
|
+
EOFUNC
|
101
|
+
|
102
|
+
logic = <<~EOLOGIC
|
103
|
+
else
|
104
|
+
local nocasematchWasOff=0
|
105
|
+
shopt nocasematch >/dev/null || nocasematchWasOff=1
|
106
|
+
(( nocasematchWasOff )) && shopt -s nocasematch
|
107
|
+
local w matches=()
|
108
|
+
OLD_IFS="$IFS"
|
109
|
+
IFS=$'\t'‰
|
110
|
+
for w in $words; do
|
111
|
+
if [[ "$w" == "$token"* ]]; then
|
112
|
+
matches+=("${w// /\ }")
|
113
|
+
fi
|
114
|
+
done
|
115
|
+
IFS="$OLD_IFS"
|
116
|
+
(( nocasematchWasOff )) && shopt -u nocasematch
|
117
|
+
COMPREPLY=("${matches[@]}")
|
118
|
+
EOLOGIC
|
119
|
+
|
120
|
+
[func, logic]
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
|
125
|
+
def get_help_sections(command = '')
|
126
|
+
res = `doing help #{command}`.strip
|
127
|
+
scanned = res.scan(/(?m-i)^([A-Z ]+)\n([\s\S]*?)(?=\n+[A-Z]+|\Z)/)
|
128
|
+
sections = {}
|
129
|
+
scanned.each do |sect|
|
130
|
+
title = sect[0].downcase.strip.gsub(/ +/, '_').to_sym
|
131
|
+
content = sect[1].split(/\n/).map(&:strip).delete_if(&:empty?)
|
132
|
+
sections[title] = content
|
133
|
+
end
|
134
|
+
sections
|
135
|
+
end
|
136
|
+
|
137
|
+
def parse_option(option)
|
138
|
+
res = option.match(/(?:-(?<short>\w), )?(?:--(?:\[no-\])?(?<long>[\w_]+)(?:=(?<arg>\w+))?)\s+- (?<desc>.*?)$/)
|
139
|
+
return nil unless res
|
140
|
+
{
|
141
|
+
short: res['short'],
|
142
|
+
long: res['long'],
|
143
|
+
arg: res[:arg],
|
144
|
+
description: res['desc'].short_desc
|
145
|
+
}
|
146
|
+
end
|
147
|
+
|
148
|
+
def parse_options(options)
|
149
|
+
options.map { |opt| parse_option(opt) }
|
150
|
+
end
|
151
|
+
|
152
|
+
def parse_command(command)
|
153
|
+
res = command.match(/^(?<cmd>[^, \t]+)(?<alias>(?:, [^, \t]+)*)?\s+- (?<desc>.*?)$/)
|
154
|
+
commands = [res['cmd']]
|
155
|
+
commands.concat(res['alias'].split(/, /).delete_if(&:empty?)) if res['alias']
|
156
|
+
|
157
|
+
{
|
158
|
+
commands: commands,
|
159
|
+
description: res['desc'].short_desc
|
160
|
+
}
|
161
|
+
end
|
162
|
+
|
163
|
+
def parse_commands(commands)
|
164
|
+
commands.map { |cmd| parse_command(cmd) }
|
165
|
+
end
|
166
|
+
|
167
|
+
def initialize
|
168
|
+
data = get_help_sections
|
169
|
+
@global_options = parse_options(data[:global_options])
|
170
|
+
@commands = parse_commands(data[:commands])
|
171
|
+
@bar = TTY::ProgressBar.new("\033[0;0;33mGenerating Bash completions: \033[0;35;40m[:bar]\033[0m", total: @commands.count, bar_format: :blade)
|
172
|
+
@bar.resize(25)
|
173
|
+
end
|
174
|
+
|
175
|
+
def generate_completions
|
176
|
+
@bar.start
|
177
|
+
out = []
|
178
|
+
out << main_function
|
179
|
+
out << 'complete -F _doing doing'
|
180
|
+
@bar.finish
|
181
|
+
out.join("\n")
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
module Doing
|
2
|
+
module Completion
|
3
|
+
class FishCompletions
|
4
|
+
|
5
|
+
attr_accessor :commands, :global_options
|
6
|
+
|
7
|
+
def generate_helpers
|
8
|
+
<<~EOFUNCTIONS
|
9
|
+
function __fish_doing_needs_command
|
10
|
+
# Figure out if the current invocation already has a command.
|
11
|
+
|
12
|
+
set -l opts h-help config_file= f-doing_file= n-notes v-version stdout d-debug default x-noauto
|
13
|
+
set cmd (commandline -opc)
|
14
|
+
set -e cmd[1]
|
15
|
+
argparse -s $opts -- $cmd 2>/dev/null
|
16
|
+
or return 0
|
17
|
+
# These flags function as commands, effectively.
|
18
|
+
if set -q argv[1]
|
19
|
+
# Also print the command, so this can be used to figure out what it is.
|
20
|
+
echo $argv[1]
|
21
|
+
return 1
|
22
|
+
end
|
23
|
+
return 0
|
24
|
+
end
|
25
|
+
|
26
|
+
function __fish_doing_using_command
|
27
|
+
set -l cmd (__fish_doing_needs_command)
|
28
|
+
test -z "$cmd"
|
29
|
+
and return 1
|
30
|
+
contains -- $cmd $argv
|
31
|
+
and return 0
|
32
|
+
end
|
33
|
+
|
34
|
+
function __fish_doing_complete_sections
|
35
|
+
doing sections -c
|
36
|
+
end
|
37
|
+
|
38
|
+
function __fish_doing_complete_views
|
39
|
+
doing views -c
|
40
|
+
end
|
41
|
+
|
42
|
+
function __fish_doing_subcommands
|
43
|
+
doing help -c
|
44
|
+
end
|
45
|
+
|
46
|
+
function __fish_doing_export_plugins
|
47
|
+
doing plugins --type export -c
|
48
|
+
end
|
49
|
+
|
50
|
+
function __fish_doing_import_plugins
|
51
|
+
doing plugins --type import -c
|
52
|
+
end
|
53
|
+
|
54
|
+
function __fish_doing_complete_templates
|
55
|
+
doing template -c
|
56
|
+
end
|
57
|
+
|
58
|
+
complete -c doing -f
|
59
|
+
complete -xc doing -n '__fish_doing_needs_command' -a '(__fish_doing_subcommands)'
|
60
|
+
|
61
|
+
complete -f -c doing -n '__fish_doing_using_command show' -a '(__fish_doing_complete_sections)'
|
62
|
+
complete -f -c doing -n '__fish_doing_using_command view' -a '(__fish_doing_complete_views)'
|
63
|
+
complete -f -c doing -n '__fish_doing_using_command template' -a '(__fish_doing_complete_templates)'
|
64
|
+
complete -f -c doing -s t -l type -x -n '__fish_doing_using_command import' -a '(__fish_doing_import_plugins)'
|
65
|
+
|
66
|
+
complete -xc doing -n '__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from (doing help -c)' -a "(doing help -c)"
|
67
|
+
EOFUNCTIONS
|
68
|
+
end
|
69
|
+
|
70
|
+
def get_help_sections(command = '')
|
71
|
+
res = `doing help #{command}`.strip
|
72
|
+
scanned = res.scan(/(?m-i)^([A-Z ]+)\n([\s\S]*?)(?=\n+[A-Z]+|\Z)/)
|
73
|
+
sections = {}
|
74
|
+
scanned.each do |sect|
|
75
|
+
title = sect[0].downcase.strip.gsub(/ +/, '_').to_sym
|
76
|
+
content = sect[1].split(/\n/).map(&:strip).delete_if(&:empty?)
|
77
|
+
sections[title] = content
|
78
|
+
end
|
79
|
+
sections
|
80
|
+
end
|
81
|
+
|
82
|
+
def parse_option(option)
|
83
|
+
res = option.match(/(?:-(?<short>\w), )?(?:--(?:\[no-\])?(?<long>[\w_]+)(?:=(?<arg>\w+))?)\s+- (?<desc>.*?)$/)
|
84
|
+
return nil unless res
|
85
|
+
{
|
86
|
+
short: res['short'],
|
87
|
+
long: res['long'],
|
88
|
+
arg: res[:arg],
|
89
|
+
description: res['desc'].short_desc
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
93
|
+
def parse_options(options)
|
94
|
+
options.map { |opt| parse_option(opt) }
|
95
|
+
end
|
96
|
+
|
97
|
+
def parse_command(command)
|
98
|
+
res = command.match(/^(?<cmd>[^, \t]+)(?<alias>(?:, [^, \t]+)*)?\s+- (?<desc>.*?)$/)
|
99
|
+
commands = [res['cmd']]
|
100
|
+
commands.concat(res['alias'].split(/, /).delete_if(&:empty?)) if res['alias']
|
101
|
+
|
102
|
+
{
|
103
|
+
commands: commands,
|
104
|
+
description: res['desc'].short_desc
|
105
|
+
}
|
106
|
+
end
|
107
|
+
|
108
|
+
def parse_commands(commands)
|
109
|
+
commands.map { |cmd| parse_command(cmd) }
|
110
|
+
end
|
111
|
+
|
112
|
+
def generate_subcommand_completions
|
113
|
+
out = []
|
114
|
+
@commands.each_with_index do |cmd, i|
|
115
|
+
out << "complete -xc doing -n '__fish_doing_needs_command' -a '#{cmd[:commands].join(' ')}' -d #{Shellwords.escape(cmd[:description])}"
|
116
|
+
end
|
117
|
+
|
118
|
+
out.join("\n")
|
119
|
+
end
|
120
|
+
|
121
|
+
def generate_subcommand_option_completions
|
122
|
+
|
123
|
+
out = []
|
124
|
+
need_export = []
|
125
|
+
|
126
|
+
@commands.each_with_index do |cmd, i|
|
127
|
+
@bar.advance
|
128
|
+
data = get_help_sections(cmd[:commands].first)
|
129
|
+
|
130
|
+
if data[:synopsis].join(' ').strip.split(/ /).last =~ /(path|file)/i
|
131
|
+
out << "complete -c doing -F -n '__fish_doing_using_command #{cmd[:commands].join(" ")}'"
|
132
|
+
end
|
133
|
+
|
134
|
+
if data[:command_options]
|
135
|
+
parse_options(data[:command_options]).each do |option|
|
136
|
+
next if option.nil?
|
137
|
+
|
138
|
+
arg = option[:arg] ? '-r' : ''
|
139
|
+
short = option[:short] ? "-s #{option[:short]}" : ''
|
140
|
+
long = option[:long] ? "-l #{option[:long]}" : ''
|
141
|
+
out << "complete -c doing #{long} #{short} -f #{arg} -n '__fish_doing_using_command #{cmd[:commands].join(' ')}' -d #{Shellwords.escape(option[:description])}"
|
142
|
+
|
143
|
+
need_export.concat(cmd[:commands]) if option[:long] == 'output'
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
unless need_export.empty?
|
149
|
+
out << "complete -f -c doing -s o -l output -x -n '__fish_doing_using_command #{need_export.join(' ')}' -a '(__fish_doing_export_plugins)'"
|
150
|
+
end
|
151
|
+
|
152
|
+
# clear
|
153
|
+
out.join("\n")
|
154
|
+
end
|
155
|
+
|
156
|
+
def initialize
|
157
|
+
data = get_help_sections
|
158
|
+
@global_options = parse_options(data[:global_options])
|
159
|
+
@commands = parse_commands(data[:commands])
|
160
|
+
@bar = TTY::ProgressBar.new("\033[0;0;33mGenerating Fish completions: \033[0;35;40m[:bar]\033[0m", total: @commands.count, bar_format: :blade)
|
161
|
+
@bar.resize(25)
|
162
|
+
end
|
163
|
+
|
164
|
+
def generate_completions
|
165
|
+
@bar.start
|
166
|
+
out = []
|
167
|
+
out << generate_helpers
|
168
|
+
out << generate_subcommand_completions
|
169
|
+
out << generate_subcommand_option_completions
|
170
|
+
@bar.finish
|
171
|
+
out.join("\n")
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class ::String
|
2
|
+
def short_desc
|
3
|
+
split(/[,.]/)[0].sub(/ \(.*?\)?$/, '').strip
|
4
|
+
end
|
5
|
+
|
6
|
+
def ltrunc(max)
|
7
|
+
if length > max
|
8
|
+
sub(/^.*?(.{#{max - 3}})$/, '...\1')
|
9
|
+
else
|
10
|
+
self
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def ltrunc!(max)
|
15
|
+
replace ltrunc(max)
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
module Doing
|
2
|
+
module Completion
|
3
|
+
class ZshCompletions
|
4
|
+
|
5
|
+
attr_accessor :commands, :global_options
|
6
|
+
|
7
|
+
def generate_helpers
|
8
|
+
out=<<~EOFUNCTIONS
|
9
|
+
compdef _doing doing
|
10
|
+
|
11
|
+
function _doing() {
|
12
|
+
local line state
|
13
|
+
|
14
|
+
function _commands {
|
15
|
+
local -a commands
|
16
|
+
|
17
|
+
commands=(
|
18
|
+
#{generate_subcommand_completions.join("\n ")}
|
19
|
+
)
|
20
|
+
_describe 'command' commands
|
21
|
+
}
|
22
|
+
|
23
|
+
_arguments -C \
|
24
|
+
"1: :_commands" \
|
25
|
+
"*::arg:->args"
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
case $line[1] in
|
30
|
+
#{generate_subcommand_option_completions(indent: ' ').join("\n ")}
|
31
|
+
esac
|
32
|
+
|
33
|
+
_arguments -s $args
|
34
|
+
}
|
35
|
+
|
36
|
+
EOFUNCTIONS
|
37
|
+
@bar.finish
|
38
|
+
out
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_help_sections(command = '')
|
42
|
+
res = `doing help #{command}`.strip
|
43
|
+
scanned = res.scan(/(?m-i)^([A-Z ]+)\n([\s\S]*?)(?=\n+[A-Z]+|\Z)/)
|
44
|
+
sections = {}
|
45
|
+
scanned.each do |sect|
|
46
|
+
title = sect[0].downcase.strip.gsub(/ +/, '_').to_sym
|
47
|
+
content = sect[1].split(/\n/).map(&:strip).delete_if(&:empty?)
|
48
|
+
sections[title] = content
|
49
|
+
end
|
50
|
+
sections
|
51
|
+
end
|
52
|
+
|
53
|
+
def parse_option(option)
|
54
|
+
res = option.match(/(?:-(?<short>\w), )?(?:--(?:\[no-\])?(?<long>[\w_]+)(?:=(?<arg>\w+))?)\s+- (?<desc>.*?)$/)
|
55
|
+
return nil unless res
|
56
|
+
|
57
|
+
{
|
58
|
+
short: res['short'],
|
59
|
+
long: res['long'],
|
60
|
+
arg: res[:arg],
|
61
|
+
description: res['desc'].short_desc
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
def parse_options(options)
|
66
|
+
options.map { |opt| parse_option(opt) }
|
67
|
+
end
|
68
|
+
|
69
|
+
def parse_command(command)
|
70
|
+
res = command.match(/^(?<cmd>[^, \t]+)(?<alias>(?:, [^, \t]+)*)?\s+- (?<desc>.*?)$/)
|
71
|
+
commands = [res['cmd']]
|
72
|
+
commands.concat(res['alias'].split(/, /).delete_if(&:empty?)) if res['alias']
|
73
|
+
|
74
|
+
{
|
75
|
+
commands: commands,
|
76
|
+
description: res['desc'].short_desc
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
def parse_commands(commands)
|
81
|
+
commands.map { |cmd| parse_command(cmd) }
|
82
|
+
end
|
83
|
+
|
84
|
+
def generate_subcommand_completions
|
85
|
+
out = []
|
86
|
+
@commands.each_with_index do |cmd, i|
|
87
|
+
cmd[:commands].each do |c|
|
88
|
+
out << "'#{c}:#{cmd[:description].gsub(/'/, '\\\'')}'"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
out
|
92
|
+
end
|
93
|
+
|
94
|
+
def generate_subcommand_option_completions(indent: ' ')
|
95
|
+
|
96
|
+
out = []
|
97
|
+
|
98
|
+
@commands.each_with_index do |cmd, i|
|
99
|
+
@bar.advance
|
100
|
+
|
101
|
+
data = get_help_sections(cmd[:commands].first)
|
102
|
+
option_arr = []
|
103
|
+
|
104
|
+
if data[:command_options]
|
105
|
+
parse_options(data[:command_options]).each do |option|
|
106
|
+
next if option.nil?
|
107
|
+
|
108
|
+
arg = option[:arg] ? '=' : ''
|
109
|
+
|
110
|
+
option_arr << if option[:short]
|
111
|
+
%({-#{option[:short]},--#{option[:long]}#{arg}}"[#{option[:description].gsub(/'/, '\\\'')}]")
|
112
|
+
else
|
113
|
+
%("(--#{option[:long]}#{arg})--#{option[:long]}#{arg}}[#{option[:description].gsub(/'/, '\\\'')}]")
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
cmd[:commands].each do |c|
|
119
|
+
out << "#{c}) \n#{indent} args=( #{option_arr.join(' ')} )\n#{indent};;"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
out
|
124
|
+
end
|
125
|
+
|
126
|
+
def initialize
|
127
|
+
data = get_help_sections
|
128
|
+
@global_options = parse_options(data[:global_options])
|
129
|
+
@commands = parse_commands(data[:commands])
|
130
|
+
@bar = TTY::ProgressBar.new(" \033[0;0;33mGenerating Zsh completions: \033[0;35;40m[:bar]\033[0m", total: @commands.count, bar_format: :blade)
|
131
|
+
@bar.resize(25)
|
132
|
+
end
|
133
|
+
|
134
|
+
def generate_completions
|
135
|
+
@bar.start
|
136
|
+
generate_helpers
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'tty-progressbar'
|
4
|
+
|
5
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'completion'))
|
6
|
+
require 'string'
|
7
|
+
require 'fish_completion'
|
8
|
+
require 'zsh_completion'
|
9
|
+
require 'bash_completion'
|
10
|
+
|
11
|
+
module Doing
|
12
|
+
# Completion script generator
|
13
|
+
module Completion
|
14
|
+
class << self
|
15
|
+
def generate_completion(type: 'zsh', file: 'stdout')
|
16
|
+
|
17
|
+
generator = case type.to_s
|
18
|
+
when /^f/
|
19
|
+
FishCompletions.new
|
20
|
+
when /^b/
|
21
|
+
BashCompletions.new
|
22
|
+
else
|
23
|
+
ZshCompletions.new
|
24
|
+
end
|
25
|
+
|
26
|
+
result = generator.generate_completions
|
27
|
+
|
28
|
+
if file =~ /^stdout$/i
|
29
|
+
$stdout.puts result
|
30
|
+
else
|
31
|
+
File.open(File.expand_path(file), 'w') do |f|
|
32
|
+
f.puts result
|
33
|
+
end
|
34
|
+
Doing.logger.warn('File written:', "#{type} completions written to #{file}")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/doing/version.rb
CHANGED
data/lib/doing/wwid.rb
CHANGED
@@ -611,6 +611,22 @@ module Doing
|
|
611
611
|
last_entry
|
612
612
|
end
|
613
613
|
|
614
|
+
def fzf
|
615
|
+
fzf_dir = File.join(File.dirname(__FILE__), '../helpers/fzf')
|
616
|
+
FileUtils.mkdir_p(fzf_dir) unless File.directory?(fzf_dir)
|
617
|
+
fzf = File.join(fzf_dir, 'bin/fzf')
|
618
|
+
return fzf if File.exist?(fzf)
|
619
|
+
|
620
|
+
Doing.logger.log_now(:warn, 'Downloading and installing FZF. This will only happen once')
|
621
|
+
Doing.logger.log_now(:warn, 'fzf is copyright Junegunn Choi <https://github.com/junegunn/fzf/blob/master/LICENSE>')
|
622
|
+
res = `git clone --depth 1 https://github.com/junegunn/fzf.git #{fzf_dir}`
|
623
|
+
res = `#{fzf_dir}/install --bin --no-key-bindings --no-completion --no-update-rc --no-bash --no-zsh --no-fish`
|
624
|
+
|
625
|
+
raise DoingRuntimeError unless File.exist?(fzf)
|
626
|
+
|
627
|
+
fzf
|
628
|
+
end
|
629
|
+
|
614
630
|
##
|
615
631
|
## Generate a menu of options and allow user selection
|
616
632
|
##
|
@@ -619,7 +635,6 @@ module Doing
|
|
619
635
|
def choose_from(options, prompt: 'Make a selection: ', multiple: false, sorted: true, fzf_args: [])
|
620
636
|
return nil unless $stdout.isatty
|
621
637
|
|
622
|
-
fzf = File.join(File.dirname(__FILE__), '../helpers/fuzzyfilefinder')
|
623
638
|
# fzf_args << '-1' # User is expecting a menu, and even if only one it seves as confirmation
|
624
639
|
fzf_args << %(--prompt "#{prompt}")
|
625
640
|
fzf_args << '--multi' if multiple
|
@@ -653,8 +668,6 @@ module Doing
|
|
653
668
|
def fuzzy_filter_items(items, opt: {})
|
654
669
|
scannable = items.map.with_index { |item, idx| "#{item.title} #{item.note.join(' ')}".gsub(/[|*?!]/, '') + "|#{idx}" }.join("\n")
|
655
670
|
|
656
|
-
fzf = File.join(File.dirname(__FILE__), '../helpers/fuzzyfilefinder')
|
657
|
-
|
658
671
|
fzf_args = [
|
659
672
|
'--multi',
|
660
673
|
%(--filter="#{opt[:search].sub(/^'?/, "'")}"),
|
@@ -869,8 +882,6 @@ module Doing
|
|
869
882
|
out.join('')
|
870
883
|
end
|
871
884
|
|
872
|
-
fzf = File.join(File.dirname(__FILE__), '../helpers/fuzzyfilefinder')
|
873
|
-
|
874
885
|
fzf_args = [
|
875
886
|
%(--header="#{opt[:header]}"),
|
876
887
|
%(--prompt="#{opt[:prompt].sub(/ *$/, ' ')}"),
|
data/lib/doing.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
2
|
require 'doing/version'
|
4
3
|
require 'time'
|
5
4
|
require 'date'
|
@@ -30,6 +29,7 @@ require 'doing/errors'
|
|
30
29
|
require 'doing/hooks'
|
31
30
|
require 'doing/plugin_manager'
|
32
31
|
require 'doing/pager'
|
32
|
+
require 'doing/completion'
|
33
33
|
# require 'doing/markdown_document_listener'
|
34
34
|
|
35
35
|
# Main doing module
|
@@ -1,7 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'doing/cli_status'
|
4
|
-
|
2
|
+
require 'tty-progressbar'
|
5
3
|
require 'shellwords'
|
6
4
|
|
7
5
|
class ::String
|
@@ -23,8 +21,6 @@ class ::String
|
|
23
21
|
end
|
24
22
|
|
25
23
|
class BashCompletions
|
26
|
-
include Status
|
27
|
-
|
28
24
|
attr_accessor :commands, :global_options
|
29
25
|
|
30
26
|
def main_function
|
@@ -32,12 +28,9 @@ class BashCompletions
|
|
32
28
|
out = []
|
33
29
|
logic = []
|
34
30
|
need_export = []
|
35
|
-
# processing = []
|
36
31
|
|
37
32
|
@commands.each_with_index do |cmd, i|
|
38
|
-
|
39
|
-
processing = cmd[:commands]
|
40
|
-
progress('Processing subcommand options', i, @commands.count, processing)
|
33
|
+
@bar.advance
|
41
34
|
|
42
35
|
data = get_help_sections(cmd[:commands].first)
|
43
36
|
|
@@ -82,7 +75,6 @@ class BashCompletions
|
|
82
75
|
fi
|
83
76
|
}
|
84
77
|
EOFUNC
|
85
|
-
clear
|
86
78
|
out.join("\n")
|
87
79
|
end
|
88
80
|
|
@@ -193,17 +185,19 @@ class BashCompletions
|
|
193
185
|
end
|
194
186
|
|
195
187
|
def initialize
|
196
|
-
status('Generating Bash completions', reset: false)
|
197
188
|
data = get_help_sections
|
198
189
|
@global_options = parse_options(data[:global_options])
|
199
190
|
@commands = parse_commands(data[:commands])
|
191
|
+
@bar = TTY::ProgressBar.new("\033[0;0;33mGenerating Bash completions: \033[0;35;40m[:bar]\033[0m", total: @commands.count, bar_format: :blade)
|
192
|
+
@bar.resize(25)
|
200
193
|
end
|
201
194
|
|
202
195
|
def generate_completions
|
196
|
+
@bar.start
|
203
197
|
out = []
|
204
198
|
out << main_function
|
205
199
|
out << 'complete -F _doing doing'
|
206
|
-
|
200
|
+
@bar.finish
|
207
201
|
out.join("\n")
|
208
202
|
end
|
209
203
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'doing/cli_status'
|
4
|
-
|
2
|
+
require 'tty-progressbar'
|
5
3
|
require 'shellwords'
|
6
4
|
|
7
5
|
class ::String
|
@@ -23,7 +21,6 @@ class ::String
|
|
23
21
|
end
|
24
22
|
|
25
23
|
class FishCompletions
|
26
|
-
include Status
|
27
24
|
|
28
25
|
attr_accessor :commands, :global_options
|
29
26
|
|
@@ -134,11 +131,7 @@ class FishCompletions
|
|
134
131
|
|
135
132
|
def generate_subcommand_completions
|
136
133
|
out = []
|
137
|
-
# processing = []
|
138
134
|
@commands.each_with_index do |cmd, i|
|
139
|
-
# processing << cmd[:commands].first
|
140
|
-
processing = cmd[:commands]
|
141
|
-
progress('Processing subcommands', i, @commands.count, processing)
|
142
135
|
out << "complete -xc doing -n '__fish_doing_needs_command' -a '#{cmd[:commands].join(' ')}' -d #{Shellwords.escape(cmd[:description])}"
|
143
136
|
end
|
144
137
|
|
@@ -149,13 +142,9 @@ class FishCompletions
|
|
149
142
|
|
150
143
|
out = []
|
151
144
|
need_export = []
|
152
|
-
# processing = []
|
153
145
|
|
154
146
|
@commands.each_with_index do |cmd, i|
|
155
|
-
|
156
|
-
processing = cmd[:commands]
|
157
|
-
progress('Processing subcommand options', i, @commands.count, processing)
|
158
|
-
|
147
|
+
@bar.advance
|
159
148
|
data = get_help_sections(cmd[:commands].first)
|
160
149
|
|
161
150
|
if data[:synopsis].join(' ').strip.split(/ /).last =~ /(path|file)/i
|
@@ -180,23 +169,25 @@ class FishCompletions
|
|
180
169
|
out << "complete -f -c doing -s o -l output -x -n '__fish_doing_using_command #{need_export.join(' ')}' -a '(__fish_doing_export_plugins)'"
|
181
170
|
end
|
182
171
|
|
183
|
-
clear
|
172
|
+
# clear
|
184
173
|
out.join("\n")
|
185
174
|
end
|
186
175
|
|
187
176
|
def initialize
|
188
|
-
status('Generating Fish completions', reset: false)
|
189
177
|
data = get_help_sections
|
190
178
|
@global_options = parse_options(data[:global_options])
|
191
179
|
@commands = parse_commands(data[:commands])
|
180
|
+
@bar = TTY::ProgressBar.new("\033[0;0;33mGenerating Fish completions: \033[0;35;40m[:bar]\033[0m", total: @commands.count, bar_format: :blade)
|
181
|
+
@bar.resize(25)
|
192
182
|
end
|
193
183
|
|
194
184
|
def generate_completions
|
185
|
+
@bar.start
|
195
186
|
out = []
|
196
187
|
out << generate_helpers
|
197
188
|
out << generate_subcommand_completions
|
198
189
|
out << generate_subcommand_option_completions
|
199
|
-
|
190
|
+
@bar.finish
|
200
191
|
out.join("\n")
|
201
192
|
end
|
202
193
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'doing/cli_status'
|
4
|
-
|
2
|
+
require 'tty-progressbar'
|
5
3
|
require 'shellwords'
|
6
4
|
|
7
5
|
class ::String
|
@@ -23,7 +21,6 @@ class ::String
|
|
23
21
|
end
|
24
22
|
|
25
23
|
class ZshCompletions
|
26
|
-
include Status
|
27
24
|
|
28
25
|
attr_accessor :commands, :global_options
|
29
26
|
|
@@ -57,7 +54,7 @@ class ZshCompletions
|
|
57
54
|
}
|
58
55
|
|
59
56
|
EOFUNCTIONS
|
60
|
-
|
57
|
+
@bar.finish
|
61
58
|
out
|
62
59
|
end
|
63
60
|
|
@@ -106,28 +103,20 @@ class ZshCompletions
|
|
106
103
|
|
107
104
|
def generate_subcommand_completions
|
108
105
|
out = []
|
109
|
-
# processing = []
|
110
106
|
@commands.each_with_index do |cmd, i|
|
111
|
-
# processing << cmd[:commands].first
|
112
|
-
processing = cmd[:commands]
|
113
|
-
progress('Processing subcommands', i, @commands.count, processing)
|
114
107
|
cmd[:commands].each do |c|
|
115
108
|
out << "'#{c}:#{cmd[:description].gsub(/'/, '\\\'')}'"
|
116
109
|
end
|
117
110
|
end
|
118
|
-
clear
|
119
111
|
out
|
120
112
|
end
|
121
113
|
|
122
114
|
def generate_subcommand_option_completions(indent: ' ')
|
123
115
|
|
124
116
|
out = []
|
125
|
-
# processing = []
|
126
117
|
|
127
118
|
@commands.each_with_index do |cmd, i|
|
128
|
-
|
129
|
-
processing = cmd[:commands]
|
130
|
-
progress('Processing subcommand options', i, @commands.count, processing)
|
119
|
+
@bar.advance
|
131
120
|
|
132
121
|
data = get_help_sections(cmd[:commands].first)
|
133
122
|
option_arr = []
|
@@ -155,13 +144,15 @@ class ZshCompletions
|
|
155
144
|
end
|
156
145
|
|
157
146
|
def initialize
|
158
|
-
status('Generating Zsh completions', reset: false)
|
159
147
|
data = get_help_sections
|
160
148
|
@global_options = parse_options(data[:global_options])
|
161
149
|
@commands = parse_commands(data[:commands])
|
150
|
+
@bar = TTY::ProgressBar.new(" \033[0;0;33mGenerating Zsh completions: \033[0;35;40m[:bar]\033[0m", total: @commands.count, bar_format: :blade)
|
151
|
+
@bar.resize(25)
|
162
152
|
end
|
163
153
|
|
164
154
|
def generate_completions
|
155
|
+
@bar.start
|
165
156
|
generate_helpers
|
166
157
|
end
|
167
158
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: doing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.20
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Terpstra
|
@@ -90,58 +90,102 @@ dependencies:
|
|
90
90
|
name: yard
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|
92
92
|
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0.9'
|
93
96
|
- - ">="
|
94
97
|
- !ruby/object:Gem::Version
|
95
|
-
version:
|
98
|
+
version: 0.9.26
|
96
99
|
type: :development
|
97
100
|
prerelease: false
|
98
101
|
version_requirements: !ruby/object:Gem::Requirement
|
99
102
|
requirements:
|
103
|
+
- - "~>"
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0.9'
|
100
106
|
- - ">="
|
101
107
|
- !ruby/object:Gem::Version
|
102
|
-
version:
|
108
|
+
version: 0.9.26
|
103
109
|
- !ruby/object:Gem::Dependency
|
104
110
|
name: redcarpet
|
105
111
|
requirement: !ruby/object:Gem::Requirement
|
106
112
|
requirements:
|
113
|
+
- - "~>"
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '3.5'
|
107
116
|
- - ">="
|
108
117
|
- !ruby/object:Gem::Version
|
109
|
-
version:
|
118
|
+
version: 3.5.1
|
110
119
|
type: :development
|
111
120
|
prerelease: false
|
112
121
|
version_requirements: !ruby/object:Gem::Requirement
|
113
122
|
requirements:
|
123
|
+
- - "~>"
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '3.5'
|
114
126
|
- - ">="
|
115
127
|
- !ruby/object:Gem::Version
|
116
|
-
version:
|
128
|
+
version: 3.5.1
|
117
129
|
- !ruby/object:Gem::Dependency
|
118
130
|
name: github-markup
|
119
131
|
requirement: !ruby/object:Gem::Requirement
|
120
132
|
requirements:
|
133
|
+
- - "~>"
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '4.0'
|
121
136
|
- - ">="
|
122
137
|
- !ruby/object:Gem::Version
|
123
|
-
version:
|
138
|
+
version: 4.0.0
|
124
139
|
type: :development
|
125
140
|
prerelease: false
|
126
141
|
version_requirements: !ruby/object:Gem::Requirement
|
127
142
|
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '4.0'
|
128
146
|
- - ">="
|
129
147
|
- !ruby/object:Gem::Version
|
130
|
-
version:
|
148
|
+
version: 4.0.0
|
131
149
|
- !ruby/object:Gem::Dependency
|
132
150
|
name: parallel_tests
|
133
151
|
requirement: !ruby/object:Gem::Requirement
|
134
152
|
requirements:
|
153
|
+
- - "~>"
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: '3.7'
|
135
156
|
- - ">="
|
136
157
|
- !ruby/object:Gem::Version
|
137
|
-
version:
|
158
|
+
version: 3.7.3
|
138
159
|
type: :development
|
139
160
|
prerelease: false
|
140
161
|
version_requirements: !ruby/object:Gem::Requirement
|
141
162
|
requirements:
|
163
|
+
- - "~>"
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '3.7'
|
166
|
+
- - ">="
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
version: 3.7.3
|
169
|
+
- !ruby/object:Gem::Dependency
|
170
|
+
name: tty-progressbar
|
171
|
+
requirement: !ruby/object:Gem::Requirement
|
172
|
+
requirements:
|
173
|
+
- - "~>"
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
version: '0.18'
|
176
|
+
- - ">="
|
177
|
+
- !ruby/object:Gem::Version
|
178
|
+
version: 0.18.2
|
179
|
+
type: :runtime
|
180
|
+
prerelease: false
|
181
|
+
version_requirements: !ruby/object:Gem::Requirement
|
182
|
+
requirements:
|
183
|
+
- - "~>"
|
184
|
+
- !ruby/object:Gem::Version
|
185
|
+
version: '0.18'
|
142
186
|
- - ">="
|
143
187
|
- !ruby/object:Gem::Version
|
144
|
-
version:
|
188
|
+
version: 0.18.2
|
145
189
|
- !ruby/object:Gem::Dependency
|
146
190
|
name: gli
|
147
191
|
requirement: !ruby/object:Gem::Requirement
|
@@ -306,6 +350,11 @@ files:
|
|
306
350
|
- lib/doing/array.rb
|
307
351
|
- lib/doing/cli_status.rb
|
308
352
|
- lib/doing/colors.rb
|
353
|
+
- lib/doing/completion.rb
|
354
|
+
- lib/doing/completion/bash_completion.rb
|
355
|
+
- lib/doing/completion/fish_completion.rb
|
356
|
+
- lib/doing/completion/string.rb
|
357
|
+
- lib/doing/completion/zsh_completion.rb
|
309
358
|
- lib/doing/configuration.rb
|
310
359
|
- lib/doing/errors.rb
|
311
360
|
- lib/doing/hash.rb
|