spirit_hands 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/.gitignore +17 -0
  4. data/.hound.yml +20 -0
  5. data/.pryrc +2 -0
  6. data/.rubocop.yml +20 -0
  7. data/.ruby-gemset +1 -0
  8. data/CHANGELOG.md +147 -0
  9. data/CONTRIBUTING.md +18 -0
  10. data/CONTRIBUTORS.md +10 -0
  11. data/Gemfile +3 -0
  12. data/LICENSE.md +22 -0
  13. data/README.md +133 -0
  14. data/Rakefile +3 -0
  15. data/gem-public_cert.pem +32 -0
  16. data/lib/spirit_hands/hirb/fixes/enabled.rb +38 -0
  17. data/lib/spirit_hands/hirb/fixes/pager.rb +144 -0
  18. data/lib/spirit_hands/hirb/fixes/util.rb +23 -0
  19. data/lib/spirit_hands/hirb/fixes/view.rb +10 -0
  20. data/lib/spirit_hands/hirb/fixes.rb +5 -0
  21. data/lib/spirit_hands/hirb.rb +2 -0
  22. data/lib/spirit_hands/load_plugins.rb +10 -0
  23. data/lib/spirit_hands/mattr_accessor_with_default.rb +48 -0
  24. data/lib/spirit_hands/melody.rb +41 -0
  25. data/lib/spirit_hands/options/color.rb +12 -0
  26. data/lib/spirit_hands/options/hirb.rb +34 -0
  27. data/lib/spirit_hands/options/less/colorize.rb +42 -0
  28. data/lib/spirit_hands/options/less/show_raw_unicode.rb +38 -0
  29. data/lib/spirit_hands/options/less.rb +2 -0
  30. data/lib/spirit_hands/options.rb +57 -0
  31. data/lib/spirit_hands/plugin.rb +28 -0
  32. data/lib/spirit_hands/print.rb +72 -0
  33. data/lib/spirit_hands/prompt/base.rb +249 -0
  34. data/lib/spirit_hands/prompt/main.rb +18 -0
  35. data/lib/spirit_hands/prompt/multiline.rb +17 -0
  36. data/lib/spirit_hands/prompt.rb +13 -0
  37. data/lib/spirit_hands/railtie.rb +7 -0
  38. data/lib/spirit_hands/terminal.rb +14 -0
  39. data/lib/spirit_hands/version.rb +3 -0
  40. data/lib/spirit_hands.rb +13 -0
  41. data/spirit_hands.gemspec +37 -0
  42. data.tar.gz.sig +0 -0
  43. metadata +258 -0
  44. metadata.gz.sig +0 -0
@@ -0,0 +1,10 @@
1
+ require 'spirit_hands/plugin'
2
+
3
+ # awesome_print is autoloaded by Hirb::View patch and/or SpiritHands::Print
4
+ # pry was loaded earlier
5
+ SpiritHands.plugin 'pry-coolline'
6
+ SpiritHands.plugin 'pry-doc'
7
+ SpiritHands.plugin 'pry-git'
8
+ # pry-rails was loaded earlier (if needed)
9
+ SpiritHands.plugin 'pry-remote'
10
+ # hirb is autoloaded by SpiritHands.hirb = true
@@ -0,0 +1,48 @@
1
+ class Module
2
+ def mattr_accessor_with_default(property, default = nil, &block)
3
+ if block_given?
4
+ if default
5
+ raise ArgumentError, 'Must specify only one of +default+ or &block'
6
+ end
7
+ default = block
8
+ end
9
+
10
+ getter = property.to_sym
11
+ setter = "#{property}=".to_sym
12
+ class_var = "@@#{property}".to_sym
13
+
14
+ # self.property=
15
+ define_singleton_method(setter) do |value|
16
+ if value.nil?
17
+ remove_class_variable(class_var)
18
+ else
19
+ class_variable_set(class_var, value)
20
+ end
21
+ end
22
+
23
+ # self.property
24
+ if default.respond_to?(:call) # default is callable
25
+ define_singleton_method(getter) do
26
+ if class_variable_defined?(class_var)
27
+ class_variable_get(class_var)
28
+ else
29
+ default.()
30
+ end
31
+ end
32
+ else # default is literal object
33
+ default_value_name = "DEFAULT_#{property}".upcase.to_sym
34
+ const_set(default_value_name, default)
35
+ define_singleton_method(getter) do
36
+ if class_variable_defined?(class_var)
37
+ class_variable_get(class_var)
38
+ else
39
+ const_get(default_value_name)
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ NO_OP = -> { }.freeze
48
+ end
@@ -0,0 +1,41 @@
1
+ require 'pry'
2
+
3
+ # We're managing the loading of plugins. So don't let pry autoload them.
4
+ ::Pry.config.should_load_plugins = false
5
+
6
+ if defined? ::Rails
7
+ STDERR.puts 'JF pry-rails' if ENV['SPIRIT_FINGERS_PLUGIN_DEBUG']
8
+ require 'pry-rails'
9
+ end
10
+
11
+ module SpiritHands
12
+ autoload :Print, 'spirit_hands/print'
13
+ autoload :Prompt, 'spirit_hands/prompt'
14
+
15
+ class << self
16
+ @installed = false
17
+ # This modifies pry to play our tune
18
+ def melody!(app = nil)
19
+ return false if @installed
20
+
21
+ # Require all of our pry plugins
22
+ require 'spirit_hands/load_plugins'
23
+
24
+ setup_less_colorize
25
+ setup_less_show_raw_unicode
26
+ setup_hirb
27
+
28
+ # Use awesome_print for output, but keep pry's pager. If Hirb is
29
+ # enabled, try printing with it first.
30
+ ::SpiritHands::Print.install!
31
+
32
+ # Friendlier prompt - line number, app name, nesting levels look like
33
+ # directory paths.
34
+ #
35
+ # Configuration (like Pry.color) can be changed later or even during console usage.
36
+ ::SpiritHands::Prompt.install!(app)
37
+
38
+ @installed = true
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,12 @@
1
+ module SpiritHands
2
+ class << self
3
+ # Alias for Pry.color
4
+ def color
5
+ ::Pry.color
6
+ end
7
+
8
+ def color=(v)
9
+ ::Pry.color = v
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,34 @@
1
+ autoload :Hirb, '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,42 @@
1
+ require 'shellwords'
2
+
3
+ module SpiritHands
4
+ class << self
5
+ # Allow less to display colorized output (default: true)
6
+ # (If, set updates LESS env var)
7
+ def less_colorize
8
+ ENV['LESS'].to_s.shellsplit.any? { |arg| arg == LESS_R_LONG || arg =~ LESS_R }
9
+ end
10
+
11
+ # true: add -R to LESS env var (default)
12
+ # false: remove -R from LESS env var
13
+ # nil: set to default (true)
14
+ def less_colorize=(n)
15
+ n = DEFAULT_LESS_COLORIZE if n.nil?
16
+
17
+ args = ENV['LESS'].to_s.shellsplit.map do |arg|
18
+ next if arg == LESS_R_LONG
19
+ if arg =~ LESS_R
20
+ arg = $1 + $2
21
+ end
22
+ arg unless arg.empty?
23
+ end
24
+ args << '-R' if n
25
+ new_less = args.collect.to_a.shelljoin
26
+ ENV['LESS'] = new_less.empty? ? nil : new_less
27
+ @less_colorize = !!n
28
+ end
29
+
30
+ private
31
+
32
+ def setup_less_colorize
33
+ self.less_colorize = nil unless @less_colorize
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ DEFAULT_LESS_COLORIZE = true
40
+ LESS_R_LONG = '--RAW-CONTROL-CHARS'.freeze
41
+ LESS_R = /\A(.*-[^-R]*)R(.*)\z/.freeze
42
+ end
@@ -0,0 +1,38 @@
1
+ require 'shellwords'
2
+
3
+ module SpiritHands
4
+ class << self
5
+ # Allow less to display colorized output (default: true)
6
+ # (If, set updates LESS env var)
7
+ def less_show_raw_unicode
8
+ ENV['LESSUTFBINFMT'] == LESS_SHOW_RAW_BINFMT
9
+ end
10
+
11
+ # true: set LESSUTFBINFMT to %*c
12
+ # false: unset LESSUTFBINFMT
13
+ # String: set custom LESSUTFBINFMT
14
+ # nil: set default(true)
15
+ def less_show_raw_unicode=(n)
16
+ n = DEFAULT_LESS_SHOW_RAW_UNICODE if n.nil?
17
+ ENV['LESSUTFBINFMT'] = if n.is_a?(String)
18
+ n
19
+ elsif n
20
+ LESS_SHOW_RAW_BINFMT
21
+ else
22
+ nil
23
+ end
24
+ @less_show_raw_unicode = !!n
25
+ end
26
+
27
+ private
28
+
29
+ def setup_less_show_raw_unicode
30
+ self.less_show_raw_unicode = nil unless @less_show_raw_unicode
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ DEFAULT_LESS_SHOW_RAW_UNICODE = true
37
+ LESS_SHOW_RAW_BINFMT = '*n%c'.freeze
38
+ end
@@ -0,0 +1,2 @@
1
+ require 'spirit_hands/options/less/colorize'
2
+ require 'spirit_hands/options/less/show_raw_unicode'
@@ -0,0 +1,57 @@
1
+ # encoding: UTF-8
2
+ require 'readline'
3
+ require 'spirit_hands/mattr_accessor_with_default'
4
+ require 'spirit_hands/options/color'
5
+ require 'spirit_hands/options/less'
6
+ require 'spirit_hands/options/hirb'
7
+
8
+ module SpiritHands
9
+ autoload :Terminal, 'spirit_hands/terminal'
10
+
11
+ ### Options ###
12
+
13
+ # When printing values, start with this (default: '=> ')
14
+ mattr_accessor_with_default :value_prompt, '=> '
15
+
16
+ # Spaces to indent value (default: 2 spaces)
17
+ mattr_accessor_with_default :value_indent, 2
18
+
19
+ # Name of the app, which can be displayed to <app/> tag in prompt
20
+ mattr_accessor_with_default :app, -> {
21
+ # Trumpet emoji or pry
22
+ (Terminal.unicode?) ? "\u{1F3BA}" : 'pry'
23
+ }
24
+
25
+ # <color>...</color>
26
+ # <bold>...</color>
27
+ # <cmd/> command number
28
+ # <app/> SpiritHands.app, which can be String or a Rails Applicatino object
29
+ # <sep/> SpiritHands.prompt_separator
30
+ #
31
+ # Use \ to escape literal <, so in a Ruby string constant, "\\<"
32
+ #
33
+ mattr_accessor_with_default :prompt,
34
+ '<b>[<cmd/>]</b> <blue><app/></blue><tgt/> <red><sep/></red> '
35
+
36
+ # Color the prompt?
37
+ #
38
+ # A different setting than Pry.color since some may like colored output, but a
39
+ # plain prompt.
40
+ #
41
+ # Default: 'true' for GNU readline or rb-readline which correctly count line
42
+ # widths with color codes when using \001 and \002 hints. 'false' for
43
+ # libedit-based wrapper (standard on OS X unless ruby is explicitly compiled
44
+ # otherwise).
45
+ mattr_accessor_with_default :colored_prompt, -> { ::Readline::VERSION !~ /EditLine/ }
46
+
47
+ # Separator between application name and input in the prompt.
48
+ #
49
+ # Default: right angle quote (chevron) or >
50
+ #
51
+ mattr_accessor_with_default :prompt_separator, -> {
52
+ (Terminal.unicode?) ? "\u{BB}" : '>'
53
+ }
54
+
55
+ # Enable or disable AwesomePrint (default: true)
56
+ mattr_accessor_with_default :awesome_print, true
57
+ end
@@ -0,0 +1,28 @@
1
+ module SpiritHands
2
+ class << self
3
+ # A thin wrapper around require for troubleshooting
4
+ def plugin(*requires)
5
+ cond = requires.pop if requires.last.respond_to? :call
6
+ requires.each do |r|
7
+ begin
8
+ if cond && !cond.()
9
+ plugin_debug "JF require #{r} (skipped)"
10
+ next
11
+ end
12
+ res = require r
13
+ rescue LoadError
14
+ plugin_debug "JF require #{r} FAILED"
15
+ else
16
+ plugin_debug "JF require #{r} -> #{res}"
17
+ end
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def plugin_debug(*args)
24
+ return if !ENV['SPIRIT_FINGERS_PLUGIN_DEBUG']
25
+ STDERR.puts(*args)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,72 @@
1
+ module SpiritHands
2
+ module Print
3
+ class << self
4
+ def install!
5
+ ::Pry.config.print = PRINT_FUNCTION
6
+ end
7
+
8
+ def pretty(value)
9
+ if ::SpiritHands.awesome_print
10
+ require 'awesome_print' unless defined?(AwesomePrint)
11
+ opts = { :indent => ::SpiritHands.value_indent }
12
+ opts[:plain] = true if !SpiritHands.color
13
+ value.ai(opts)
14
+ else
15
+ value.inspect
16
+ end
17
+ end
18
+
19
+ def hirb_unicode_enabled?
20
+ ::Hirb::Formatter.dynamic_config.keys.any? do |key|
21
+ if opts = ::Hirb::Formatter.dynamic_config[key][:options]
22
+ opts && opts[:unicode]
23
+ end
24
+ end
25
+ end
26
+
27
+ def print(_output, value, _pry_)
28
+ if ::Hirb.enabled?
29
+ setup_hirb_unicode
30
+ return if ::Hirb::View.view_or_page_output(value)
31
+ end
32
+ _pry_.pager.page("#{::SpiritHands.value_prompt}#{pretty(value)}")
33
+ end
34
+
35
+ private
36
+
37
+ PRINT_FUNCTION = ->(_output, value, _pry_) do
38
+ ::SpiritHands::Print.print(_output, value, _pry_)
39
+ end
40
+
41
+ def hirb_unicode_enable
42
+ return false unless ::SpiritHands::Terminal.unicode?
43
+ require 'hirb/unicode'
44
+
45
+ ::Hirb::Formatter.dynamic_config.keys.each do |key|
46
+ ::Hirb::Formatter.dynamic_config[key][:options] ||= {}
47
+ ::Hirb::Formatter.dynamic_config[key][:options][:unicode] = true
48
+ end
49
+ true
50
+ end
51
+
52
+ def hirb_unicode_disable
53
+ ::Hirb::Formatter.dynamic_config.keys.each do |key|
54
+ ::Hirb::Formatter.dynamic_config[key][:options] ||= {}
55
+ ::Hirb::Formatter.dynamic_config[key][:options][:unicode] = false
56
+ end
57
+ false
58
+ end
59
+
60
+ def setup_hirb_unicode
61
+ if hirb_unicode_enabled? != SpiritHands.hirb_unicode
62
+ if SpiritHands.hirb_unicode
63
+ hirb_unicode_enable
64
+ else
65
+ hirb_unicode_disable
66
+ end
67
+ end
68
+ nil
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,249 @@
1
+ module SpiritHands
2
+ module Prompt
3
+ class << self
4
+ private
5
+
6
+ def render(state, prompt, color = true)
7
+ r = Render.new(state, prompt, color)
8
+ res = r.to_s
9
+ STDERR.puts "\n" + (r.errors * "\n") + "\n" if r.errors?
10
+ res
11
+ end
12
+ end
13
+
14
+ # :object Object
15
+ # :level Fixnum
16
+ # :pry Pry
17
+ # :app String or Rails::Application
18
+ # :multiline false: normal prompt, true: multiline prompt
19
+ State = Struct.new(:object, :level, :pry, :app, :multiline)
20
+
21
+ # <....>
22
+ # <..../>
23
+ # </....>
24
+ #
25
+ class Render
26
+ # <tag> ... </tag>, tag -> inner part of escape codes
27
+ MATCHED_TAG_CODES = {
28
+ 'b' => 1,
29
+ 'bold' => 1,
30
+ 'bright' => 1,
31
+ 'strong' => 1,
32
+
33
+ 'dark' => 2,
34
+ 'faint' => 2,
35
+
36
+ 'i' => 3,
37
+ 'italic' => 3,
38
+ 'em' => 3,
39
+
40
+ 'u' => 4,
41
+ 'underline' => 4,
42
+
43
+ 'blink' => 5, # evil
44
+ 'flash' => 5,
45
+
46
+ 'rapid-blink' => 6, # sinister
47
+ 'rapid-flash' => 6,
48
+
49
+ 'reverse' => 7,
50
+ 'negative' => 7,
51
+ 'inverse' => 7,
52
+
53
+ 'concealed' => 8,
54
+
55
+ 'strike' => 9,
56
+ 'strikethrough' => 9,
57
+
58
+ 'black' => 30,
59
+ 'red' => 31,
60
+ 'green' => 32,
61
+ 'yellow' => 33,
62
+ 'blue' => 34,
63
+ 'magenta' => 35,
64
+ 'cyan' => 36,
65
+ 'white' => 37,
66
+
67
+ 'bgblack' => 40,
68
+ 'bgred' => 41,
69
+ 'bggreen' => 42,
70
+ 'bgyellow' => 43,
71
+ 'bgblue' => 44,
72
+ 'bgmagenta' => 45,
73
+ 'bgcyan' => 46,
74
+ 'bgwhite' => 47,
75
+ }
76
+
77
+ # <.../>
78
+ SINGLE_TAGS = {
79
+ # <cmd/>: command number
80
+ 'cmd' => ->(state) { state.pry.input_array.size },
81
+
82
+ # <tgt/>: target string
83
+ 'tgt' => ->(state) {
84
+ unless (str = Pry.view_clip(state.object)) == 'main'
85
+ state.level = 0 if state.level < 0
86
+ "(#{'../' * state.level}#{str})"
87
+ else
88
+ ''
89
+ end
90
+ },
91
+
92
+ # <app/>: state.app (Object) converted to String
93
+ 'app' => ->(state) {
94
+ app = state.app
95
+ if app.class.respond_to?(:parent_name) && \
96
+ app.class.parent_name.respond_to?(:underscore)
97
+ app.class.parent_name.underscore
98
+ elsif app
99
+ app.to_s
100
+ else
101
+ ::SpiritHands.app
102
+ end
103
+ },
104
+
105
+ # <sep/>: SpiritHands.prompt_separator
106
+ 'sep' => ->(_state) {
107
+ ::SpiritHands.prompt_separator
108
+ }
109
+ }
110
+
111
+ # Array<String>
112
+ attr_reader :errors
113
+
114
+ def errors?
115
+ errors.any?
116
+ end
117
+
118
+ # :state SpiritHands::Prompt::State
119
+ # :prompt String
120
+ # :color true or false/nil
121
+ def initialize(state, prompt, color)
122
+ @state = state
123
+ @prompt = prompt
124
+ @color = color
125
+ end
126
+
127
+ def to_s
128
+ @errors = []
129
+ @tag_stack = []
130
+ @result = ''
131
+ @color_applied = false
132
+ @in_tag = false
133
+
134
+ @prompt.each_char do |c|
135
+ if @in_tag
136
+ tag_char(c)
137
+ else
138
+ nontag_char(c)
139
+ end
140
+ end
141
+
142
+ # @tag_stack.any? --> error/s
143
+ @tag_stack.each { |t| errors << "<#{t}>: Missing </#{t}>" }
144
+
145
+ (errors?) ? '' : @result
146
+ end
147
+
148
+ private
149
+
150
+ def tag_char(c)
151
+ case c
152
+ when '/'
153
+ # close: </
154
+ # single <.+/
155
+ @tag_type = (@tag.blank?) ? :close : :single
156
+ when '>' # close tag
157
+ @tag.downcase!
158
+ send @tag_type # :start, :close or :single
159
+ @in_tag = false
160
+ else # append to existing tag
161
+ @tag += c
162
+ end
163
+ end
164
+
165
+ def nontag_char(c)
166
+ if @escape
167
+ nontag_escaped_char(c)
168
+ else
169
+ nontag_unescaped_char(c)
170
+ end
171
+ end
172
+
173
+ def nontag_escaped_char(c)
174
+ @escape = false
175
+ @result += (@state.multiline) ? ' ' : c
176
+ end
177
+
178
+ def nontag_unescaped_char(c)
179
+ case c
180
+ when '\\' # escape next char
181
+ @escape = true
182
+ when '<' # start tag
183
+ @in_tag = true
184
+ @tag_type = :start
185
+ @tag = ''
186
+ else # normal char
187
+ @result += (@state.multiline) ? ' ' : c
188
+ end
189
+ end
190
+
191
+ # <...>
192
+ def start
193
+ code = MATCHED_TAG_CODES[@tag]
194
+ if !code
195
+ errors << "Unknown <#{@tag}>"
196
+ return
197
+ end
198
+ @result += esc(code)
199
+ @tag_stack << @tag
200
+ end
201
+
202
+ # </...>
203
+ def close
204
+ code = MATCHED_TAG_CODES[@tag]
205
+ if !code
206
+ errors << "Unknown </#{@tag}>"
207
+ return
208
+ end
209
+ idx = @tag_stack.rindex @tag
210
+ if idx.nil?
211
+ errors << "</#{@tag}>: missing start <#{@tag}>"
212
+ return
213
+ end
214
+ # remove the now closed tag from the stack
215
+ @tag_stack.delete_at idx
216
+ # reset and reapply all codes on the @tag_stack
217
+ @result += reset
218
+ @tag_stack.each { |tag| @result += esc(MATCHED_TAG_CODES[tag]) }
219
+ end
220
+
221
+ # <.../>
222
+ def single
223
+ f = SINGLE_TAGS[@tag]
224
+ if !f
225
+ errors << "Unknown </#{@tag}>"
226
+ return
227
+ end
228
+ result = f.(@state).to_s
229
+
230
+ # blank out all but sep for multiline prompt, vs. main (normal)
231
+ if @state.multiline && @tag != 'sep'
232
+ result = ' ' * result.length
233
+ end
234
+ @result += result
235
+ end
236
+
237
+ def reset
238
+ esc(0)
239
+ end
240
+
241
+ # convert a code to an actual character
242
+ def esc(code)
243
+ return '' if !@color
244
+ @color_applied = true
245
+ "\001\e[#{code}m\002".freeze
246
+ end
247
+ end
248
+ end
249
+ end
@@ -0,0 +1,18 @@
1
+ require 'spirit_hands/prompt/base'
2
+
3
+ module SpiritHands
4
+ module Prompt
5
+ class << self
6
+ private
7
+
8
+ # Normal, main pry prompt
9
+ def main
10
+ ->(object, level, pry) do
11
+ s = State.new(object, level, pry, ::SpiritHands.app, false)
12
+ color = ::SpiritHands.color && ::SpiritHands.colored_prompt
13
+ render(s, ::SpiritHands.prompt, color)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ require 'spirit_hands/prompt/base'
2
+
3
+ module SpiritHands
4
+ module Prompt
5
+ class << self
6
+ private
7
+
8
+ # Wait pry prompt in multiline input
9
+ def multiline
10
+ ->(object, level, pry) {
11
+ s = State.new(object, level, pry, ::SpiritHands.app, true)
12
+ render(s, ::SpiritHands.prompt, ::SpiritHands.color && ::SpiritHands.colored_prompt)
13
+ }
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ require 'spirit_hands/prompt/main'
2
+ require 'spirit_hands/prompt/multiline'
3
+
4
+ module SpiritHands
5
+ module Prompt
6
+ class << self
7
+ def install!(app = nil)
8
+ ::SpiritHands.app ||= app
9
+ ::Pry.config.prompt = [ main, multiline ].freeze
10
+ end
11
+ end
12
+ end
13
+ end