claide-completion 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +20 -0
- data/README.markdown +1 -0
- data/lib/claide_completion.rb +23 -0
- data/lib/claide_completion/gem_version.rb +3 -0
- data/lib/claide_completion/generator.rb +36 -0
- data/lib/claide_completion/generator/zsh.rb +195 -0
- data/lib/claide_plugin.rb +4 -0
- metadata +51 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e9e12551365a7dd992c916bb8804d463d6750def
|
4
|
+
data.tar.gz: 39b2c08434bf6ba4b6014af4c967c0a0e09ac3a8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 33b09cf9b3a7e6f64822a63738b6b5e323f2ada25477a001d2a2378f2d129088747039f956e97a7b96c1420774c89189f4e0846eb98750af8ff0236b21839d8a
|
7
|
+
data.tar.gz: 05d3fd62a7395d6c92b0dc1d2946366d457a266dc6b1cbc40e948dfc6249ff6a390e125607466fc68a51ec3a6f6bb1c29063d330d20634c4889d48230e7c0a12
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 - 2012 Eloy Durán <eloy.de.enige@gmail.com>
|
2
|
+
Copyright (c) 2012 Fabio Pelosin <fabiopelosin@gmail.com>
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
of this software and associated documentation files (the "Software"), to deal
|
6
|
+
in the Software without restriction, including without limitation the rights
|
7
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the Software is
|
9
|
+
furnished to do so, subject to the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be included in
|
12
|
+
all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Hi, I’m CLAide Completion, making your command line experience feel complete.
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'claide_completion/generator'
|
2
|
+
|
3
|
+
module CLAideCompletion
|
4
|
+
def self.included(mod)
|
5
|
+
if defined?(mod::DEFAULT_ROOT_OPTIONS)
|
6
|
+
mod::DEFAULT_ROOT_OPTIONS << [
|
7
|
+
'--completion-script', 'Print the auto-completion script'
|
8
|
+
]
|
9
|
+
end
|
10
|
+
mod.prepend(Prepend)
|
11
|
+
end
|
12
|
+
|
13
|
+
module Prepend
|
14
|
+
def handle_root_options(argv)
|
15
|
+
return false unless self.class.root_command?
|
16
|
+
if argv.flag?('completion-script')
|
17
|
+
puts Generator.generate(self.class)
|
18
|
+
return true
|
19
|
+
end
|
20
|
+
super
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module CLAideCompletion
|
2
|
+
module Generator
|
3
|
+
class ShellCompletionNotFound < StandardError
|
4
|
+
include CLAide::InformativeError
|
5
|
+
end
|
6
|
+
|
7
|
+
autoload :Zsh, 'claide_completion/generator/zsh'
|
8
|
+
|
9
|
+
def self.generate(command, shell = nil)
|
10
|
+
shell ||= ENV['SHELL'].split(File::SEPARATOR).last
|
11
|
+
begin
|
12
|
+
generator = const_get(shell.capitalize.to_sym)
|
13
|
+
rescue NameError
|
14
|
+
raise ShellCompletionNotFound, 'Auto-completion generator for ' \
|
15
|
+
"the `#{shell}` shell is not implemented."
|
16
|
+
end
|
17
|
+
generator.new(command).generate
|
18
|
+
end
|
19
|
+
|
20
|
+
# Indents the lines of the given string except the first one to the given
|
21
|
+
# level. Uses two spaces per each level.
|
22
|
+
#
|
23
|
+
# @param [String] string
|
24
|
+
# The string to indent.
|
25
|
+
#
|
26
|
+
# @param [Fixnum] indentation
|
27
|
+
# The indentation amount.
|
28
|
+
#
|
29
|
+
# @return [String] An indented string.
|
30
|
+
#
|
31
|
+
def indent(string, indentation)
|
32
|
+
string.gsub("\n", "\n#{' ' * indentation * 2}")
|
33
|
+
end
|
34
|
+
module_function :indent
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,195 @@
|
|
1
|
+
module CLAideCompletion
|
2
|
+
module Generator
|
3
|
+
# Generates a completion script for the Z shell.
|
4
|
+
#
|
5
|
+
class Zsh
|
6
|
+
attr_reader :command
|
7
|
+
|
8
|
+
# @param [Class] command
|
9
|
+
# The command to generate the script for.
|
10
|
+
#
|
11
|
+
def initialize(command)
|
12
|
+
@command = command
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [String] The completion script.
|
16
|
+
#
|
17
|
+
def generate
|
18
|
+
result = <<-DOC
|
19
|
+
#compdef #{command.command}
|
20
|
+
# setopt XTRACE VERBOSE
|
21
|
+
# vim: ft=zsh sw=2 ts=2 et
|
22
|
+
|
23
|
+
local -a _subcommands
|
24
|
+
local -a _options
|
25
|
+
|
26
|
+
#{case_statement_fragment(command)}
|
27
|
+
DOC
|
28
|
+
|
29
|
+
post_process(result)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# Returns a case statement for a given command with the given nesting
|
35
|
+
# level.
|
36
|
+
#
|
37
|
+
# @param [Class] command
|
38
|
+
# The command to generate the fragment for.
|
39
|
+
#
|
40
|
+
# @param [Fixnum] nest_level
|
41
|
+
# The nesting level to detect the index of the words array.
|
42
|
+
#
|
43
|
+
# @return [String] the case statement fragment.
|
44
|
+
#
|
45
|
+
# @example
|
46
|
+
# case "$words[2]" in
|
47
|
+
# spec-file)
|
48
|
+
# [..snip..]
|
49
|
+
# ;;
|
50
|
+
# *) # bin
|
51
|
+
# _subcommands=(
|
52
|
+
# "spec-file:"
|
53
|
+
# )
|
54
|
+
# _describe -t commands "bin subcommands" _subcommands
|
55
|
+
# _options=(
|
56
|
+
# "--completion-script:Print the auto-completion script"
|
57
|
+
# "--help:Show help banner of specified command"
|
58
|
+
# "--verbose:Show more debugging information"
|
59
|
+
# "--version:Show the version of the tool"
|
60
|
+
# )
|
61
|
+
# _describe -t options "bin options" _options
|
62
|
+
# ;;
|
63
|
+
# esac
|
64
|
+
#
|
65
|
+
# rubocop:disable MethodLength
|
66
|
+
def case_statement_fragment(command, nest_level = 0)
|
67
|
+
entries = case_statement_entries_fragment(command, nest_level + 1)
|
68
|
+
subcommands = subcommands_fragment(command)
|
69
|
+
options = options_fragment(command)
|
70
|
+
|
71
|
+
result = <<-DOC
|
72
|
+
case "$words[#{nest_level + 2}]" in
|
73
|
+
#{Generator.indent(entries, 1)}
|
74
|
+
*) # #{command.full_command}
|
75
|
+
#{Generator.indent(subcommands, 2)}
|
76
|
+
#{Generator.indent(options, 2)}
|
77
|
+
;;
|
78
|
+
esac
|
79
|
+
DOC
|
80
|
+
result.gsub(/\n *\n/, "\n").chomp
|
81
|
+
end
|
82
|
+
# rubocop:enable MethodLength
|
83
|
+
|
84
|
+
# Returns a case statement for a given command with the given nesting
|
85
|
+
# level.
|
86
|
+
#
|
87
|
+
# @param [Class] command
|
88
|
+
# The command to generate the fragment for.
|
89
|
+
#
|
90
|
+
# @param [Fixnum] nest_level
|
91
|
+
# The nesting level to detect the index of the words array.
|
92
|
+
#
|
93
|
+
# @return [String] the case statement fragment.
|
94
|
+
#
|
95
|
+
# @example
|
96
|
+
# repo)
|
97
|
+
# case "$words[5]" in
|
98
|
+
# *) # bin spec-file lint
|
99
|
+
# _options=(
|
100
|
+
# "--help:Show help banner of specified command"
|
101
|
+
# "--only-errors:Skip warnings"
|
102
|
+
# "--verbose:Show more debugging information"
|
103
|
+
# )
|
104
|
+
# _describe -t options "bin spec-file lint options" _options
|
105
|
+
# ;;
|
106
|
+
# esac
|
107
|
+
# ;;
|
108
|
+
#
|
109
|
+
def case_statement_entries_fragment(command, nest_level)
|
110
|
+
subcommands = command.subcommands_for_command_lookup
|
111
|
+
subcommands.sort_by(&:name).map do |subcommand|
|
112
|
+
subcase = case_statement_fragment(subcommand, nest_level)
|
113
|
+
<<-DOC
|
114
|
+
#{subcommand.command})
|
115
|
+
#{Generator.indent(subcase, 1)}
|
116
|
+
;;
|
117
|
+
DOC
|
118
|
+
end.join("\n")
|
119
|
+
end
|
120
|
+
|
121
|
+
# Returns the fragment of the subcommands array.
|
122
|
+
#
|
123
|
+
# @param [Class] command
|
124
|
+
# The command to generate the fragment for.
|
125
|
+
#
|
126
|
+
# @return [String] The fragment.
|
127
|
+
#
|
128
|
+
def subcommands_fragment(command)
|
129
|
+
subcommands = command.subcommands_for_command_lookup
|
130
|
+
list = subcommands.sort_by(&:name).map do |subcommand|
|
131
|
+
"\"#{subcommand.command}:#{subcommand.summary}\""
|
132
|
+
end
|
133
|
+
describe_fragment(command, 'subcommands', 'commands', list)
|
134
|
+
end
|
135
|
+
|
136
|
+
# Returns the fragment of the options array.
|
137
|
+
#
|
138
|
+
# @param [Class] command
|
139
|
+
# The command to generate the fragment for.
|
140
|
+
#
|
141
|
+
# @return [String] The fragment.
|
142
|
+
#
|
143
|
+
def options_fragment(command)
|
144
|
+
list = command.options.sort_by(&:first).map do |option|
|
145
|
+
"\"#{option[0]}:#{option[1]}\""
|
146
|
+
end
|
147
|
+
describe_fragment(command, 'options', 'options', list)
|
148
|
+
end
|
149
|
+
|
150
|
+
# Returns the fragment for a list of completions and the ZSH
|
151
|
+
# `_describe` function.
|
152
|
+
#
|
153
|
+
# @param [Class] command
|
154
|
+
# The command to generate the fragment for.
|
155
|
+
#
|
156
|
+
# @param [String] name
|
157
|
+
# The name of the list.
|
158
|
+
#
|
159
|
+
# @param [Class] tag
|
160
|
+
# The ZSH tag to use (e.g. command or option).
|
161
|
+
#
|
162
|
+
# @param [Array<String>] list
|
163
|
+
# The list of the entries.
|
164
|
+
#
|
165
|
+
# @return [String] The fragment.
|
166
|
+
#
|
167
|
+
def describe_fragment(command, name, tag, list)
|
168
|
+
if list && !list.empty?
|
169
|
+
<<-DOC
|
170
|
+
_#{name}=(
|
171
|
+
#{Generator.indent(list.join("\n"), 1)}
|
172
|
+
)
|
173
|
+
_describe -t #{tag} "#{command.full_command} #{name}" _#{name}
|
174
|
+
DOC
|
175
|
+
else
|
176
|
+
''
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
# Post processes a script to remove any artifact and escape any needed
|
181
|
+
# character.
|
182
|
+
#
|
183
|
+
# @param [String] string
|
184
|
+
# The string to post process.
|
185
|
+
#
|
186
|
+
# @return [String] The post processed script.
|
187
|
+
#
|
188
|
+
def post_process(string)
|
189
|
+
string.gsub!(/\n *\n/, "\n\n")
|
190
|
+
string.gsub!(/`/, '\\\`')
|
191
|
+
string
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
metadata
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: claide-completion
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Fabio Pelosin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-06-28 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description:
|
14
|
+
email:
|
15
|
+
- fabiopelosin@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- LICENSE
|
21
|
+
- README.markdown
|
22
|
+
- lib/claide_completion.rb
|
23
|
+
- lib/claide_completion/gem_version.rb
|
24
|
+
- lib/claide_completion/generator.rb
|
25
|
+
- lib/claide_completion/generator/zsh.rb
|
26
|
+
- lib/claide_plugin.rb
|
27
|
+
homepage: https://github.com/CocoaPods/CLAide
|
28
|
+
licenses:
|
29
|
+
- MIT
|
30
|
+
metadata: {}
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
require_paths:
|
34
|
+
- lib
|
35
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
requirements: []
|
46
|
+
rubyforge_project:
|
47
|
+
rubygems_version: 2.4.8
|
48
|
+
signing_key:
|
49
|
+
specification_version: 3
|
50
|
+
summary: CLI completion plugin for CLAide.
|
51
|
+
test_files: []
|