super-smart-mod 0.0.1
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/pry-0.16.0/CHANGELOG.md +1211 -0
- data/pry-0.16.0/LICENSE +25 -0
- data/pry-0.16.0/README.md +469 -0
- data/pry-0.16.0/bin/pry +13 -0
- data/pry-0.16.0/lib/pry/basic_object.rb +10 -0
- data/pry-0.16.0/lib/pry/block_command.rb +22 -0
- data/pry-0.16.0/lib/pry/class_command.rb +194 -0
- data/pry-0.16.0/lib/pry/cli.rb +211 -0
- data/pry-0.16.0/lib/pry/code/code_file.rb +114 -0
- data/pry-0.16.0/lib/pry/code/code_range.rb +73 -0
- data/pry-0.16.0/lib/pry/code/loc.rb +105 -0
- data/pry-0.16.0/lib/pry/code.rb +357 -0
- data/pry-0.16.0/lib/pry/code_object.rb +197 -0
- data/pry-0.16.0/lib/pry/color_printer.rb +66 -0
- data/pry-0.16.0/lib/pry/command.rb +520 -0
- data/pry-0.16.0/lib/pry/command_set.rb +418 -0
- data/pry-0.16.0/lib/pry/command_state.rb +36 -0
- data/pry-0.16.0/lib/pry/commands/amend_line.rb +103 -0
- data/pry-0.16.0/lib/pry/commands/bang.rb +24 -0
- data/pry-0.16.0/lib/pry/commands/bang_pry.rb +21 -0
- data/pry-0.16.0/lib/pry/commands/cat/abstract_formatter.rb +32 -0
- data/pry-0.16.0/lib/pry/commands/cat/exception_formatter.rb +90 -0
- data/pry-0.16.0/lib/pry/commands/cat/file_formatter.rb +77 -0
- data/pry-0.16.0/lib/pry/commands/cat/input_expression_formatter.rb +48 -0
- data/pry-0.16.0/lib/pry/commands/cat.rb +70 -0
- data/pry-0.16.0/lib/pry/commands/cd.rb +48 -0
- data/pry-0.16.0/lib/pry/commands/change_inspector.rb +34 -0
- data/pry-0.16.0/lib/pry/commands/change_prompt.rb +51 -0
- data/pry-0.16.0/lib/pry/commands/clear_screen.rb +20 -0
- data/pry-0.16.0/lib/pry/commands/code_collector.rb +182 -0
- data/pry-0.16.0/lib/pry/commands/disable_pry.rb +31 -0
- data/pry-0.16.0/lib/pry/commands/easter_eggs.rb +101 -0
- data/pry-0.16.0/lib/pry/commands/edit/exception_patcher.rb +29 -0
- data/pry-0.16.0/lib/pry/commands/edit/file_and_line_locator.rb +47 -0
- data/pry-0.16.0/lib/pry/commands/edit.rb +225 -0
- data/pry-0.16.0/lib/pry/commands/exit.rb +47 -0
- data/pry-0.16.0/lib/pry/commands/exit_all.rb +33 -0
- data/pry-0.16.0/lib/pry/commands/exit_program.rb +27 -0
- data/pry-0.16.0/lib/pry/commands/find_method.rb +199 -0
- data/pry-0.16.0/lib/pry/commands/fix_indent.rb +23 -0
- data/pry-0.16.0/lib/pry/commands/help.rb +171 -0
- data/pry-0.16.0/lib/pry/commands/hist.rb +182 -0
- data/pry-0.16.0/lib/pry/commands/import_set.rb +27 -0
- data/pry-0.16.0/lib/pry/commands/jump_to.rb +33 -0
- data/pry-0.16.0/lib/pry/commands/list_inspectors.rb +42 -0
- data/pry-0.16.0/lib/pry/commands/ls/config.rb +54 -0
- data/pry-0.16.0/lib/pry/commands/ls/constants.rb +75 -0
- data/pry-0.16.0/lib/pry/commands/ls/formatter.rb +55 -0
- data/pry-0.16.0/lib/pry/commands/ls/globals.rb +50 -0
- data/pry-0.16.0/lib/pry/commands/ls/grep.rb +23 -0
- data/pry-0.16.0/lib/pry/commands/ls/instance_vars.rb +40 -0
- data/pry-0.16.0/lib/pry/commands/ls/interrogatable.rb +24 -0
- data/pry-0.16.0/lib/pry/commands/ls/jruby_hacks.rb +55 -0
- data/pry-0.16.0/lib/pry/commands/ls/local_names.rb +37 -0
- data/pry-0.16.0/lib/pry/commands/ls/local_vars.rb +47 -0
- data/pry-0.16.0/lib/pry/commands/ls/ls_entity.rb +65 -0
- data/pry-0.16.0/lib/pry/commands/ls/methods.rb +55 -0
- data/pry-0.16.0/lib/pry/commands/ls/methods_helper.rb +50 -0
- data/pry-0.16.0/lib/pry/commands/ls/self_methods.rb +34 -0
- data/pry-0.16.0/lib/pry/commands/ls.rb +114 -0
- data/pry-0.16.0/lib/pry/commands/nesting.rb +29 -0
- data/pry-0.16.0/lib/pry/commands/play.rb +113 -0
- data/pry-0.16.0/lib/pry/commands/pry_backtrace.rb +30 -0
- data/pry-0.16.0/lib/pry/commands/pry_version.rb +21 -0
- data/pry-0.16.0/lib/pry/commands/raise_up.rb +38 -0
- data/pry-0.16.0/lib/pry/commands/reload_code.rb +74 -0
- data/pry-0.16.0/lib/pry/commands/reset.rb +22 -0
- data/pry-0.16.0/lib/pry/commands/ri.rb +75 -0
- data/pry-0.16.0/lib/pry/commands/save_file.rb +63 -0
- data/pry-0.16.0/lib/pry/commands/shell_command.rb +75 -0
- data/pry-0.16.0/lib/pry/commands/shell_mode.rb +30 -0
- data/pry-0.16.0/lib/pry/commands/show_doc.rb +84 -0
- data/pry-0.16.0/lib/pry/commands/show_info.rb +234 -0
- data/pry-0.16.0/lib/pry/commands/show_input.rb +22 -0
- data/pry-0.16.0/lib/pry/commands/show_source.rb +57 -0
- data/pry-0.16.0/lib/pry/commands/stat.rb +44 -0
- data/pry-0.16.0/lib/pry/commands/switch_to.rb +29 -0
- data/pry-0.16.0/lib/pry/commands/toggle_color.rb +28 -0
- data/pry-0.16.0/lib/pry/commands/watch_expression/expression.rb +43 -0
- data/pry-0.16.0/lib/pry/commands/watch_expression.rb +108 -0
- data/pry-0.16.0/lib/pry/commands/whereami.rb +205 -0
- data/pry-0.16.0/lib/pry/commands/wtf.rb +95 -0
- data/pry-0.16.0/lib/pry/config/attributable.rb +22 -0
- data/pry-0.16.0/lib/pry/config/lazy_value.rb +29 -0
- data/pry-0.16.0/lib/pry/config/memoized_value.rb +34 -0
- data/pry-0.16.0/lib/pry/config/value.rb +24 -0
- data/pry-0.16.0/lib/pry/config.rb +321 -0
- data/pry-0.16.0/lib/pry/control_d_handler.rb +28 -0
- data/pry-0.16.0/lib/pry/core_extensions.rb +144 -0
- data/pry-0.16.0/lib/pry/editor.rb +157 -0
- data/pry-0.16.0/lib/pry/env.rb +18 -0
- data/pry-0.16.0/lib/pry/exception_handler.rb +48 -0
- data/pry-0.16.0/lib/pry/exceptions.rb +73 -0
- data/pry-0.16.0/lib/pry/forwardable.rb +27 -0
- data/pry-0.16.0/lib/pry/helpers/base_helpers.rb +71 -0
- data/pry-0.16.0/lib/pry/helpers/command_helpers.rb +146 -0
- data/pry-0.16.0/lib/pry/helpers/documentation_helpers.rb +84 -0
- data/pry-0.16.0/lib/pry/helpers/options_helpers.rb +34 -0
- data/pry-0.16.0/lib/pry/helpers/platform.rb +55 -0
- data/pry-0.16.0/lib/pry/helpers/table.rb +121 -0
- data/pry-0.16.0/lib/pry/helpers/text.rb +118 -0
- data/pry-0.16.0/lib/pry/helpers.rb +8 -0
- data/pry-0.16.0/lib/pry/history.rb +153 -0
- data/pry-0.16.0/lib/pry/hooks.rb +180 -0
- data/pry-0.16.0/lib/pry/indent.rb +414 -0
- data/pry-0.16.0/lib/pry/input/simple_stdio.rb +13 -0
- data/pry-0.16.0/lib/pry/input_completer.rb +283 -0
- data/pry-0.16.0/lib/pry/input_lock.rb +129 -0
- data/pry-0.16.0/lib/pry/inspector.rb +39 -0
- data/pry-0.16.0/lib/pry/last_exception.rb +61 -0
- data/pry-0.16.0/lib/pry/method/disowned.rb +67 -0
- data/pry-0.16.0/lib/pry/method/patcher.rb +131 -0
- data/pry-0.16.0/lib/pry/method/weird_method_locator.rb +222 -0
- data/pry-0.16.0/lib/pry/method.rb +599 -0
- data/pry-0.16.0/lib/pry/object_path.rb +91 -0
- data/pry-0.16.0/lib/pry/output.rb +136 -0
- data/pry-0.16.0/lib/pry/pager.rb +249 -0
- data/pry-0.16.0/lib/pry/prompt.rb +214 -0
- data/pry-0.16.0/lib/pry/pry_class.rb +371 -0
- data/pry-0.16.0/lib/pry/pry_instance.rb +663 -0
- data/pry-0.16.0/lib/pry/repl.rb +326 -0
- data/pry-0.16.0/lib/pry/repl_file_loader.rb +79 -0
- data/pry-0.16.0/lib/pry/ring.rb +89 -0
- data/pry-0.16.0/lib/pry/slop/LICENSE +20 -0
- data/pry-0.16.0/lib/pry/slop/commands.rb +190 -0
- data/pry-0.16.0/lib/pry/slop/option.rb +210 -0
- data/pry-0.16.0/lib/pry/slop.rb +672 -0
- data/pry-0.16.0/lib/pry/syntax_highlighter.rb +26 -0
- data/pry-0.16.0/lib/pry/system_command_handler.rb +17 -0
- data/pry-0.16.0/lib/pry/testable/evalable.rb +24 -0
- data/pry-0.16.0/lib/pry/testable/mockable.rb +22 -0
- data/pry-0.16.0/lib/pry/testable/pry_tester.rb +88 -0
- data/pry-0.16.0/lib/pry/testable/utility.rb +34 -0
- data/pry-0.16.0/lib/pry/testable/variables.rb +52 -0
- data/pry-0.16.0/lib/pry/testable.rb +68 -0
- data/pry-0.16.0/lib/pry/version.rb +5 -0
- data/pry-0.16.0/lib/pry/warning.rb +20 -0
- data/pry-0.16.0/lib/pry/wrapped_module/candidate.rb +145 -0
- data/pry-0.16.0/lib/pry/wrapped_module.rb +382 -0
- data/pry-0.16.0/lib/pry.rb +148 -0
- data/super-smart-mod.gemspec +12 -0
- metadata +182 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Pry
|
|
4
|
+
class Output
|
|
5
|
+
# @return [Array<Integer>] default terminal screen size [rows, cols]
|
|
6
|
+
DEFAULT_SIZE = [27, 80].freeze
|
|
7
|
+
|
|
8
|
+
attr_reader :pry_instance
|
|
9
|
+
|
|
10
|
+
def initialize(pry_instance)
|
|
11
|
+
@output = pry_instance.config.output
|
|
12
|
+
@color = pry_instance.config.color
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def puts(*objs)
|
|
16
|
+
return print "\n" if objs.empty?
|
|
17
|
+
|
|
18
|
+
objs.each do |obj|
|
|
19
|
+
if (ary = Array.try_convert(obj))
|
|
20
|
+
puts(*ary)
|
|
21
|
+
else
|
|
22
|
+
print "#{obj.to_s.chomp}\n"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
nil
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def print(*objs)
|
|
29
|
+
objs.each do |obj|
|
|
30
|
+
@output.print decolorize_maybe(obj.to_s)
|
|
31
|
+
end
|
|
32
|
+
nil
|
|
33
|
+
end
|
|
34
|
+
alias << print
|
|
35
|
+
alias write print
|
|
36
|
+
|
|
37
|
+
def tty?
|
|
38
|
+
@output.respond_to?(:tty?) && @output.tty?
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def method_missing(method_name, *args, &block)
|
|
42
|
+
if @output.respond_to?(method_name)
|
|
43
|
+
@output.__send__(method_name, *args, &block)
|
|
44
|
+
else
|
|
45
|
+
super
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def respond_to_missing?(method_name, include_private = false)
|
|
50
|
+
@output.respond_to?(method_name, include_private)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def decolorize_maybe(str)
|
|
54
|
+
return str if @color
|
|
55
|
+
|
|
56
|
+
Pry::Helpers::Text.strip_color(str)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# @return [Array<Integer>] a pair of [rows, columns] which gives the size of
|
|
60
|
+
# the window. If the window size cannot be determined, the default value.
|
|
61
|
+
def size
|
|
62
|
+
rows, cols = actual_screen_size
|
|
63
|
+
return [rows.to_i, cols.to_i] if rows.to_i != 0 && cols.to_i != 0
|
|
64
|
+
|
|
65
|
+
DEFAULT_SIZE
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Return a screen width or the default if that fails.
|
|
69
|
+
def width
|
|
70
|
+
size.last
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Return a screen height or the default if that fails.
|
|
74
|
+
def height
|
|
75
|
+
size.first
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
def actual_screen_size
|
|
81
|
+
# The best way, if possible (requires non-jruby >=1.9 or io-console gem).
|
|
82
|
+
io_console_size ||
|
|
83
|
+
# Fall back to the old standby, though it might be stale.
|
|
84
|
+
env_size ||
|
|
85
|
+
# Fall further back, though this one is also out of date without
|
|
86
|
+
# something calling Readline.set_screen_size.
|
|
87
|
+
readline_size ||
|
|
88
|
+
# Windows users can otherwise run ansicon and get a decent answer.
|
|
89
|
+
ansicon_env_size
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def io_console_size
|
|
93
|
+
return if Pry::Helpers::Platform.jruby?
|
|
94
|
+
|
|
95
|
+
begin
|
|
96
|
+
require 'io/console'
|
|
97
|
+
|
|
98
|
+
begin
|
|
99
|
+
@output.winsize if tty? && @output.respond_to?(:winsize)
|
|
100
|
+
rescue Errno::EOPNOTSUPP # rubocop:disable Lint/HandleExceptions
|
|
101
|
+
# Output is probably a socket, which doesn't support #winsize.
|
|
102
|
+
end
|
|
103
|
+
rescue LoadError # rubocop:disable Lint/HandleExceptions
|
|
104
|
+
# They probably don't have the io/console stdlib or the io-console gem.
|
|
105
|
+
# We'll keep trying.
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def env_size
|
|
110
|
+
size = [Pry::Env['LINES'] || Pry::Env['ROWS'], Pry::Env['COLUMNS']]
|
|
111
|
+
size if nonzero_column?(size)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def readline_size
|
|
115
|
+
return unless defined?(Readline) && Readline.respond_to?(:get_screen_size)
|
|
116
|
+
|
|
117
|
+
size = Readline.get_screen_size
|
|
118
|
+
size if nonzero_column?(size)
|
|
119
|
+
rescue Java::JavaLang::NullPointerException
|
|
120
|
+
# This rescue won't happen on jrubies later than:
|
|
121
|
+
# https://github.com/jruby/jruby/pull/436
|
|
122
|
+
nil
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def ansicon_env_size
|
|
126
|
+
return unless Pry::Env['ANSICON'] =~ /\((.*)x(.*)\)/
|
|
127
|
+
|
|
128
|
+
size = [Regexp.last_match(2), Regexp.last_match(1)]
|
|
129
|
+
size if nonzero_column?(size)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def nonzero_column?(size)
|
|
133
|
+
size[1].to_i > 0
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# A pager is an `IO`-like object that accepts text and either prints it
|
|
4
|
+
# immediately, prints it one page at a time, or streams it to an external
|
|
5
|
+
# program to print one page at a time.
|
|
6
|
+
class Pry
|
|
7
|
+
class Pager
|
|
8
|
+
class StopPaging < StandardError
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
attr_reader :pry_instance
|
|
12
|
+
|
|
13
|
+
def initialize(pry_instance)
|
|
14
|
+
@pry_instance = pry_instance
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Send the given text through the best available pager (if
|
|
18
|
+
# `Pry.config.pager` is enabled). If you want to send text through in
|
|
19
|
+
# chunks as you generate it, use `open` to get a writable object
|
|
20
|
+
# instead.
|
|
21
|
+
#
|
|
22
|
+
# @param [String] text
|
|
23
|
+
# Text to run through a pager.
|
|
24
|
+
#
|
|
25
|
+
def page(text)
|
|
26
|
+
open do |pager|
|
|
27
|
+
pager << text
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Yields a pager object (`NullPager`, `SimplePager`, or `SystemPager`).
|
|
32
|
+
# All pagers accept output with `#puts`, `#print`, `#write`, and `#<<`.
|
|
33
|
+
def open
|
|
34
|
+
pager = best_available
|
|
35
|
+
yield pager
|
|
36
|
+
rescue StopPaging # rubocop:disable Lint/HandleExceptions
|
|
37
|
+
ensure
|
|
38
|
+
pager.close if pager
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def enabled?
|
|
44
|
+
!!@enabled
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
attr_reader :output
|
|
48
|
+
|
|
49
|
+
# Return an instance of the "best" available pager class --
|
|
50
|
+
# `SystemPager` if possible, `SimplePager` if `SystemPager` isn't
|
|
51
|
+
# available, and `NullPager` if the user has disabled paging. All
|
|
52
|
+
# pagers accept output with `#puts`, `#print`, `#write`, and `#<<`. You
|
|
53
|
+
# must call `#close` when you're done writing output to a pager, and
|
|
54
|
+
# you must rescue `Pry::Pager::StopPaging`. These requirements can be
|
|
55
|
+
# avoided by using `.open` instead.
|
|
56
|
+
def best_available
|
|
57
|
+
if !pry_instance.config.pager
|
|
58
|
+
NullPager.new(pry_instance.output)
|
|
59
|
+
elsif !SystemPager.available? || Helpers::Platform.jruby?
|
|
60
|
+
SimplePager.new(pry_instance.output)
|
|
61
|
+
else
|
|
62
|
+
SystemPager.new(pry_instance.output)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# `NullPager` is a "pager" that actually just prints all output as it
|
|
67
|
+
# comes in. Used when `Pry.config.pager` is false.
|
|
68
|
+
class NullPager
|
|
69
|
+
def initialize(out)
|
|
70
|
+
@out = out
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def puts(str)
|
|
74
|
+
print "#{str.chomp}\n"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def print(str)
|
|
78
|
+
write str
|
|
79
|
+
end
|
|
80
|
+
alias << print
|
|
81
|
+
|
|
82
|
+
def write(str)
|
|
83
|
+
@out.write str
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def close; end
|
|
87
|
+
|
|
88
|
+
private
|
|
89
|
+
|
|
90
|
+
def height
|
|
91
|
+
@height ||= @out.height
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def width
|
|
95
|
+
@width ||= @out.width
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# `SimplePager` is a straightforward pure-Ruby pager. We use it on
|
|
100
|
+
# JRuby and when we can't find a usable external pager.
|
|
101
|
+
class SimplePager < NullPager
|
|
102
|
+
def initialize(*)
|
|
103
|
+
super
|
|
104
|
+
@tracker = PageTracker.new(height - 3, width)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def write(str)
|
|
108
|
+
str.lines.each do |line|
|
|
109
|
+
@out.print line
|
|
110
|
+
@tracker.record line
|
|
111
|
+
|
|
112
|
+
next unless @tracker.page?
|
|
113
|
+
|
|
114
|
+
@out.print "\n"
|
|
115
|
+
@out.print "\e[0m"
|
|
116
|
+
@out.print "<page break> --- Press enter to continue " \
|
|
117
|
+
"( q<enter> to break ) --- <page break>\n"
|
|
118
|
+
raise StopPaging if Readline.readline("").chomp == "q"
|
|
119
|
+
|
|
120
|
+
@tracker.reset
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# `SystemPager` buffers output until we're pretty sure it's at least a
|
|
126
|
+
# page long, then invokes an external pager and starts streaming output
|
|
127
|
+
# to it. If `#close` is called before then, it just prints out the
|
|
128
|
+
# buffered content.
|
|
129
|
+
class SystemPager < NullPager
|
|
130
|
+
def self.default_pager
|
|
131
|
+
pager = Pry::Env['PAGER'] || ''
|
|
132
|
+
|
|
133
|
+
# Default to less, and make sure less is being passed the correct
|
|
134
|
+
# options
|
|
135
|
+
pager = "less -R -F -X" if pager.strip.empty? || pager =~ /^less\b/
|
|
136
|
+
|
|
137
|
+
pager
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
@system_pager = nil
|
|
141
|
+
|
|
142
|
+
def self.available?
|
|
143
|
+
if @system_pager.nil?
|
|
144
|
+
@system_pager =
|
|
145
|
+
begin
|
|
146
|
+
pager_executable = default_pager.split(' ').first
|
|
147
|
+
if Helpers::Platform.windows? || Helpers::Platform.windows_ansi?
|
|
148
|
+
`where /Q #{pager_executable}`
|
|
149
|
+
else
|
|
150
|
+
`which #{pager_executable}`
|
|
151
|
+
end
|
|
152
|
+
$CHILD_STATUS.success?
|
|
153
|
+
rescue StandardError
|
|
154
|
+
false
|
|
155
|
+
end
|
|
156
|
+
else
|
|
157
|
+
@system_pager
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def initialize(*)
|
|
162
|
+
super
|
|
163
|
+
@tracker = PageTracker.new(height, width)
|
|
164
|
+
@buffer = ""
|
|
165
|
+
@pager = nil
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def write(str)
|
|
169
|
+
if invoked_pager?
|
|
170
|
+
write_to_pager str
|
|
171
|
+
else
|
|
172
|
+
@tracker.record str
|
|
173
|
+
@buffer += str
|
|
174
|
+
|
|
175
|
+
write_to_pager @buffer if @tracker.page?
|
|
176
|
+
end
|
|
177
|
+
rescue Errno::EPIPE
|
|
178
|
+
raise StopPaging
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def close
|
|
182
|
+
if invoked_pager?
|
|
183
|
+
pager.close
|
|
184
|
+
else
|
|
185
|
+
@out.puts @buffer
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
private
|
|
190
|
+
|
|
191
|
+
def write_to_pager(text)
|
|
192
|
+
pager.write @out.decolorize_maybe(text)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def invoked_pager?
|
|
196
|
+
@pager
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def pager
|
|
200
|
+
@pager ||= IO.popen(self.class.default_pager, 'w')
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# `PageTracker` tracks output to determine whether it's likely to take
|
|
205
|
+
# up a whole page. This doesn't need to be super precise, but we can
|
|
206
|
+
# use it for `SimplePager` and to avoid invoking the system pager
|
|
207
|
+
# unnecessarily.
|
|
208
|
+
#
|
|
209
|
+
# One simplifying assumption is that we don't need `#page?` to return
|
|
210
|
+
# `true` on the basis of an incomplete line. Long lines should be
|
|
211
|
+
# counted as multiple lines, but we don't have to transition from
|
|
212
|
+
# `false` to `true` until we see a newline.
|
|
213
|
+
class PageTracker
|
|
214
|
+
def initialize(rows, cols)
|
|
215
|
+
@rows = rows
|
|
216
|
+
@cols = cols
|
|
217
|
+
reset
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def record(str)
|
|
221
|
+
str.lines.each do |line|
|
|
222
|
+
if line.end_with? "\n"
|
|
223
|
+
@row += ((@col + line_length(line) - 1) / @cols) + 1
|
|
224
|
+
@col = 0
|
|
225
|
+
else
|
|
226
|
+
@col += line_length(line)
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def page?
|
|
232
|
+
@row >= @rows
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def reset
|
|
236
|
+
@row = 0
|
|
237
|
+
@col = 0
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
private
|
|
241
|
+
|
|
242
|
+
# Approximation of the printable length of a given line, without the
|
|
243
|
+
# newline and without ANSI color codes.
|
|
244
|
+
def line_length(line)
|
|
245
|
+
line.chomp.gsub(/\e\[[\d;]*m/, '').length
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
end
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Pry
|
|
4
|
+
# Prompt represents the Pry prompt, which can be used with Readline-like
|
|
5
|
+
# libraries. It defines a few default prompts (default prompt, simple prompt,
|
|
6
|
+
# etc) and also provides an API for adding and implementing custom prompts.
|
|
7
|
+
#
|
|
8
|
+
# @example Registering a new Pry prompt
|
|
9
|
+
# Pry::Prompt.add(
|
|
10
|
+
# :ipython,
|
|
11
|
+
# 'IPython-like prompt', [':', '...:']
|
|
12
|
+
# ) do |_context, _nesting, pry_instance, sep|
|
|
13
|
+
# sep == ':' ? "In [#{pry_instance.input_ring.count}]: " : ' ...: '
|
|
14
|
+
# end
|
|
15
|
+
#
|
|
16
|
+
# # Produces:
|
|
17
|
+
# # In [3]: def foo
|
|
18
|
+
# # ...: puts 'foo'
|
|
19
|
+
# # ...: end
|
|
20
|
+
# # => :foo
|
|
21
|
+
# # In [4]:
|
|
22
|
+
#
|
|
23
|
+
# @example Manually instantiating the Prompt class
|
|
24
|
+
# prompt_procs = [
|
|
25
|
+
# proc { '#{rand(1)}>" },
|
|
26
|
+
# proc { "#{('a'..'z').to_a.sample}*" }
|
|
27
|
+
# ]
|
|
28
|
+
# prompt = Pry::Prompt.new(
|
|
29
|
+
# :random,
|
|
30
|
+
# 'Random number or letter prompt.',
|
|
31
|
+
# prompt_procs
|
|
32
|
+
# )
|
|
33
|
+
# prompt.wait_proc.call(...) #=>
|
|
34
|
+
# prompt.incomplete_proc.call(...)
|
|
35
|
+
#
|
|
36
|
+
# @since v0.11.0
|
|
37
|
+
# @api public
|
|
38
|
+
class Prompt
|
|
39
|
+
# A Hash that holds all prompts. The keys of the Hash are prompt
|
|
40
|
+
# names, the values are Hash instances of the format {:description, :value}.
|
|
41
|
+
@prompts = {}
|
|
42
|
+
|
|
43
|
+
class << self
|
|
44
|
+
# Retrieves a prompt.
|
|
45
|
+
#
|
|
46
|
+
# @example
|
|
47
|
+
# Prompt[:my_prompt]
|
|
48
|
+
#
|
|
49
|
+
# @param [Symbol] name The name of the prompt you want to access
|
|
50
|
+
# @return [Hash{Symbol=>Object}]
|
|
51
|
+
# @since v0.12.0
|
|
52
|
+
def [](name)
|
|
53
|
+
@prompts[name.to_s]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# @return [Hash{Symbol=>Hash}] the duplicate of the internal prompts hash
|
|
57
|
+
# @note Use this for read-only operations
|
|
58
|
+
# @since v0.12.0
|
|
59
|
+
def all
|
|
60
|
+
@prompts.dup
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Adds a new prompt to the prompt hash.
|
|
64
|
+
#
|
|
65
|
+
# @param [Symbol] name
|
|
66
|
+
# @param [String] description
|
|
67
|
+
# @param [Array<String>] separators The separators to differentiate
|
|
68
|
+
# between prompt modes (default mode and class/method definition mode).
|
|
69
|
+
# The Array *must* have a size of 2.
|
|
70
|
+
# @yield [context, nesting, pry_instance, sep]
|
|
71
|
+
# @yieldparam context [Object] the context where Pry is currently in
|
|
72
|
+
# @yieldparam nesting [Integer] whether the context is nested
|
|
73
|
+
# @yieldparam pry_instance [Pry] the Pry instance
|
|
74
|
+
# @yieldparam separator [String] separator string
|
|
75
|
+
# @return [nil]
|
|
76
|
+
# @raise [ArgumentError] if the size of `separators` is not 2
|
|
77
|
+
# @raise [ArgumentError] if `prompt_name` is already occupied
|
|
78
|
+
# @since v0.12.0
|
|
79
|
+
def add(name, description = '', separators = %w[> *])
|
|
80
|
+
name = name.to_s
|
|
81
|
+
|
|
82
|
+
unless separators.size == 2
|
|
83
|
+
raise ArgumentError, "separators size must be 2, given #{separators.size}"
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
if @prompts.key?(name)
|
|
87
|
+
raise ArgumentError, "the '#{name}' prompt was already added"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
@prompts[name] = new(
|
|
91
|
+
name,
|
|
92
|
+
description,
|
|
93
|
+
separators.map do |sep|
|
|
94
|
+
proc do |context, nesting, pry_instance|
|
|
95
|
+
yield(context, nesting, pry_instance, sep)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
nil
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# @return [String]
|
|
105
|
+
attr_reader :name
|
|
106
|
+
|
|
107
|
+
# @return [String]
|
|
108
|
+
attr_reader :description
|
|
109
|
+
|
|
110
|
+
# @return [Array<Proc>] the array of procs that hold
|
|
111
|
+
# `[wait_proc, incomplete_proc]`
|
|
112
|
+
attr_reader :prompt_procs
|
|
113
|
+
|
|
114
|
+
# @param [String] name
|
|
115
|
+
# @param [String] description
|
|
116
|
+
# @param [Array<Proc>] prompt_procs
|
|
117
|
+
def initialize(name, description, prompt_procs)
|
|
118
|
+
@name = name
|
|
119
|
+
@description = description
|
|
120
|
+
@prompt_procs = prompt_procs
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# @return [Proc] the proc which builds the wait prompt (`>`)
|
|
124
|
+
def wait_proc
|
|
125
|
+
@prompt_procs.first
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# @return [Proc] the proc which builds the prompt when in the middle of an
|
|
129
|
+
# expression such as open method, etc. (`*`)
|
|
130
|
+
def incomplete_proc
|
|
131
|
+
@prompt_procs.last
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# @deprecated Use a `Pry::Prompt` instance directly
|
|
135
|
+
def [](key)
|
|
136
|
+
key = key.to_s
|
|
137
|
+
if %w[name description].include?(key)
|
|
138
|
+
Pry::Warning.warn(
|
|
139
|
+
"`Pry::Prompt[:#{@name}][:#{key}]` is deprecated. " \
|
|
140
|
+
"Use `#{self.class}##{key}` instead"
|
|
141
|
+
)
|
|
142
|
+
public_send(key)
|
|
143
|
+
elsif key.to_s == 'value'
|
|
144
|
+
Pry::Warning.warn(
|
|
145
|
+
"`#{self.class}[:#{@name}][:value]` is deprecated. Use " \
|
|
146
|
+
"`#{self.class}#prompt_procs` instead or an instance of " \
|
|
147
|
+
"`#{self.class}` directly"
|
|
148
|
+
)
|
|
149
|
+
@prompt_procs
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
add(
|
|
154
|
+
:default,
|
|
155
|
+
"The default Pry prompt. Includes information about the current expression \n" \
|
|
156
|
+
"number, evaluation context, and nesting level, plus a reminder that you're \n" \
|
|
157
|
+
'using Pry.'
|
|
158
|
+
) do |context, nesting, pry_instance, sep|
|
|
159
|
+
format(
|
|
160
|
+
"[%<in_count>s] %<name>s(%<context>s)%<nesting>s%<separator>s ",
|
|
161
|
+
in_count: pry_instance.input_ring.count,
|
|
162
|
+
name: pry_instance.config.prompt_name,
|
|
163
|
+
context: Pry.view_clip(context),
|
|
164
|
+
nesting: (nesting > 0 ? ":#{nesting}" : ''),
|
|
165
|
+
separator: sep
|
|
166
|
+
)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
add(
|
|
170
|
+
:simple,
|
|
171
|
+
"A simple `>>`.",
|
|
172
|
+
['>> ', ' | ']
|
|
173
|
+
) do |_, _, _, sep|
|
|
174
|
+
sep
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
add(
|
|
178
|
+
:nav,
|
|
179
|
+
"A prompt that displays the binding stack as a path and includes information \n" \
|
|
180
|
+
"about #{Helpers::Text.bold('_in_')} and #{Helpers::Text.bold('_out_')}.",
|
|
181
|
+
%w[> *]
|
|
182
|
+
) do |_context, _nesting, pry_instance, sep|
|
|
183
|
+
tree = pry_instance.binding_stack.map { |b| Pry.view_clip(b.eval('self')) }
|
|
184
|
+
format(
|
|
185
|
+
"[%<in_count>s] (%<name>s) %<tree>s: %<stack_size>s%<separator>s ",
|
|
186
|
+
in_count: pry_instance.input_ring.count,
|
|
187
|
+
name: pry_instance.config.prompt_name,
|
|
188
|
+
tree: tree.join(' / '),
|
|
189
|
+
stack_size: pry_instance.binding_stack.size - 1,
|
|
190
|
+
separator: sep
|
|
191
|
+
)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
add(
|
|
195
|
+
:shell,
|
|
196
|
+
'A prompt that displays `$PWD` as you change it.',
|
|
197
|
+
%w[$ *]
|
|
198
|
+
) do |context, _nesting, pry_instance, sep|
|
|
199
|
+
format(
|
|
200
|
+
"%<name>s %<context>s:%<pwd>s %<separator>s ",
|
|
201
|
+
name: pry_instance.config.prompt_name,
|
|
202
|
+
context: Pry.view_clip(context),
|
|
203
|
+
pwd: Dir.pwd,
|
|
204
|
+
separator: sep
|
|
205
|
+
)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
add(
|
|
209
|
+
:none,
|
|
210
|
+
'Wave goodbye to the Pry prompt.',
|
|
211
|
+
Array.new(2)
|
|
212
|
+
) { '' }
|
|
213
|
+
end
|
|
214
|
+
end
|