spirit_hands 2.0.8-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/.gitignore +17 -0
  4. data/.pryrc +1 -0
  5. data/.ruby-gemset +1 -0
  6. data/CHANGELOG.md +147 -0
  7. data/CONTRIBUTING.md +18 -0
  8. data/CONTRIBUTORS.md +10 -0
  9. data/Gemfile +3 -0
  10. data/LICENSE.md +22 -0
  11. data/README.md +138 -0
  12. data/Rakefile +127 -0
  13. data/gem-public_cert.pem +32 -0
  14. data/lib/spirit_hands/hirb/fixes/enabled.rb +36 -0
  15. data/lib/spirit_hands/hirb/fixes/pager.rb +144 -0
  16. data/lib/spirit_hands/hirb/fixes/util.rb +19 -0
  17. data/lib/spirit_hands/hirb/fixes/view.rb +10 -0
  18. data/lib/spirit_hands/hirb/fixes.rb +5 -0
  19. data/lib/spirit_hands/hirb.rb +2 -0
  20. data/lib/spirit_hands/mattr_accessor_with_default.rb +44 -0
  21. data/lib/spirit_hands/melody.rb +24 -0
  22. data/lib/spirit_hands/options/color.rb +10 -0
  23. data/lib/spirit_hands/options/hirb.rb +34 -0
  24. data/lib/spirit_hands/options/less/colorize.rb +41 -0
  25. data/lib/spirit_hands/options/less/show_raw_unicode.rb +36 -0
  26. data/lib/spirit_hands/options/less.rb +2 -0
  27. data/lib/spirit_hands/options.rb +59 -0
  28. data/lib/spirit_hands/print.rb +75 -0
  29. data/lib/spirit_hands/prompt/base/render.rb +231 -0
  30. data/lib/spirit_hands/prompt/base.rb +24 -0
  31. data/lib/spirit_hands/prompt/main.rb +18 -0
  32. data/lib/spirit_hands/prompt/multiline.rb +17 -0
  33. data/lib/spirit_hands/prompt.rb +12 -0
  34. data/lib/spirit_hands/railtie.rb +7 -0
  35. data/lib/spirit_hands/terminal.rb +16 -0
  36. data/lib/spirit_hands/version.rb +3 -0
  37. data/lib/spirit_hands.rb +21 -0
  38. data/spirit_hands.gemspec +42 -0
  39. data.tar.gz.sig +0 -0
  40. metadata +239 -0
  41. metadata.gz.sig +0 -0
@@ -0,0 +1,144 @@
1
+ # Fixes pager_command
2
+ require 'hirb'
3
+ require 'shellwords'
4
+
5
+ module Hirb
6
+ # This class provides class methods for paging and an object which can conditionally page given a terminal size that is exceeded.
7
+ class Pager
8
+ class << self
9
+ # Pages using a configured or detected shell command.
10
+ def command_pager(output, options={})
11
+ if valid_pager_command?(pc = options[:pager_command])
12
+ basic_pager(output, pc)
13
+ end
14
+ end
15
+
16
+ # Exposed to allow user-custom, external-driven formatting
17
+ def basic_pager(output, override_pager_command=nil)
18
+ pc = basic_pager_command(override_pager_command)
19
+ pager = IO.popen(pc, "w")
20
+ begin
21
+ save_stdout = STDOUT.clone
22
+ STDOUT.reopen(pager)
23
+ STDOUT.puts output
24
+ rescue Errno::EPIPE
25
+ ensure
26
+ STDOUT.reopen(save_stdout)
27
+ save_stdout.close
28
+ pager.close
29
+ end
30
+ end
31
+
32
+ def pager_command=(*commands) #:nodoc:
33
+ @pager_command = pager_command_select(*commands)
34
+ end
35
+
36
+ def pager_command #:nodoc:
37
+ @pager_command || pager_command_select
38
+ end
39
+
40
+ # Pages with a ruby-only pager which either pages or quits.
41
+ def default_pager(output, options={})
42
+ pager = new(options[:width], options[:height])
43
+ while pager.activated_by?(output, options[:inspect])
44
+ puts pager.slice!(output, options[:inspect])
45
+ return unless continue_paging?
46
+ end
47
+ puts output
48
+ puts "=== Pager finished. ==="
49
+ end
50
+
51
+ def page(string, inspect_mode, pgr_cmd, width, height)
52
+ if valid_pager_command?(pgr_cmd)
53
+ command_pager(string, :pager_command=>pgr_cmd)
54
+ else
55
+ default_pager(string, :width=>width, :height=>height, :inspect=>inspect_mode)
56
+ end
57
+ end
58
+
59
+ private
60
+
61
+ #:stopdoc:
62
+ def valid_pager_command?(cmd)
63
+ cmd && Util.command_exists?(cmd.shellsplit[0])
64
+ end
65
+
66
+ # Default pager commands to try
67
+ def pager_command_fallbacks #:nodoc:
68
+ candidates = %w[less more pager cat]
69
+ candidates.unshift ENV['PAGER'] if ENV['PAGER']
70
+ candidates
71
+ end
72
+
73
+ # Pick the first valid command from commands
74
+ def pager_command_select(*commands)
75
+ commands += pager_command_fallbacks
76
+ commands.flatten.compact.uniq.find { |c| valid_pager_command? c }
77
+ end
78
+
79
+ # Actual command basic_pager needs to perform
80
+ def basic_pager_command(override_pager_command)
81
+ if valid_pager_command?(override_pager_command)
82
+ override_pager_command
83
+ else
84
+ pager_command
85
+ end
86
+ end
87
+
88
+ def continue_paging?
89
+ puts "=== Press enter/return to continue or q to quit: ==="
90
+ !$stdin.gets.chomp[/q/i]
91
+ end
92
+ #:startdoc:
93
+ end # class methods
94
+
95
+ attr_reader :width, :height, :options
96
+
97
+ def initialize(width, height, options={})
98
+ resize(width, height)
99
+ @options = options
100
+ end
101
+
102
+ def pager_command
103
+ options[:pager_command] || self.class.pager_command
104
+ end
105
+
106
+ # Pages given string using configured pager.
107
+ def page(string, inspect_mode)
108
+ self.class.page(string, inspect_mode, pager_command, @width, @height)
109
+ end
110
+
111
+ def slice!(output, inspect_mode=false) #:nodoc:
112
+ effective_height = @height - 2 # takes into account pager prompt
113
+ if inspect_mode
114
+ sliced_output = String.slice(output, 0, @width * effective_height)
115
+ output.replace String.slice(output, char_count(sliced_output), String.size(output))
116
+ sliced_output
117
+ else
118
+ # could use output.scan(/[^\n]*\n?/) instead of split
119
+ sliced_output = output.split("\n").slice(0, effective_height).join("\n")
120
+ output.replace output.split("\n").slice(effective_height..-1).join("\n")
121
+ sliced_output
122
+ end
123
+ end
124
+
125
+ # Determines if string should be paged based on configured width and height.
126
+ def activated_by?(string_to_page, inspect_mode=false)
127
+ inspect_mode ? (String.size(string_to_page) > @height * @width) : (string_to_page.count("\n") > @height)
128
+ end
129
+
130
+ if String.method_defined? :chars
131
+ def char_count(string) #:nodoc:
132
+ string.chars.count
133
+ end
134
+ else
135
+ def char_count(string) #:nodoc:
136
+ String.size(string)
137
+ end
138
+ end
139
+
140
+ def resize(width, height) #:nodoc:
141
+ @width, @height = View.determine_terminal_size(width, height)
142
+ end
143
+ end # Pager
144
+ end # Hirb
@@ -0,0 +1,19 @@
1
+ require 'hirb'
2
+ require 'pathname'
3
+
4
+ class << Hirb::Util
5
+ # Determines if a shell command exists by searching for it in ENV['PATH'].
6
+ # (Fixed version)
7
+ def command_exists?(command)
8
+ if c = Pathname.new(command)
9
+ return true if c.absolute? && c.exist?
10
+ end
11
+ executable_file_exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
12
+ ENV['PATH'].split(File::PATH_SEPARATOR).any? do |d|
13
+ executable_file_exts.any? do |ext|
14
+ f = File.expand_path(command + ext, d)
15
+ File.executable?(f) && !File.directory?(f)
16
+ end
17
+ end
18
+ end
19
+ end # Hirb::Util.self
@@ -0,0 +1,10 @@
1
+ # Integrate Hirb + SpiritHands print output (AwesomePrint / inspect)
2
+ require 'hirb'
3
+ require 'spirit_hands'
4
+
5
+ class << Hirb::View
6
+ def view_or_page_output(str)
7
+ view_output(str) ||
8
+ page_output(::SpiritHands::Print.pretty(str), true)
9
+ end
10
+ end # Hirb::View.self
@@ -0,0 +1,5 @@
1
+ require 'hirb'
2
+ require 'spirit_hands/hirb/fixes/pager'
3
+ require 'spirit_hands/hirb/fixes/util'
4
+ require 'spirit_hands/hirb/fixes/view'
5
+ require 'spirit_hands/hirb/fixes/enabled'
@@ -0,0 +1,2 @@
1
+ require 'hirb'
2
+ require 'spirit_hands/hirb/fixes'
@@ -0,0 +1,44 @@
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
+ end # Module
@@ -0,0 +1,24 @@
1
+ require 'pry'
2
+
3
+ class << SpiritHands
4
+ # This modifies pry to play our tune
5
+ def melody!(app = nil)
6
+ return false if @installed
7
+ @installed = true
8
+
9
+ SpiritHands.app = app unless app.nil?
10
+ setup_less_colorize
11
+ setup_less_show_raw_unicode
12
+ setup_hirb
13
+
14
+ # Use awesome_print for output, but keep pry's pager. If Hirb is
15
+ # enabled, try printing with it first.
16
+ ::SpiritHands::Print.install!
17
+
18
+ # Friendlier prompt - line number, app name, nesting levels look like
19
+ # directory paths.
20
+ #
21
+ # Configuration (like Pry.color) can be changed later or even during console usage.
22
+ ::SpiritHands::Prompt.install!
23
+ end
24
+ end # SpiritHands.self
@@ -0,0 +1,10 @@
1
+ class << SpiritHands
2
+ # Alias for Pry.color
3
+ def color
4
+ ::Pry.color
5
+ end
6
+
7
+ def color=(v)
8
+ ::Pry.color = v
9
+ end
10
+ end # SpiritHands.self
@@ -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,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,2 @@
1
+ require 'spirit_hands/options/less/colorize'
2
+ require 'spirit_hands/options/less/show_raw_unicode'
@@ -0,0 +1,59 @@
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
+ ### Options ###
10
+
11
+ # When printing values, start with this (default: '=> ')
12
+ mattr_accessor_with_default :value_prompt, '=> '
13
+
14
+ # Spaces to indent value (default: 2 spaces)
15
+ mattr_accessor_with_default :value_indent, 2
16
+
17
+ # Name of the app, which can be displayed to <app/> tag in prompt
18
+ mattr_accessor_with_default :app, -> {
19
+ if defined?(::Rails)
20
+ ::Rails.application
21
+ else
22
+ # Trumpet emoji or pry
23
+ (Terminal.unicode?) ? "\u{1F3BA}" : 'pry'
24
+ end
25
+ }
26
+
27
+ # <color>...</color>
28
+ # <bold>...</color>
29
+ # <cmd/> command number
30
+ # <app/> SpiritHands.app, which can be String or a Rails Applicatino object
31
+ # <sep/> SpiritHands.prompt_separator
32
+ #
33
+ # Use \ to escape literal <, so in a Ruby string constant, "\\<"
34
+ #
35
+ mattr_accessor_with_default :prompt,
36
+ '<b>[<cmd/>]</b> <blue><app/></blue><tgt/> <red><sep/></red> '
37
+
38
+ # Color the prompt?
39
+ #
40
+ # A different setting than Pry.color since some may like colored output, but a
41
+ # plain prompt.
42
+ #
43
+ # Default: 'true' for GNU readline or rb-readline which correctly count line
44
+ # widths with color codes when using \001 and \002 hints. 'false' for
45
+ # libedit-based wrapper (standard on OS X unless ruby is explicitly compiled
46
+ # otherwise).
47
+ mattr_accessor_with_default :colored_prompt, -> { ::Readline::VERSION !~ /EditLine/ }
48
+
49
+ # Separator between application name and input in the prompt.
50
+ #
51
+ # Default: right angle quote (chevron) or >
52
+ #
53
+ mattr_accessor_with_default :prompt_separator, -> {
54
+ (Terminal.unicode?) ? "\u{BB}" : '>'
55
+ }
56
+
57
+ # Enable or disable AwesomePrint (default: true)
58
+ mattr_accessor_with_default :awesome_print, true
59
+ end
@@ -0,0 +1,75 @@
1
+ module SpiritHands
2
+ module Print
3
+ class << self
4
+ PRINT_FUNCTION = ->(_output, value, _pry_) do
5
+ ::SpiritHands::Print.print(_output, value, _pry_)
6
+ end
7
+
8
+ def install!
9
+ ::Pry.config.print = PRINT_FUNCTION
10
+ end
11
+
12
+ def pretty(value)
13
+ if ::SpiritHands.awesome_print
14
+ require 'awesome_print' unless defined?(AwesomePrint)
15
+ opts = { :indent => ::SpiritHands.value_indent }
16
+ opts[:plain] = true if !SpiritHands.color
17
+ value.ai(opts)
18
+ else
19
+ value.inspect
20
+ end
21
+ end
22
+
23
+ def hirb_unicode_enabled?
24
+ ::Hirb::Formatter.dynamic_config.keys.any? do |key|
25
+ if opts = ::Hirb::Formatter.dynamic_config[key][:options]
26
+ opts && opts[:unicode]
27
+ end
28
+ end
29
+ end
30
+
31
+ def print(_output, value, _pry_)
32
+ if ::Hirb.enabled?
33
+ setup_hirb_unicode
34
+ return if ::Hirb::View.view_or_page_output(value)
35
+ end
36
+ _pry_.pager.open do |pager|
37
+ pager.print ::SpiritHands.value_prompt
38
+ pager.puts pretty(value)
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def hirb_unicode_enable
45
+ return false unless ::SpiritHands::Terminal.unicode?
46
+ require 'hirb/unicode'
47
+
48
+ ::Hirb::Formatter.dynamic_config.keys.each do |key|
49
+ ::Hirb::Formatter.dynamic_config[key][:options] ||= {}
50
+ ::Hirb::Formatter.dynamic_config[key][:options][:unicode] = true
51
+ end
52
+ true
53
+ end
54
+
55
+ def hirb_unicode_disable
56
+ ::Hirb::Formatter.dynamic_config.keys.each do |key|
57
+ ::Hirb::Formatter.dynamic_config[key][:options] ||= {}
58
+ ::Hirb::Formatter.dynamic_config[key][:options][:unicode] = false
59
+ end
60
+ false
61
+ end
62
+
63
+ def setup_hirb_unicode
64
+ if hirb_unicode_enabled? != SpiritHands.hirb_unicode
65
+ if SpiritHands.hirb_unicode
66
+ hirb_unicode_enable
67
+ else
68
+ hirb_unicode_disable
69
+ end
70
+ end
71
+ nil
72
+ end
73
+ end # self
74
+ end # Print
75
+ end # SpiritHands