doing 2.0.19 → 2.0.23
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -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 +19 -5
- data/lib/doing.rb +1 -1
- data/lib/helpers/fzf/.goreleaser.yml +119 -0
- data/lib/helpers/fzf/.rubocop.yml +28 -0
- data/lib/helpers/fzf/ADVANCED.md +565 -0
- data/lib/helpers/fzf/BUILD.md +49 -0
- data/lib/helpers/fzf/CHANGELOG.md +1193 -0
- data/lib/helpers/fzf/Dockerfile +11 -0
- data/lib/helpers/fzf/LICENSE +21 -0
- data/lib/helpers/fzf/Makefile +166 -0
- data/lib/helpers/fzf/README-VIM.md +486 -0
- data/lib/helpers/fzf/README.md +712 -0
- data/lib/helpers/fzf/bin/fzf-tmux +233 -0
- data/lib/helpers/fzf/doc/fzf.txt +512 -0
- data/lib/helpers/fzf/go.mod +17 -0
- data/lib/helpers/fzf/go.sum +31 -0
- data/lib/helpers/fzf/install +382 -0
- data/lib/helpers/fzf/install.ps1 +65 -0
- data/lib/helpers/fzf/main.go +14 -0
- data/lib/helpers/fzf/man/man1/fzf-tmux.1 +68 -0
- data/lib/helpers/fzf/man/man1/fzf.1 +1001 -0
- data/lib/helpers/fzf/plugin/fzf.vim +1048 -0
- data/lib/helpers/fzf/shell/completion.bash +381 -0
- data/lib/helpers/fzf/shell/completion.zsh +329 -0
- data/lib/helpers/fzf/shell/key-bindings.bash +96 -0
- data/lib/helpers/fzf/shell/key-bindings.fish +172 -0
- data/lib/helpers/fzf/shell/key-bindings.zsh +114 -0
- data/lib/helpers/fzf/src/LICENSE +21 -0
- data/lib/helpers/fzf/src/algo/algo.go +884 -0
- data/lib/helpers/fzf/src/algo/algo_test.go +197 -0
- data/lib/helpers/fzf/src/algo/normalize.go +492 -0
- data/lib/helpers/fzf/src/ansi.go +409 -0
- data/lib/helpers/fzf/src/ansi_test.go +427 -0
- data/lib/helpers/fzf/src/cache.go +81 -0
- data/lib/helpers/fzf/src/cache_test.go +39 -0
- data/lib/helpers/fzf/src/chunklist.go +89 -0
- data/lib/helpers/fzf/src/chunklist_test.go +80 -0
- data/lib/helpers/fzf/src/constants.go +85 -0
- data/lib/helpers/fzf/src/core.go +351 -0
- data/lib/helpers/fzf/src/history.go +96 -0
- data/lib/helpers/fzf/src/history_test.go +68 -0
- data/lib/helpers/fzf/src/item.go +44 -0
- data/lib/helpers/fzf/src/item_test.go +23 -0
- data/lib/helpers/fzf/src/matcher.go +235 -0
- data/lib/helpers/fzf/src/merger.go +120 -0
- data/lib/helpers/fzf/src/merger_test.go +88 -0
- data/lib/helpers/fzf/src/options.go +1691 -0
- data/lib/helpers/fzf/src/options_test.go +457 -0
- data/lib/helpers/fzf/src/pattern.go +425 -0
- data/lib/helpers/fzf/src/pattern_test.go +209 -0
- data/lib/helpers/fzf/src/protector/protector.go +8 -0
- data/lib/helpers/fzf/src/protector/protector_openbsd.go +10 -0
- data/lib/helpers/fzf/src/reader.go +201 -0
- data/lib/helpers/fzf/src/reader_test.go +63 -0
- data/lib/helpers/fzf/src/result.go +243 -0
- data/lib/helpers/fzf/src/result_others.go +16 -0
- data/lib/helpers/fzf/src/result_test.go +159 -0
- data/lib/helpers/fzf/src/result_x86.go +16 -0
- data/lib/helpers/fzf/src/terminal.go +2832 -0
- data/lib/helpers/fzf/src/terminal_test.go +638 -0
- data/lib/helpers/fzf/src/terminal_unix.go +26 -0
- data/lib/helpers/fzf/src/terminal_windows.go +45 -0
- data/lib/helpers/fzf/src/tokenizer.go +253 -0
- data/lib/helpers/fzf/src/tokenizer_test.go +112 -0
- data/lib/helpers/fzf/src/tui/dummy.go +46 -0
- data/lib/helpers/fzf/src/tui/light.go +987 -0
- data/lib/helpers/fzf/src/tui/light_unix.go +110 -0
- data/lib/helpers/fzf/src/tui/light_windows.go +145 -0
- data/lib/helpers/fzf/src/tui/tcell.go +721 -0
- data/lib/helpers/fzf/src/tui/tcell_test.go +392 -0
- data/lib/helpers/fzf/src/tui/ttyname_unix.go +47 -0
- data/lib/helpers/fzf/src/tui/ttyname_windows.go +14 -0
- data/lib/helpers/fzf/src/tui/tui.go +625 -0
- data/lib/helpers/fzf/src/tui/tui_test.go +20 -0
- data/lib/helpers/fzf/src/util/atomicbool.go +34 -0
- data/lib/helpers/fzf/src/util/atomicbool_test.go +17 -0
- data/lib/helpers/fzf/src/util/chars.go +198 -0
- data/lib/helpers/fzf/src/util/chars_test.go +46 -0
- data/lib/helpers/fzf/src/util/eventbox.go +96 -0
- data/lib/helpers/fzf/src/util/eventbox_test.go +61 -0
- data/lib/helpers/fzf/src/util/slab.go +12 -0
- data/lib/helpers/fzf/src/util/util.go +138 -0
- data/lib/helpers/fzf/src/util/util_test.go +40 -0
- data/lib/helpers/fzf/src/util/util_unix.go +47 -0
- data/lib/helpers/fzf/src/util/util_windows.go +83 -0
- data/lib/helpers/fzf/test/fzf.vader +175 -0
- data/lib/helpers/fzf/test/test_go.rb +2626 -0
- data/lib/helpers/fzf/uninstall +117 -0
- 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 +144 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47e702ec6e32cc0f97b0d81ef0e6482fb78ea462916fd2f83a58474759c0b4af
|
4
|
+
data.tar.gz: b50848409e7a8b409bd9f82a77dbf0722ef97ac3a2a9491a5096ad60ca94f563
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25b1e4482ee5120b1b8fc6716c6f717235addf893917b8c21116da57ee25fef5d0bca3b29b3dbda39e0fb23c149e4284e17da755a9b1f6a92c89a7e30eda55f7
|
7
|
+
data.tar.gz: 28563fdc3eadec4d60faae9bdb2a38072caea19a98a5084670591851036702d2a46e7ee4f0798e6cd22e7b9eeec1a0c822872d9457b1eb8c890c45b4d5d54998
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
### 2.0.23
|
2
|
+
|
3
|
+
- include fzf source directly, in case git isn't installed
|
4
|
+
- fall back to installing fzf with sudo on error
|
5
|
+
|
6
|
+
### 2.0.20
|
7
|
+
|
8
|
+
#### IMPROVED
|
9
|
+
|
10
|
+
- completion script generator refactor and progress bars
|
11
|
+
|
12
|
+
#### FIXED
|
13
|
+
|
14
|
+
- compile fzf for current operating system
|
15
|
+
|
1
16
|
### 2.0.19
|
2
17
|
|
3
18
|
#### FIXED
|
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.23)
|
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.22<!--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.23
|
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
|