spirit_hands 2.1.10-universal-java-12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.pryrc +1 -0
- data/.ruby-gemset +1 -0
- data/CHANGELOG.md +150 -0
- data/CONTRIBUTING.md +18 -0
- data/CONTRIBUTORS.md +12 -0
- data/Gemfile +3 -0
- data/LICENSE.md +22 -0
- data/README.md +153 -0
- data/Rakefile +128 -0
- data/gem-public_cert.pem +31 -0
- data/lib/spirit_hands.rb +20 -0
- data/lib/spirit_hands/hirb.rb +2 -0
- data/lib/spirit_hands/hirb/fixes.rb +5 -0
- data/lib/spirit_hands/hirb/fixes/enabled.rb +36 -0
- data/lib/spirit_hands/hirb/fixes/pager.rb +157 -0
- data/lib/spirit_hands/hirb/fixes/util.rb +19 -0
- data/lib/spirit_hands/hirb/fixes/view.rb +11 -0
- data/lib/spirit_hands/mattr_accessor_with_default.rb +44 -0
- data/lib/spirit_hands/melody.rb +68 -0
- data/lib/spirit_hands/options.rb +99 -0
- data/lib/spirit_hands/options/color.rb +10 -0
- data/lib/spirit_hands/options/coolline.rb +60 -0
- data/lib/spirit_hands/options/hirb.rb +34 -0
- data/lib/spirit_hands/options/less.rb +2 -0
- data/lib/spirit_hands/options/less/colorize.rb +41 -0
- data/lib/spirit_hands/options/less/show_raw_unicode.rb +36 -0
- data/lib/spirit_hands/print.rb +76 -0
- data/lib/spirit_hands/prompt.rb +12 -0
- data/lib/spirit_hands/prompt/base.rb +25 -0
- data/lib/spirit_hands/prompt/base/render.rb +239 -0
- data/lib/spirit_hands/prompt/main.rb +18 -0
- data/lib/spirit_hands/prompt/multiline.rb +17 -0
- data/lib/spirit_hands/railtie.rb +11 -0
- data/lib/spirit_hands/terminal.rb +16 -0
- data/lib/spirit_hands/version.rb +3 -0
- data/note.txt +2 -0
- data/spirit_hands.gemspec +39 -0
- metadata +202 -0
@@ -0,0 +1,60 @@
|
|
1
|
+
module SpiritHands
|
2
|
+
class << self
|
3
|
+
# Is coolline enabled?
|
4
|
+
def coolline
|
5
|
+
@coolline = DEFAULT_COOLLINE if !instance_variable_defined?(:@coolline) || @coolline.nil?
|
6
|
+
@coolline
|
7
|
+
end
|
8
|
+
|
9
|
+
# Set whether hirb is enabled (default: true)
|
10
|
+
attr_writer :coolline
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
def install_coolline!
|
15
|
+
return if coolline_installed?
|
16
|
+
Pry.plugins['coolline'].activate!
|
17
|
+
self.input_config = @coolline_input
|
18
|
+
end
|
19
|
+
|
20
|
+
def uninstall_coolline!
|
21
|
+
return unless coolline_installed?
|
22
|
+
Pry.plugins['coolline'].disable!
|
23
|
+
self.input_config = @orig_input
|
24
|
+
end
|
25
|
+
|
26
|
+
def coolline_installed?
|
27
|
+
Pry.input == @coolline_input[0]
|
28
|
+
end
|
29
|
+
|
30
|
+
def setup_coolline!
|
31
|
+
if coolline
|
32
|
+
install_coolline!
|
33
|
+
else
|
34
|
+
uninstall_coolline!
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def input_config=(args)
|
39
|
+
Pry.input, Pry.config.completer = args
|
40
|
+
end
|
41
|
+
|
42
|
+
def input_config
|
43
|
+
[Pry.input, Pry.config.completer]
|
44
|
+
end
|
45
|
+
|
46
|
+
def setup_coolline
|
47
|
+
@orig_input = input_config
|
48
|
+
require 'pry-coolline'
|
49
|
+
@coolline_input = input_config
|
50
|
+
Pry.hooks.add_hook(:before_session, "setup_coolline_before") do |output, binding, pry|
|
51
|
+
setup_coolline!
|
52
|
+
end
|
53
|
+
Pry.hooks.add_hook(:after_eval, "setup_coolline_after") do |code, pry|
|
54
|
+
setup_coolline!
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
DEFAULT_COOLLINE = false # TODO: fix pry-coolline and/or integration
|
60
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spirit_hands/hirb'
|
2
|
+
|
3
|
+
module SpiritHands
|
4
|
+
class << self
|
5
|
+
# Is hirb enabled?
|
6
|
+
def hirb
|
7
|
+
::Hirb.enabled?
|
8
|
+
end
|
9
|
+
|
10
|
+
# Set whether hirb is enabled (default: true)
|
11
|
+
def hirb=(h)
|
12
|
+
h = DEFAULT_HIRB if h.nil?
|
13
|
+
if hirb != h
|
14
|
+
if h
|
15
|
+
::Hirb.enable
|
16
|
+
else
|
17
|
+
::Hirb.disable
|
18
|
+
end
|
19
|
+
end
|
20
|
+
@hirb = !!h
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def setup_hirb
|
26
|
+
self.hirb = nil unless @hirb
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
DEFAULT_HIRB = true
|
31
|
+
|
32
|
+
# Whether to use hirb/unicode when hirb is enabled (default: true)
|
33
|
+
mattr_accessor_with_default :hirb_unicode, true
|
34
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'shellwords'
|
2
|
+
|
3
|
+
module SpiritHands
|
4
|
+
DEFAULT_LESS_COLORIZE = true
|
5
|
+
LESS_R_LONG = '--RAW-CONTROL-CHARS'.freeze
|
6
|
+
LESS_R = /\A(.*-[^-R]*)R(.*)\z/.freeze
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
# Allow less to display colorized output (default: true)
|
11
|
+
# (If, set updates LESS env var)
|
12
|
+
def less_colorize
|
13
|
+
ENV['LESS'].to_s.shellsplit.any? { |arg| arg == LESS_R_LONG || arg =~ LESS_R }
|
14
|
+
end
|
15
|
+
|
16
|
+
# true: add -R to LESS env var (default)
|
17
|
+
# false: remove -R from LESS env var
|
18
|
+
# nil: set to default (true)
|
19
|
+
def less_colorize=(n)
|
20
|
+
n = DEFAULT_LESS_COLORIZE if n.nil?
|
21
|
+
|
22
|
+
args = ENV['LESS'].to_s.shellsplit.map do |arg|
|
23
|
+
next if arg == LESS_R_LONG
|
24
|
+
if arg =~ LESS_R
|
25
|
+
arg = $1 + $2
|
26
|
+
end
|
27
|
+
arg unless arg.empty?
|
28
|
+
end
|
29
|
+
args << '-R' if n
|
30
|
+
new_less = args.collect.to_a.shelljoin
|
31
|
+
ENV['LESS'] = new_less.empty? ? nil : new_less
|
32
|
+
@less_colorize = !!n
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def setup_less_colorize
|
38
|
+
self.less_colorize = nil unless @less_colorize
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'shellwords'
|
2
|
+
|
3
|
+
module SpiritHands
|
4
|
+
DEFAULT_LESS_SHOW_RAW_UNICODE = true
|
5
|
+
LESS_SHOW_RAW_BINFMT = '*n%c'.freeze
|
6
|
+
|
7
|
+
class << self
|
8
|
+
# Allow less to display colorized output (default: true)
|
9
|
+
# (If, set updates LESS env var)
|
10
|
+
def less_show_raw_unicode
|
11
|
+
ENV['LESSUTFBINFMT'] == LESS_SHOW_RAW_BINFMT
|
12
|
+
end
|
13
|
+
|
14
|
+
# true: set LESSUTFBINFMT to %*c
|
15
|
+
# false: unset LESSUTFBINFMT
|
16
|
+
# String: set custom LESSUTFBINFMT
|
17
|
+
# nil: set default(true)
|
18
|
+
def less_show_raw_unicode=(n)
|
19
|
+
n = DEFAULT_LESS_SHOW_RAW_UNICODE if n.nil?
|
20
|
+
ENV['LESSUTFBINFMT'] = if n.is_a?(String)
|
21
|
+
n
|
22
|
+
elsif n
|
23
|
+
LESS_SHOW_RAW_BINFMT
|
24
|
+
else
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
@less_show_raw_unicode = !!n
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def setup_less_show_raw_unicode
|
33
|
+
self.less_show_raw_unicode = nil unless @less_show_raw_unicode
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'awesome_print'
|
2
|
+
|
3
|
+
module SpiritHands
|
4
|
+
module Print
|
5
|
+
class << self
|
6
|
+
PRINT_FUNCTION = ->(_output, value, _pry_) do
|
7
|
+
::SpiritHands::Print.print(_output, value, _pry_)
|
8
|
+
end
|
9
|
+
|
10
|
+
def install!
|
11
|
+
::Pry.config.print = PRINT_FUNCTION
|
12
|
+
end
|
13
|
+
|
14
|
+
def pretty(value)
|
15
|
+
if ::SpiritHands.awesome_print
|
16
|
+
opts = { :indent => ::SpiritHands.value_indent }
|
17
|
+
opts[:plain] = true if !SpiritHands.color
|
18
|
+
value.ai(opts)
|
19
|
+
else
|
20
|
+
value.inspect
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def hirb_unicode_enabled?
|
25
|
+
::Hirb::Formatter.dynamic_config.keys.any? do |key|
|
26
|
+
if opts = ::Hirb::Formatter.dynamic_config[key][:options]
|
27
|
+
opts && opts[:unicode]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def print(_output, value, _pry_)
|
33
|
+
if ::Hirb.enabled?
|
34
|
+
setup_hirb_unicode
|
35
|
+
return if ::Hirb::View.view_or_page_output(value)
|
36
|
+
end
|
37
|
+
_pry_.pager.open do |pager|
|
38
|
+
pager.print ::SpiritHands.value_prompt
|
39
|
+
pager.puts pretty(value)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def hirb_unicode_enable
|
46
|
+
return false unless ::SpiritHands::Terminal.unicode?
|
47
|
+
require 'hirb/unicode'
|
48
|
+
|
49
|
+
::Hirb::Formatter.dynamic_config.keys.each do |key|
|
50
|
+
::Hirb::Formatter.dynamic_config[key][:options] ||= {}
|
51
|
+
::Hirb::Formatter.dynamic_config[key][:options][:unicode] = true
|
52
|
+
end
|
53
|
+
true
|
54
|
+
end
|
55
|
+
|
56
|
+
def hirb_unicode_disable
|
57
|
+
::Hirb::Formatter.dynamic_config.keys.each do |key|
|
58
|
+
::Hirb::Formatter.dynamic_config[key][:options] ||= {}
|
59
|
+
::Hirb::Formatter.dynamic_config[key][:options][:unicode] = false
|
60
|
+
end
|
61
|
+
false
|
62
|
+
end
|
63
|
+
|
64
|
+
def setup_hirb_unicode
|
65
|
+
if hirb_unicode_enabled? != SpiritHands.hirb_unicode
|
66
|
+
if SpiritHands.hirb_unicode
|
67
|
+
hirb_unicode_enable
|
68
|
+
else
|
69
|
+
hirb_unicode_disable
|
70
|
+
end
|
71
|
+
end
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
end # self
|
75
|
+
end # Print
|
76
|
+
end # SpiritHands
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spirit_hands/prompt/base/render'
|
2
|
+
|
3
|
+
module SpiritHands
|
4
|
+
module Prompt
|
5
|
+
|
6
|
+
class << self
|
7
|
+
private
|
8
|
+
|
9
|
+
|
10
|
+
def render(state, prompt, color = true)
|
11
|
+
r = Render.new(state, prompt, color)
|
12
|
+
res = r.to_s
|
13
|
+
STDERR.puts "\n" + (r.errors * "\n") + "\n" if r.errors?
|
14
|
+
res
|
15
|
+
end
|
16
|
+
end # self
|
17
|
+
|
18
|
+
# :object Object
|
19
|
+
# :level Fixnum
|
20
|
+
# :pry Pry
|
21
|
+
# :app String or Rails::Application
|
22
|
+
# :multiline false: normal prompt, true: multiline prompt
|
23
|
+
State = Struct.new(:object, :level, :pry, :app, :multiline)
|
24
|
+
end # Prompt
|
25
|
+
end # SpiritHands
|
@@ -0,0 +1,239 @@
|
|
1
|
+
module SpiritHands
|
2
|
+
module Prompt
|
3
|
+
# <....>
|
4
|
+
# <..../>
|
5
|
+
# </....>
|
6
|
+
#
|
7
|
+
class Render
|
8
|
+
# <tag> ... </tag>, tag -> inner part of escape codes
|
9
|
+
MATCHED_TAG_CODES = {
|
10
|
+
'b' => 1,
|
11
|
+
'bold' => 1,
|
12
|
+
'bright' => 1,
|
13
|
+
'strong' => 1,
|
14
|
+
|
15
|
+
'dark' => 2,
|
16
|
+
'faint' => 2,
|
17
|
+
|
18
|
+
'i' => 3,
|
19
|
+
'italic' => 3,
|
20
|
+
'em' => 3,
|
21
|
+
|
22
|
+
'u' => 4,
|
23
|
+
'underline' => 4,
|
24
|
+
|
25
|
+
'blink' => 5, # evil
|
26
|
+
'flash' => 5,
|
27
|
+
|
28
|
+
'rapid-blink' => 6, # sinister
|
29
|
+
'rapid-flash' => 6,
|
30
|
+
|
31
|
+
'reverse' => 7,
|
32
|
+
'negative' => 7,
|
33
|
+
'inverse' => 7,
|
34
|
+
|
35
|
+
'concealed' => 8,
|
36
|
+
|
37
|
+
'strike' => 9,
|
38
|
+
'strikethrough' => 9,
|
39
|
+
|
40
|
+
'black' => 30,
|
41
|
+
'red' => 31,
|
42
|
+
'green' => 32,
|
43
|
+
'yellow' => 33,
|
44
|
+
'blue' => 34,
|
45
|
+
'magenta' => 35,
|
46
|
+
'cyan' => 36,
|
47
|
+
'white' => 37,
|
48
|
+
|
49
|
+
'bgblack' => 40,
|
50
|
+
'bgred' => 41,
|
51
|
+
'bggreen' => 42,
|
52
|
+
'bgyellow' => 43,
|
53
|
+
'bgblue' => 44,
|
54
|
+
'bgmagenta' => 45,
|
55
|
+
'bgcyan' => 46,
|
56
|
+
'bgwhite' => 47,
|
57
|
+
}
|
58
|
+
|
59
|
+
# <.../>
|
60
|
+
SINGLE_TAGS = {
|
61
|
+
# <cmd/>: command number
|
62
|
+
'cmd' =>
|
63
|
+
lambda do |state|
|
64
|
+
pry = state.pry
|
65
|
+
(pry.respond_to?(:input_ring) ? pry.input_ring : pry.input_array)
|
66
|
+
.size
|
67
|
+
end,
|
68
|
+
|
69
|
+
# <tgt/>: target string
|
70
|
+
'tgt' => ->(state) {
|
71
|
+
unless (str = Pry.view_clip(state.object)) == 'main'
|
72
|
+
state.level = 0 if state.level < 0
|
73
|
+
"(#{'../' * state.level}#{str})"
|
74
|
+
else
|
75
|
+
''
|
76
|
+
end
|
77
|
+
},
|
78
|
+
|
79
|
+
# <app/>: state.app (Object) converted to String
|
80
|
+
'app' => ->(state) {
|
81
|
+
app = state.app
|
82
|
+
if app.class.respond_to?(:module_parent_name) && \
|
83
|
+
app.class.module_parent_name.respond_to?(:underscore)
|
84
|
+
app.class.module_parent_name.underscore
|
85
|
+
elsif app.class.respond_to?(:parent_name) && \
|
86
|
+
app.class.parent_name.respond_to?(:underscore)
|
87
|
+
app.class.parent_name.underscore
|
88
|
+
elsif app
|
89
|
+
app.to_s
|
90
|
+
else
|
91
|
+
::SpiritHands.app
|
92
|
+
end
|
93
|
+
},
|
94
|
+
|
95
|
+
# <sep/>: SpiritHands.prompt_separator
|
96
|
+
'sep' => ->(_state) {
|
97
|
+
::SpiritHands.prompt_separator
|
98
|
+
}
|
99
|
+
}
|
100
|
+
|
101
|
+
# Array<String>
|
102
|
+
attr_reader :errors
|
103
|
+
|
104
|
+
def errors?
|
105
|
+
errors.any?
|
106
|
+
end
|
107
|
+
|
108
|
+
# :state SpiritHands::Prompt::State
|
109
|
+
# :prompt String
|
110
|
+
# :color true or false/nil
|
111
|
+
def initialize(state, prompt, color)
|
112
|
+
@state = state
|
113
|
+
@prompt = prompt
|
114
|
+
@color = color
|
115
|
+
end
|
116
|
+
|
117
|
+
def to_s
|
118
|
+
@errors = []
|
119
|
+
@tag_stack = []
|
120
|
+
@result = ''
|
121
|
+
@color_applied = false
|
122
|
+
@in_tag = false
|
123
|
+
|
124
|
+
@prompt.each_char do |c|
|
125
|
+
if @in_tag
|
126
|
+
tag_char(c)
|
127
|
+
else
|
128
|
+
nontag_char(c)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# @tag_stack.any? --> error/s
|
133
|
+
@tag_stack.each { |t| errors << "<#{t}>: Missing </#{t}>" }
|
134
|
+
|
135
|
+
(errors?) ? '' : @result
|
136
|
+
end
|
137
|
+
|
138
|
+
private
|
139
|
+
|
140
|
+
def tag_char(c)
|
141
|
+
case c
|
142
|
+
when '/'
|
143
|
+
# close: </
|
144
|
+
# single <.+/
|
145
|
+
@tag_type = (@tag.nil? || @tag.empty?) ? :close : :single
|
146
|
+
when '>' # close tag
|
147
|
+
@tag.downcase!
|
148
|
+
send @tag_type # :start, :close or :single
|
149
|
+
@in_tag = false
|
150
|
+
else # append to existing tag
|
151
|
+
@tag += c
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def nontag_char(c)
|
156
|
+
if instance_variable_defined?(:@escape) && @escape
|
157
|
+
nontag_escaped_char(c)
|
158
|
+
else
|
159
|
+
nontag_unescaped_char(c)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def nontag_escaped_char(c)
|
164
|
+
@escape = false
|
165
|
+
@result += (@state.multiline) ? ' ' : c
|
166
|
+
end
|
167
|
+
|
168
|
+
def nontag_unescaped_char(c)
|
169
|
+
case c
|
170
|
+
when '\\' # escape next char
|
171
|
+
@escape = true
|
172
|
+
when '<' # start tag
|
173
|
+
@in_tag = true
|
174
|
+
@tag_type = :start
|
175
|
+
@tag = ''
|
176
|
+
else # normal char
|
177
|
+
@result += (@state.multiline) ? ' ' : c
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# <...>
|
182
|
+
def start
|
183
|
+
code = MATCHED_TAG_CODES[@tag]
|
184
|
+
if !code
|
185
|
+
errors << "Unknown <#{@tag}>"
|
186
|
+
return
|
187
|
+
end
|
188
|
+
@result += esc(code)
|
189
|
+
@tag_stack << @tag
|
190
|
+
end
|
191
|
+
|
192
|
+
# </...>
|
193
|
+
def close
|
194
|
+
code = MATCHED_TAG_CODES[@tag]
|
195
|
+
if !code
|
196
|
+
errors << "Unknown </#{@tag}>"
|
197
|
+
return
|
198
|
+
end
|
199
|
+
idx = @tag_stack.rindex @tag
|
200
|
+
if idx.nil?
|
201
|
+
errors << "</#{@tag}>: missing start <#{@tag}>"
|
202
|
+
return
|
203
|
+
end
|
204
|
+
# remove the now closed tag from the stack
|
205
|
+
@tag_stack.delete_at idx
|
206
|
+
# reset and reapply all codes on the @tag_stack
|
207
|
+
@result += reset
|
208
|
+
@tag_stack.each { |tag| @result += esc(MATCHED_TAG_CODES[tag]) }
|
209
|
+
end
|
210
|
+
|
211
|
+
# <.../>
|
212
|
+
def single
|
213
|
+
f = SINGLE_TAGS[@tag]
|
214
|
+
if !f
|
215
|
+
errors << "Unknown </#{@tag}>"
|
216
|
+
return
|
217
|
+
end
|
218
|
+
result = f.(@state).to_s
|
219
|
+
|
220
|
+
# blank out all but sep for multiline prompt, vs. main (normal)
|
221
|
+
if @state.multiline && @tag != 'sep'
|
222
|
+
result = ' ' * result.length
|
223
|
+
end
|
224
|
+
@result += result
|
225
|
+
end
|
226
|
+
|
227
|
+
def reset
|
228
|
+
esc(0)
|
229
|
+
end
|
230
|
+
|
231
|
+
# convert a code to an actual character
|
232
|
+
def esc(code)
|
233
|
+
return '' if !@color
|
234
|
+
@color_applied = true
|
235
|
+
"\001\e[#{code}m\002".freeze
|
236
|
+
end
|
237
|
+
end # Render
|
238
|
+
end # Prompt
|
239
|
+
end # SpiritHands
|