pry 0.10.0.pre4-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +702 -0
- data/LICENSE +25 -0
- data/README.md +406 -0
- data/bin/pry +16 -0
- data/lib/pry.rb +161 -0
- data/lib/pry/cli.rb +220 -0
- data/lib/pry/code.rb +341 -0
- data/lib/pry/code/code_file.rb +103 -0
- data/lib/pry/code/code_range.rb +71 -0
- data/lib/pry/code/loc.rb +92 -0
- data/lib/pry/code_object.rb +172 -0
- data/lib/pry/color_printer.rb +55 -0
- data/lib/pry/command.rb +692 -0
- data/lib/pry/command_set.rb +443 -0
- data/lib/pry/commands.rb +6 -0
- data/lib/pry/commands/amend_line.rb +99 -0
- data/lib/pry/commands/bang.rb +20 -0
- data/lib/pry/commands/bang_pry.rb +17 -0
- data/lib/pry/commands/cat.rb +62 -0
- data/lib/pry/commands/cat/abstract_formatter.rb +27 -0
- data/lib/pry/commands/cat/exception_formatter.rb +77 -0
- data/lib/pry/commands/cat/file_formatter.rb +67 -0
- data/lib/pry/commands/cat/input_expression_formatter.rb +43 -0
- data/lib/pry/commands/cd.rb +41 -0
- data/lib/pry/commands/change_inspector.rb +27 -0
- data/lib/pry/commands/change_prompt.rb +26 -0
- data/lib/pry/commands/code_collector.rb +165 -0
- data/lib/pry/commands/disable_pry.rb +27 -0
- data/lib/pry/commands/disabled_commands.rb +2 -0
- data/lib/pry/commands/easter_eggs.rb +112 -0
- data/lib/pry/commands/edit.rb +195 -0
- data/lib/pry/commands/edit/exception_patcher.rb +25 -0
- data/lib/pry/commands/edit/file_and_line_locator.rb +36 -0
- data/lib/pry/commands/exit.rb +42 -0
- data/lib/pry/commands/exit_all.rb +29 -0
- data/lib/pry/commands/exit_program.rb +23 -0
- data/lib/pry/commands/find_method.rb +193 -0
- data/lib/pry/commands/fix_indent.rb +19 -0
- data/lib/pry/commands/gem_cd.rb +26 -0
- data/lib/pry/commands/gem_install.rb +32 -0
- data/lib/pry/commands/gem_list.rb +33 -0
- data/lib/pry/commands/gem_open.rb +29 -0
- data/lib/pry/commands/gist.rb +101 -0
- data/lib/pry/commands/help.rb +164 -0
- data/lib/pry/commands/hist.rb +180 -0
- data/lib/pry/commands/import_set.rb +22 -0
- data/lib/pry/commands/install_command.rb +53 -0
- data/lib/pry/commands/jump_to.rb +29 -0
- data/lib/pry/commands/list_inspectors.rb +35 -0
- data/lib/pry/commands/list_prompts.rb +35 -0
- data/lib/pry/commands/ls.rb +114 -0
- data/lib/pry/commands/ls/constants.rb +47 -0
- data/lib/pry/commands/ls/formatter.rb +49 -0
- data/lib/pry/commands/ls/globals.rb +48 -0
- data/lib/pry/commands/ls/grep.rb +21 -0
- data/lib/pry/commands/ls/instance_vars.rb +39 -0
- data/lib/pry/commands/ls/interrogatable.rb +18 -0
- data/lib/pry/commands/ls/jruby_hacks.rb +49 -0
- data/lib/pry/commands/ls/local_names.rb +35 -0
- data/lib/pry/commands/ls/local_vars.rb +39 -0
- data/lib/pry/commands/ls/ls_entity.rb +70 -0
- data/lib/pry/commands/ls/methods.rb +57 -0
- data/lib/pry/commands/ls/methods_helper.rb +46 -0
- data/lib/pry/commands/ls/self_methods.rb +32 -0
- data/lib/pry/commands/nesting.rb +25 -0
- data/lib/pry/commands/play.rb +103 -0
- data/lib/pry/commands/pry_backtrace.rb +25 -0
- data/lib/pry/commands/pry_version.rb +17 -0
- data/lib/pry/commands/raise_up.rb +32 -0
- data/lib/pry/commands/reload_code.rb +62 -0
- data/lib/pry/commands/reset.rb +18 -0
- data/lib/pry/commands/ri.rb +60 -0
- data/lib/pry/commands/save_file.rb +61 -0
- data/lib/pry/commands/shell_command.rb +48 -0
- data/lib/pry/commands/shell_mode.rb +25 -0
- data/lib/pry/commands/show_doc.rb +83 -0
- data/lib/pry/commands/show_info.rb +195 -0
- data/lib/pry/commands/show_input.rb +17 -0
- data/lib/pry/commands/show_source.rb +50 -0
- data/lib/pry/commands/simple_prompt.rb +22 -0
- data/lib/pry/commands/stat.rb +40 -0
- data/lib/pry/commands/switch_to.rb +23 -0
- data/lib/pry/commands/toggle_color.rb +24 -0
- data/lib/pry/commands/watch_expression.rb +105 -0
- data/lib/pry/commands/watch_expression/expression.rb +38 -0
- data/lib/pry/commands/whereami.rb +190 -0
- data/lib/pry/commands/wtf.rb +57 -0
- data/lib/pry/config.rb +24 -0
- data/lib/pry/config/behavior.rb +139 -0
- data/lib/pry/config/convenience.rb +26 -0
- data/lib/pry/config/default.rb +165 -0
- data/lib/pry/core_extensions.rb +131 -0
- data/lib/pry/editor.rb +133 -0
- data/lib/pry/exceptions.rb +77 -0
- data/lib/pry/helpers.rb +5 -0
- data/lib/pry/helpers/base_helpers.rb +113 -0
- data/lib/pry/helpers/command_helpers.rb +156 -0
- data/lib/pry/helpers/documentation_helpers.rb +75 -0
- data/lib/pry/helpers/options_helpers.rb +27 -0
- data/lib/pry/helpers/table.rb +109 -0
- data/lib/pry/helpers/text.rb +107 -0
- data/lib/pry/history.rb +125 -0
- data/lib/pry/history_array.rb +121 -0
- data/lib/pry/hooks.rb +230 -0
- data/lib/pry/indent.rb +406 -0
- data/lib/pry/input_completer.rb +242 -0
- data/lib/pry/input_lock.rb +132 -0
- data/lib/pry/inspector.rb +27 -0
- data/lib/pry/last_exception.rb +61 -0
- data/lib/pry/method.rb +546 -0
- data/lib/pry/method/disowned.rb +53 -0
- data/lib/pry/method/patcher.rb +125 -0
- data/lib/pry/method/weird_method_locator.rb +186 -0
- data/lib/pry/module_candidate.rb +136 -0
- data/lib/pry/object_path.rb +82 -0
- data/lib/pry/output.rb +50 -0
- data/lib/pry/pager.rb +234 -0
- data/lib/pry/plugins.rb +103 -0
- data/lib/pry/prompt.rb +26 -0
- data/lib/pry/pry_class.rb +375 -0
- data/lib/pry/pry_instance.rb +654 -0
- data/lib/pry/rbx_path.rb +22 -0
- data/lib/pry/repl.rb +202 -0
- data/lib/pry/repl_file_loader.rb +74 -0
- data/lib/pry/rubygem.rb +82 -0
- data/lib/pry/terminal.rb +79 -0
- data/lib/pry/test/helper.rb +170 -0
- data/lib/pry/version.rb +3 -0
- data/lib/pry/wrapped_module.rb +373 -0
- metadata +248 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
class Pry
|
2
|
+
module Helpers
|
3
|
+
|
4
|
+
# This class contains methods useful for extracting
|
5
|
+
# documentation from methods and classes.
|
6
|
+
module DocumentationHelpers
|
7
|
+
|
8
|
+
module_function
|
9
|
+
|
10
|
+
def process_rdoc(comment)
|
11
|
+
comment = comment.dup
|
12
|
+
comment.gsub(/<code>(?:\s*\n)?(.*?)\s*<\/code>/m) { CodeRay.scan($1, :ruby).term }.
|
13
|
+
gsub(/<em>(?:\s*\n)?(.*?)\s*<\/em>/m) { "\e[1m#{$1}\e[0m" }.
|
14
|
+
gsub(/<i>(?:\s*\n)?(.*?)\s*<\/i>/m) { "\e[1m#{$1}\e[0m" }.
|
15
|
+
gsub(/\B\+(\w+?)\+\B/) { "\e[32m#{$1}\e[0m" }.
|
16
|
+
gsub(/((?:^[ \t]+.+(?:\n+|\Z))+)/) { CodeRay.scan($1, :ruby).term }.
|
17
|
+
gsub(/`(?:\s*\n)?([^\e]*?)\s*`/) { "`#{CodeRay.scan($1, :ruby).term}`" }
|
18
|
+
end
|
19
|
+
|
20
|
+
def process_yardoc_tag(comment, tag)
|
21
|
+
in_tag_block = nil
|
22
|
+
comment.lines.map do |v|
|
23
|
+
if in_tag_block && v !~ /^\S/
|
24
|
+
Pry::Helpers::Text.strip_color Pry::Helpers::Text.strip_color(v)
|
25
|
+
elsif in_tag_block
|
26
|
+
in_tag_block = false
|
27
|
+
v
|
28
|
+
else
|
29
|
+
in_tag_block = true if v =~ /^@#{tag}/
|
30
|
+
v
|
31
|
+
end
|
32
|
+
end.join
|
33
|
+
end
|
34
|
+
|
35
|
+
def process_yardoc(comment)
|
36
|
+
yard_tags = ["param", "return", "option", "yield", "attr", "attr_reader", "attr_writer",
|
37
|
+
"deprecate", "example", "raise"]
|
38
|
+
(yard_tags - ["example"]).inject(comment) { |a, v| process_yardoc_tag(a, v) }.
|
39
|
+
gsub(/^@(#{yard_tags.join("|")})/) { "\e[33m#{$1}\e[0m" }
|
40
|
+
end
|
41
|
+
|
42
|
+
def process_comment_markup(comment)
|
43
|
+
process_yardoc process_rdoc(comment)
|
44
|
+
end
|
45
|
+
|
46
|
+
# @param [String] code
|
47
|
+
# @return [String]
|
48
|
+
def strip_comments_from_c_code(code)
|
49
|
+
code.sub(/\A\s*\/\*.*?\*\/\s*/m, '')
|
50
|
+
end
|
51
|
+
|
52
|
+
# Given a string that makes up a comment in a source-code file parse out the content
|
53
|
+
# that the user is intended to read. (i.e. without leading indentation, #-characters
|
54
|
+
# or shebangs)
|
55
|
+
#
|
56
|
+
# @param [String] comment
|
57
|
+
# @return [String]
|
58
|
+
def get_comment_content(comment)
|
59
|
+
comment = comment.dup
|
60
|
+
# Remove #!/usr/bin/ruby
|
61
|
+
comment.gsub!(/\A\#!.*$/, '')
|
62
|
+
# Remove leading empty comment lines
|
63
|
+
comment.gsub!(/\A\#+?$/, '')
|
64
|
+
comment.gsub!(/^\s*#/, '')
|
65
|
+
strip_leading_whitespace(comment)
|
66
|
+
end
|
67
|
+
|
68
|
+
# @param [String] text
|
69
|
+
# @return [String]
|
70
|
+
def strip_leading_whitespace(text)
|
71
|
+
Pry::Helpers::CommandHelpers.unindent(text)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class Pry
|
2
|
+
module Helpers
|
3
|
+
module OptionsHelpers
|
4
|
+
module_function
|
5
|
+
|
6
|
+
# Add method options to the Slop instance
|
7
|
+
def method_options(opt)
|
8
|
+
@method_target = target
|
9
|
+
opt.on :M, "instance-methods", "Operate on instance methods."
|
10
|
+
opt.on :m, :methods, "Operate on methods."
|
11
|
+
opt.on :s, :super, "Select the 'super' method. Can be repeated to traverse the ancestors.", :as => :count
|
12
|
+
opt.on :c, :context, "Select object context to run under.", :argument => true do |context|
|
13
|
+
@method_target = Pry.binding_for(target.eval(context))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Get the method object parsed by the slop instance
|
18
|
+
def method_object
|
19
|
+
@method_object ||= get_method_or_raise(args.empty? ? nil : args.join(" "), @method_target,
|
20
|
+
:super => opts[:super],
|
21
|
+
:instance => opts.present?(:'instance-methods') && !opts.present?(:'methods'),
|
22
|
+
:methods => opts.present?(:'methods') && !opts.present?(:'instance-methods')
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
class Pry
|
2
|
+
module Helpers
|
3
|
+
def self.tablify_or_one_line(heading, things)
|
4
|
+
plain_heading = Pry::Helpers::Text.strip_color(heading)
|
5
|
+
attempt = Table.new(things, :column_count => things.size)
|
6
|
+
if attempt.fits_on_line?(Terminal.width! - plain_heading.size - 2)
|
7
|
+
"#{heading}: #{attempt}\n"
|
8
|
+
else
|
9
|
+
"#{heading}: \n#{tablify_to_screen_width(things, :indent => ' ')}\n"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.tablify_to_screen_width(things, options = {})
|
14
|
+
things = things.compact
|
15
|
+
if indent = options[:indent]
|
16
|
+
usable_width = Terminal.width! - indent.size
|
17
|
+
tablify(things, usable_width).to_s.gsub(/^/, indent)
|
18
|
+
else
|
19
|
+
tablify(things, Terminal.width!).to_s
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.tablify(things, line_length)
|
24
|
+
table = Table.new(things, :column_count => things.size)
|
25
|
+
table.column_count -= 1 until 1 == table.column_count or
|
26
|
+
table.fits_on_line?(line_length)
|
27
|
+
table
|
28
|
+
end
|
29
|
+
|
30
|
+
class Table
|
31
|
+
attr_reader :items, :column_count
|
32
|
+
def initialize items, args = {}
|
33
|
+
@column_count = args[:column_count]
|
34
|
+
self.items = items
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_s
|
38
|
+
rows_to_s.join("\n")
|
39
|
+
end
|
40
|
+
|
41
|
+
def rows_to_s style = :color_on
|
42
|
+
widths = columns.map{|e| _max_width(e)}
|
43
|
+
@rows_without_colors.map do |r|
|
44
|
+
padded = []
|
45
|
+
r.each_with_index do |e,i|
|
46
|
+
next unless e
|
47
|
+
item = e.ljust(widths[i])
|
48
|
+
item.sub! e, _recall_color_for(e) if :color_on == style
|
49
|
+
padded << item
|
50
|
+
end
|
51
|
+
padded.join(Pry.config.ls.separator)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def items= items
|
56
|
+
@items = items
|
57
|
+
_rebuild_colorless_cache
|
58
|
+
_recolumn
|
59
|
+
items
|
60
|
+
end
|
61
|
+
|
62
|
+
def column_count= n
|
63
|
+
@column_count = n
|
64
|
+
_recolumn
|
65
|
+
end
|
66
|
+
|
67
|
+
def fits_on_line? line_length
|
68
|
+
_max_width(rows_to_s :no_color) <= line_length
|
69
|
+
end
|
70
|
+
|
71
|
+
def columns
|
72
|
+
@rows_without_colors.transpose
|
73
|
+
end
|
74
|
+
|
75
|
+
def ==(other); items == other.to_a end
|
76
|
+
def to_a; items.to_a end
|
77
|
+
|
78
|
+
private
|
79
|
+
def _max_width(things)
|
80
|
+
things.compact.map(&:size).max || 0
|
81
|
+
end
|
82
|
+
|
83
|
+
def _rebuild_colorless_cache
|
84
|
+
@colorless_cache = {}
|
85
|
+
@plain_items = []
|
86
|
+
items.map do |e|
|
87
|
+
plain = Pry::Helpers::Text.strip_color(e)
|
88
|
+
@colorless_cache[plain] = e
|
89
|
+
@plain_items << plain
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def _recolumn
|
94
|
+
@rows_without_colors = []
|
95
|
+
return if items.size.zero?
|
96
|
+
row_count = (items.size.to_f/column_count).ceil
|
97
|
+
row_count.times do |i|
|
98
|
+
row_indices = (0...column_count).map{|e| row_count*e+i}
|
99
|
+
@rows_without_colors << row_indices.map{|e| @plain_items[e]}
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def _recall_color_for thing
|
104
|
+
@colorless_cache[thing]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
class Pry
|
2
|
+
module Helpers
|
3
|
+
|
4
|
+
# The methods defined on {Text} are available to custom commands via {Pry::Command#text}.
|
5
|
+
module Text
|
6
|
+
|
7
|
+
COLORS =
|
8
|
+
{
|
9
|
+
"black" => 0,
|
10
|
+
"red" => 1,
|
11
|
+
"green" => 2,
|
12
|
+
"yellow" => 3,
|
13
|
+
"blue" => 4,
|
14
|
+
"purple" => 5,
|
15
|
+
"magenta" => 5,
|
16
|
+
"cyan" => 6,
|
17
|
+
"white" => 7
|
18
|
+
}
|
19
|
+
|
20
|
+
class << self
|
21
|
+
|
22
|
+
COLORS.each_pair do |color, value|
|
23
|
+
define_method color do |text|
|
24
|
+
"\033[0;#{30+value}m#{text}\033[0m"
|
25
|
+
end
|
26
|
+
|
27
|
+
define_method "bright_#{color}" do |text|
|
28
|
+
"\033[1;#{30+value}m#{text}\033[0m"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Remove any color codes from _text_.
|
33
|
+
#
|
34
|
+
# @param [String, #to_s] text
|
35
|
+
# @return [String] _text_ stripped of any color codes.
|
36
|
+
def strip_color(text)
|
37
|
+
text.to_s.gsub(/\e\[.*?(\d)+m/ , '')
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns _text_ as bold text for use on a terminal.
|
41
|
+
#
|
42
|
+
# @param [String, #to_s] text
|
43
|
+
# @return [String] _text_
|
44
|
+
def bold(text)
|
45
|
+
"\e[1m#{text}\e[0m"
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns `text` in the default foreground colour.
|
49
|
+
# Use this instead of "black" or "white" when you mean absence of colour.
|
50
|
+
#
|
51
|
+
# @param [String, #to_s] text
|
52
|
+
# @return [String]
|
53
|
+
def default(text)
|
54
|
+
text.to_s
|
55
|
+
end
|
56
|
+
alias_method :bright_default, :bold
|
57
|
+
|
58
|
+
# Executes the block with `Pry.config.color` set to false.
|
59
|
+
# @yield
|
60
|
+
# @return [void]
|
61
|
+
def no_color(&block)
|
62
|
+
boolean = Pry.config.color
|
63
|
+
Pry.config.color = false
|
64
|
+
yield
|
65
|
+
ensure
|
66
|
+
Pry.config.color = boolean
|
67
|
+
end
|
68
|
+
|
69
|
+
# Executes the block with `Pry.config.pager` set to false.
|
70
|
+
# @yield
|
71
|
+
# @return [void]
|
72
|
+
def no_pager(&block)
|
73
|
+
boolean = Pry.config.pager
|
74
|
+
Pry.config.pager = false
|
75
|
+
yield
|
76
|
+
ensure
|
77
|
+
Pry.config.pager = boolean
|
78
|
+
end
|
79
|
+
|
80
|
+
# Returns _text_ in a numbered list, beginning at _offset_.
|
81
|
+
#
|
82
|
+
# @param [#each_line] text
|
83
|
+
# @param [Fixnum] offset
|
84
|
+
# @return [String]
|
85
|
+
def with_line_numbers(text, offset, color=:blue)
|
86
|
+
lines = text.each_line.to_a
|
87
|
+
max_width = (offset + lines.count).to_s.length
|
88
|
+
lines.each_with_index.map do |line, index|
|
89
|
+
adjusted_index = (index + offset).to_s.rjust(max_width)
|
90
|
+
"#{self.send(color, adjusted_index)}: #{line}"
|
91
|
+
end.join
|
92
|
+
end
|
93
|
+
|
94
|
+
# Returns _text_ indented by _chars_ spaces.
|
95
|
+
#
|
96
|
+
# @param [String] text
|
97
|
+
# @param [Fixnum] chars
|
98
|
+
def indent(text, chars)
|
99
|
+
text.lines.map { |l| "#{' ' * chars}#{l}" }.join
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
data/lib/pry/history.rb
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
class Pry
|
2
|
+
# The History class is responsible for maintaining the user's input history,
|
3
|
+
# both internally and within Readline.
|
4
|
+
class History
|
5
|
+
attr_accessor :loader, :saver, :pusher, :clearer
|
6
|
+
|
7
|
+
# @return [Fixnum] Number of lines in history when Pry first loaded.
|
8
|
+
attr_reader :original_lines
|
9
|
+
|
10
|
+
def initialize(options={})
|
11
|
+
@history = []
|
12
|
+
@original_lines = 0
|
13
|
+
@file_path = options[:file_path]
|
14
|
+
restore_default_behavior
|
15
|
+
end
|
16
|
+
|
17
|
+
# Assign the default methods for loading, saving, pushing, and clearing.
|
18
|
+
def restore_default_behavior
|
19
|
+
Pry.config.input # force Readline to load if applicable
|
20
|
+
|
21
|
+
@loader = method(:read_from_file)
|
22
|
+
@saver = method(:save_to_file)
|
23
|
+
|
24
|
+
if defined?(Readline)
|
25
|
+
@pusher = method(:push_to_readline)
|
26
|
+
@clearer = method(:clear_readline)
|
27
|
+
else
|
28
|
+
@pusher = proc { }
|
29
|
+
@clearer = proc { }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Load the input history using `History.loader`.
|
34
|
+
# @return [Integer] The number of lines loaded
|
35
|
+
def load
|
36
|
+
@loader.call do |line|
|
37
|
+
@pusher.call(line.chomp)
|
38
|
+
@history << line.chomp
|
39
|
+
@original_lines += 1
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Add a line to the input history, ignoring blank and duplicate lines.
|
44
|
+
# @param [String] line
|
45
|
+
# @return [String] The same line that was passed in
|
46
|
+
def push(line)
|
47
|
+
unless line.empty? || (@history.last && line == @history.last)
|
48
|
+
@pusher.call(line)
|
49
|
+
@history << line
|
50
|
+
@saver.call(line) if Pry.config.history.should_save
|
51
|
+
end
|
52
|
+
line
|
53
|
+
end
|
54
|
+
alias << push
|
55
|
+
|
56
|
+
# Clear this session's history. This won't affect the contents of the
|
57
|
+
# history file.
|
58
|
+
def clear
|
59
|
+
@clearer.call
|
60
|
+
@history = []
|
61
|
+
end
|
62
|
+
|
63
|
+
# @return [Fixnum] The number of lines in history.
|
64
|
+
def history_line_count
|
65
|
+
@history.count
|
66
|
+
end
|
67
|
+
|
68
|
+
# @return [Fixnum] The number of lines in history from just this session.
|
69
|
+
def session_line_count
|
70
|
+
@history.count - @original_lines
|
71
|
+
end
|
72
|
+
|
73
|
+
# Return an Array containing all stored history.
|
74
|
+
# @return [Array<String>] An Array containing all lines of history loaded
|
75
|
+
# or entered by the user in the current session.
|
76
|
+
def to_a
|
77
|
+
@history.dup
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
# The default loader. Yields lines from `Pry.history.config.file`.
|
83
|
+
def read_from_file
|
84
|
+
filename = File.expand_path(Pry.config.history.file)
|
85
|
+
|
86
|
+
if File.exists?(filename)
|
87
|
+
File.foreach(filename) { |line| yield(line) }
|
88
|
+
end
|
89
|
+
rescue => error
|
90
|
+
warn "History file not loaded: #{error.message}"
|
91
|
+
end
|
92
|
+
|
93
|
+
# The default pusher. Appends the given line to Readline::HISTORY.
|
94
|
+
# @param [String] line
|
95
|
+
def push_to_readline(line)
|
96
|
+
Readline::HISTORY << line
|
97
|
+
end
|
98
|
+
|
99
|
+
# The default clearer. Clears Readline::HISTORY.
|
100
|
+
def clear_readline
|
101
|
+
Readline::HISTORY.shift until Readline::HISTORY.empty?
|
102
|
+
end
|
103
|
+
|
104
|
+
# The default saver. Appends the given line to `Pry.history.config.file`.
|
105
|
+
def save_to_file(line)
|
106
|
+
history_file.puts line if history_file
|
107
|
+
end
|
108
|
+
|
109
|
+
# The history file, opened for appending.
|
110
|
+
def history_file
|
111
|
+
if defined?(@history_file)
|
112
|
+
@history_file
|
113
|
+
else
|
114
|
+
@history_file = File.open(file_path, 'a', 0600).tap { |f| f.sync = true }
|
115
|
+
end
|
116
|
+
rescue Errno::EACCES
|
117
|
+
warn 'History not saved; unable to open your history file for writing.'
|
118
|
+
@history_file = false
|
119
|
+
end
|
120
|
+
|
121
|
+
def file_path
|
122
|
+
@file_path || Pry.config.history.file
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
class Pry
|
2
|
+
# A history array is an array to which you can only add elements. Older
|
3
|
+
# entries are removed progressively, so that the array never contains more than
|
4
|
+
# N elements.
|
5
|
+
#
|
6
|
+
# History arrays are used by Pry to store the output of the last commands.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# ary = Pry::HistoryArray.new 10
|
10
|
+
# ary << 1 << 2 << 3
|
11
|
+
# ary[0] # => 1
|
12
|
+
# ary[1] # => 2
|
13
|
+
# 10.times { |n| ary << n }
|
14
|
+
# ary[0] # => nil
|
15
|
+
# ary[-1] # => 9
|
16
|
+
class HistoryArray
|
17
|
+
include Enumerable
|
18
|
+
|
19
|
+
# @param [Integer] size Maximum amount of objects in the array
|
20
|
+
def initialize(size)
|
21
|
+
@max_size = size
|
22
|
+
|
23
|
+
@hash = {}
|
24
|
+
@count = 0
|
25
|
+
end
|
26
|
+
|
27
|
+
# Pushes an object at the end of the array
|
28
|
+
# @param [Object] value Object to be added
|
29
|
+
def <<(value)
|
30
|
+
@hash[@count] = value
|
31
|
+
|
32
|
+
if @hash.size > max_size
|
33
|
+
@hash.delete(@count - max_size)
|
34
|
+
end
|
35
|
+
|
36
|
+
@count += 1
|
37
|
+
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
# @overload [](index)
|
42
|
+
# @param [Integer] index Index of the item to access.
|
43
|
+
# @return [Object, nil] Item at that index or nil if it has been removed.
|
44
|
+
# @overload [](index, size)
|
45
|
+
# @param [Integer] index Index of the first item to access.
|
46
|
+
# @param [Integer] size Amount of items to access
|
47
|
+
# @return [Array, nil] The selected items. Nil if index is greater than
|
48
|
+
# the size of the array.
|
49
|
+
# @overload [](range)
|
50
|
+
# @param [Range<Integer>] range Range of indices to access.
|
51
|
+
# @return [Array, nil] The selected items. Nil if index is greater than
|
52
|
+
# the size of the array.
|
53
|
+
def [](index_or_range, size = nil)
|
54
|
+
if index_or_range.is_a? Integer
|
55
|
+
index = convert_index(index_or_range)
|
56
|
+
|
57
|
+
if size
|
58
|
+
end_index = index + size
|
59
|
+
index > @count ? nil : (index...[end_index, @count].min).map do |n|
|
60
|
+
@hash[n]
|
61
|
+
end
|
62
|
+
else
|
63
|
+
@hash[index]
|
64
|
+
end
|
65
|
+
else
|
66
|
+
range = convert_range(index_or_range)
|
67
|
+
range.begin > @count ? nil : range.map { |n| @hash[n] }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# @return [Integer] Amount of objects in the array
|
72
|
+
def size
|
73
|
+
@count
|
74
|
+
end
|
75
|
+
alias count size
|
76
|
+
alias length size
|
77
|
+
|
78
|
+
def empty?
|
79
|
+
size == 0
|
80
|
+
end
|
81
|
+
|
82
|
+
def each
|
83
|
+
((@count - size)...@count).each do |n|
|
84
|
+
yield @hash[n]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def to_a
|
89
|
+
((@count - size)...@count).map { |n| @hash[n] }
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns [Hash] copy of the internal @hash history
|
93
|
+
def to_h
|
94
|
+
@hash.dup
|
95
|
+
end
|
96
|
+
|
97
|
+
def pop!
|
98
|
+
@hash.delete @count - 1
|
99
|
+
@count -= 1
|
100
|
+
end
|
101
|
+
|
102
|
+
def inspect
|
103
|
+
"#<#{self.class} size=#{size} first=#{@count - size} max_size=#{max_size}>"
|
104
|
+
end
|
105
|
+
|
106
|
+
# @return [Integer] Maximum amount of objects in the array
|
107
|
+
attr_reader :max_size
|
108
|
+
|
109
|
+
private
|
110
|
+
def convert_index(n)
|
111
|
+
n >= 0 ? n : @count + n
|
112
|
+
end
|
113
|
+
|
114
|
+
def convert_range(range)
|
115
|
+
end_index = convert_index(range.end)
|
116
|
+
end_index += 1 unless range.exclude_end?
|
117
|
+
|
118
|
+
Range.new(convert_index(range.begin), [end_index, @count].min, true)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|