pry 0.10.0.pre2-universal-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +702 -0
  3. data/LICENSE +25 -0
  4. data/README.md +406 -0
  5. data/bin/pry +16 -0
  6. data/lib/pry.rb +161 -0
  7. data/lib/pry/cli.rb +220 -0
  8. data/lib/pry/code.rb +346 -0
  9. data/lib/pry/code/code_file.rb +103 -0
  10. data/lib/pry/code/code_range.rb +71 -0
  11. data/lib/pry/code/loc.rb +92 -0
  12. data/lib/pry/code_object.rb +172 -0
  13. data/lib/pry/color_printer.rb +55 -0
  14. data/lib/pry/command.rb +692 -0
  15. data/lib/pry/command_set.rb +443 -0
  16. data/lib/pry/commands.rb +6 -0
  17. data/lib/pry/commands/amend_line.rb +99 -0
  18. data/lib/pry/commands/bang.rb +20 -0
  19. data/lib/pry/commands/bang_pry.rb +17 -0
  20. data/lib/pry/commands/cat.rb +62 -0
  21. data/lib/pry/commands/cat/abstract_formatter.rb +27 -0
  22. data/lib/pry/commands/cat/exception_formatter.rb +77 -0
  23. data/lib/pry/commands/cat/file_formatter.rb +67 -0
  24. data/lib/pry/commands/cat/input_expression_formatter.rb +43 -0
  25. data/lib/pry/commands/cd.rb +41 -0
  26. data/lib/pry/commands/change_inspector.rb +27 -0
  27. data/lib/pry/commands/change_prompt.rb +26 -0
  28. data/lib/pry/commands/code_collector.rb +165 -0
  29. data/lib/pry/commands/disable_pry.rb +27 -0
  30. data/lib/pry/commands/disabled_commands.rb +2 -0
  31. data/lib/pry/commands/easter_eggs.rb +112 -0
  32. data/lib/pry/commands/edit.rb +195 -0
  33. data/lib/pry/commands/edit/exception_patcher.rb +25 -0
  34. data/lib/pry/commands/edit/file_and_line_locator.rb +36 -0
  35. data/lib/pry/commands/exit.rb +42 -0
  36. data/lib/pry/commands/exit_all.rb +29 -0
  37. data/lib/pry/commands/exit_program.rb +23 -0
  38. data/lib/pry/commands/find_method.rb +193 -0
  39. data/lib/pry/commands/fix_indent.rb +19 -0
  40. data/lib/pry/commands/gem_cd.rb +26 -0
  41. data/lib/pry/commands/gem_install.rb +32 -0
  42. data/lib/pry/commands/gem_list.rb +33 -0
  43. data/lib/pry/commands/gem_open.rb +29 -0
  44. data/lib/pry/commands/gist.rb +101 -0
  45. data/lib/pry/commands/help.rb +164 -0
  46. data/lib/pry/commands/hist.rb +180 -0
  47. data/lib/pry/commands/import_set.rb +22 -0
  48. data/lib/pry/commands/install_command.rb +53 -0
  49. data/lib/pry/commands/jump_to.rb +29 -0
  50. data/lib/pry/commands/list_inspectors.rb +35 -0
  51. data/lib/pry/commands/list_prompts.rb +35 -0
  52. data/lib/pry/commands/ls.rb +114 -0
  53. data/lib/pry/commands/ls/constants.rb +47 -0
  54. data/lib/pry/commands/ls/formatter.rb +49 -0
  55. data/lib/pry/commands/ls/globals.rb +48 -0
  56. data/lib/pry/commands/ls/grep.rb +21 -0
  57. data/lib/pry/commands/ls/instance_vars.rb +39 -0
  58. data/lib/pry/commands/ls/interrogatable.rb +18 -0
  59. data/lib/pry/commands/ls/jruby_hacks.rb +49 -0
  60. data/lib/pry/commands/ls/local_names.rb +35 -0
  61. data/lib/pry/commands/ls/local_vars.rb +39 -0
  62. data/lib/pry/commands/ls/ls_entity.rb +70 -0
  63. data/lib/pry/commands/ls/methods.rb +57 -0
  64. data/lib/pry/commands/ls/methods_helper.rb +46 -0
  65. data/lib/pry/commands/ls/self_methods.rb +32 -0
  66. data/lib/pry/commands/nesting.rb +25 -0
  67. data/lib/pry/commands/play.rb +103 -0
  68. data/lib/pry/commands/pry_backtrace.rb +25 -0
  69. data/lib/pry/commands/pry_version.rb +17 -0
  70. data/lib/pry/commands/raise_up.rb +32 -0
  71. data/lib/pry/commands/reload_code.rb +62 -0
  72. data/lib/pry/commands/reset.rb +18 -0
  73. data/lib/pry/commands/ri.rb +60 -0
  74. data/lib/pry/commands/save_file.rb +61 -0
  75. data/lib/pry/commands/shell_command.rb +48 -0
  76. data/lib/pry/commands/shell_mode.rb +25 -0
  77. data/lib/pry/commands/show_doc.rb +83 -0
  78. data/lib/pry/commands/show_info.rb +195 -0
  79. data/lib/pry/commands/show_input.rb +17 -0
  80. data/lib/pry/commands/show_source.rb +50 -0
  81. data/lib/pry/commands/simple_prompt.rb +22 -0
  82. data/lib/pry/commands/stat.rb +40 -0
  83. data/lib/pry/commands/switch_to.rb +23 -0
  84. data/lib/pry/commands/toggle_color.rb +24 -0
  85. data/lib/pry/commands/watch_expression.rb +105 -0
  86. data/lib/pry/commands/watch_expression/expression.rb +38 -0
  87. data/lib/pry/commands/whereami.rb +190 -0
  88. data/lib/pry/commands/wtf.rb +57 -0
  89. data/lib/pry/config.rb +24 -0
  90. data/lib/pry/config/behavior.rb +139 -0
  91. data/lib/pry/config/convenience.rb +26 -0
  92. data/lib/pry/config/default.rb +165 -0
  93. data/lib/pry/core_extensions.rb +131 -0
  94. data/lib/pry/editor.rb +133 -0
  95. data/lib/pry/exceptions.rb +77 -0
  96. data/lib/pry/helpers.rb +5 -0
  97. data/lib/pry/helpers/base_helpers.rb +113 -0
  98. data/lib/pry/helpers/command_helpers.rb +156 -0
  99. data/lib/pry/helpers/documentation_helpers.rb +75 -0
  100. data/lib/pry/helpers/options_helpers.rb +27 -0
  101. data/lib/pry/helpers/table.rb +109 -0
  102. data/lib/pry/helpers/text.rb +107 -0
  103. data/lib/pry/history.rb +125 -0
  104. data/lib/pry/history_array.rb +121 -0
  105. data/lib/pry/hooks.rb +230 -0
  106. data/lib/pry/indent.rb +406 -0
  107. data/lib/pry/input_completer.rb +242 -0
  108. data/lib/pry/input_lock.rb +132 -0
  109. data/lib/pry/inspector.rb +27 -0
  110. data/lib/pry/last_exception.rb +61 -0
  111. data/lib/pry/method.rb +546 -0
  112. data/lib/pry/method/disowned.rb +53 -0
  113. data/lib/pry/method/patcher.rb +125 -0
  114. data/lib/pry/method/weird_method_locator.rb +186 -0
  115. data/lib/pry/module_candidate.rb +136 -0
  116. data/lib/pry/object_path.rb +82 -0
  117. data/lib/pry/output.rb +50 -0
  118. data/lib/pry/pager.rb +234 -0
  119. data/lib/pry/plugins.rb +103 -0
  120. data/lib/pry/prompt.rb +26 -0
  121. data/lib/pry/pry_class.rb +375 -0
  122. data/lib/pry/pry_instance.rb +654 -0
  123. data/lib/pry/rbx_path.rb +22 -0
  124. data/lib/pry/repl.rb +202 -0
  125. data/lib/pry/repl_file_loader.rb +74 -0
  126. data/lib/pry/rubygem.rb +82 -0
  127. data/lib/pry/terminal.rb +79 -0
  128. data/lib/pry/test/helper.rb +170 -0
  129. data/lib/pry/version.rb +3 -0
  130. data/lib/pry/wrapped_module.rb +373 -0
  131. metadata +248 -0
data/lib/pry/editor.rb ADDED
@@ -0,0 +1,133 @@
1
+ class Pry
2
+ class Editor
3
+ include Pry::Helpers::BaseHelpers
4
+ include Pry::Helpers::CommandHelpers
5
+
6
+ attr_reader :_pry_
7
+
8
+ def initialize(_pry_)
9
+ @_pry_ = _pry_
10
+ end
11
+
12
+ def edit_tempfile_with_content(initial_content, line=1)
13
+ temp_file do |f|
14
+ f.puts(initial_content)
15
+ f.flush
16
+ f.close(false)
17
+ invoke_editor(f.path, line, true)
18
+ File.read(f.path)
19
+ end
20
+ end
21
+
22
+ def invoke_editor(file, line, blocking=true)
23
+ raise CommandError, "Please set Pry.config.editor or export $VISUAL or $EDITOR" unless _pry_.config.editor
24
+
25
+ editor_invocation = build_editor_invocation_string(file, line, blocking)
26
+ return nil unless editor_invocation
27
+
28
+ if jruby?
29
+ open_editor_on_jruby(editor_invocation)
30
+ else
31
+ open_editor(editor_invocation)
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ # Generate the string that's used to start the editor. This includes
38
+ # all the flags we want as well as the file and line number we
39
+ # want to open at.
40
+ def build_editor_invocation_string(file, line, blocking)
41
+
42
+ if _pry_.config.editor.respond_to?(:call)
43
+ args = [file, line, blocking][0...(_pry_.config.editor.arity)]
44
+ _pry_.config.editor.call(*args)
45
+ else
46
+ sanitized_file = if windows?
47
+ file.gsub(/\//, '\\')
48
+ else
49
+ Shellwords.escape(file)
50
+ end
51
+
52
+ "#{_pry_.config.editor} #{blocking_flag_for_editor(blocking)} #{start_line_syntax_for_editor(sanitized_file, line)}"
53
+ end
54
+ end
55
+
56
+ # Start the editor running, using the calculated invocation string
57
+ def open_editor(editor_invocation)
58
+ # Note we dont want to use Pry.config.system here as that
59
+ # may be invoked non-interactively (i.e via Open4), whereas we want to
60
+ # ensure the editor is always interactive
61
+ system(*Shellwords.split(editor_invocation)) or raise CommandError, "`#{editor_invocation}` gave exit status: #{$?.exitstatus}"
62
+ end
63
+
64
+ # We need JRuby specific code here cos just shelling out using
65
+ # system() appears to be pretty broken :/
66
+ def open_editor_on_jruby(editor_invocation)
67
+ begin
68
+ require 'spoon'
69
+ pid = Spoon.spawnp(*Shellwords.split(editor_invocation))
70
+ Process.waitpid(pid)
71
+ rescue FFI::NotFoundError
72
+ system(editor_invocation)
73
+ end
74
+ end
75
+
76
+ # Some editors that run outside the terminal allow you to control whether or
77
+ # not to block the process from which they were launched (in this case, Pry).
78
+ # For those editors, return the flag that produces the desired behavior.
79
+ def blocking_flag_for_editor(blocking)
80
+ case editor_name
81
+ when /^emacsclient/
82
+ '--no-wait' unless blocking
83
+ when /^[gm]vim/
84
+ '--nofork' if blocking
85
+ when /^jedit/
86
+ '-wait' if blocking
87
+ when /^mate/, /^subl/
88
+ '-w' if blocking
89
+ end
90
+ end
91
+
92
+ # Return the syntax for a given editor for starting the editor
93
+ # and moving to a particular line within that file
94
+ def start_line_syntax_for_editor(file_name, line_number)
95
+ # special case for 1st line
96
+ return file_name if line_number <= 1
97
+
98
+ case editor_name
99
+ when /^[gm]?vi/, /^emacs/, /^nano/, /^pico/, /^gedit/, /^kate/
100
+ "+#{line_number} #{file_name}"
101
+ when /^mate/, /^geany/
102
+ "-l #{line_number} #{file_name}"
103
+ when /^subl/
104
+ "#{file_name}:#{line_number}"
105
+ when /^uedit32/
106
+ "#{file_name}/#{line_number}"
107
+ when /^jedit/
108
+ "#{file_name} +line:#{line_number}"
109
+ else
110
+ if windows?
111
+ "#{file_name}"
112
+ else
113
+ "+#{line_number} #{file_name}"
114
+ end
115
+ end
116
+ end
117
+
118
+ # Get the name of the binary that Pry.config.editor points to.
119
+ #
120
+ # This is useful for deciding which flags we pass to the editor as
121
+ # we can just use the program's name and ignore any absolute paths.
122
+ #
123
+ # @example
124
+ # Pry.config.editor="/home/conrad/bin/textmate -w"
125
+ # editor_name
126
+ # # => textmate
127
+ #
128
+ def editor_name
129
+ File.basename(_pry_.config.editor).split(" ").first
130
+ end
131
+
132
+ end
133
+ end
@@ -0,0 +1,77 @@
1
+ class Pry
2
+
3
+ # As a REPL, we often want to catch any unexpected exceptions that may have
4
+ # been raised; however we don't want to go overboard and prevent the user
5
+ # from exiting Pry when they want to.
6
+ module RescuableException
7
+ def self.===(exception)
8
+ case exception
9
+ # Catch when the user hits ^C (Interrupt < SignalException), and assume
10
+ # that they just wanted to stop the in-progress command (just like bash
11
+ # etc.)
12
+ when Interrupt
13
+ true
14
+ # Don't catch signals (particularly not SIGTERM) as these are unlikely
15
+ # to be intended for pry itself. We should also make sure that
16
+ # Kernel#exit works.
17
+ when *Pry.config.exception_whitelist
18
+ false
19
+ # All other exceptions will be caught.
20
+ else
21
+ true
22
+ end
23
+ end
24
+ end
25
+
26
+ # Catches SecurityErrors if $SAFE is set
27
+ module Pry::TooSafeException
28
+ def self.===(exception)
29
+ $SAFE > 0 && SecurityError === exception
30
+ end
31
+ end
32
+
33
+ # An Exception Tag (cf. Exceptional Ruby) that instructs Pry to show the error
34
+ # in a more user-friendly manner. This should be used when the exception
35
+ # happens within Pry itself as a direct consequence of the user typing
36
+ # something wrong.
37
+ #
38
+ # This allows us to distinguish between the user typing:
39
+ #
40
+ # pry(main)> def )
41
+ # SyntaxError: unexpected )
42
+ #
43
+ # pry(main)> method_that_evals("def )")
44
+ # SyntaxError: (eval):1: syntax error, unexpected ')'
45
+ # from ./a.rb:2 in `eval'
46
+ module UserError; end
47
+
48
+ # When we try to get a binding for an object, we try to define a method on
49
+ # that Object's singleton class. This doesn't work for "frozen" Object's, and
50
+ # the exception is just a vanilla RuntimeError.
51
+ module FrozenObjectException
52
+ def self.===(exception)
53
+ ["can't modify frozen class/module",
54
+ "can't modify frozen Class",
55
+ ].include?(exception.message)
56
+ end
57
+ end
58
+
59
+ # Don't catch these exceptions
60
+ DEFAULT_EXCEPTION_WHITELIST = [SystemExit,
61
+ SignalException,
62
+ Pry::TooSafeException]
63
+
64
+ # CommandErrors are caught by the REPL loop and displayed to the user. They
65
+ # indicate an exceptional condition that's fatal to the current command.
66
+ class CommandError < StandardError; end
67
+ class MethodNotFound < CommandError; end
68
+
69
+ # indicates obsolete API
70
+ class ObsoleteError < StandardError; end
71
+
72
+ # This is to keep from breaking under Rails 3.2 for people who are doing that
73
+ # IRB = Pry thing.
74
+ module ExtendCommandBundle
75
+ end
76
+
77
+ end
@@ -0,0 +1,5 @@
1
+ require "pry/helpers/base_helpers"
2
+ require "pry/helpers/options_helpers"
3
+ require "pry/helpers/command_helpers"
4
+ require "pry/helpers/text"
5
+ require "pry/helpers/table"
@@ -0,0 +1,113 @@
1
+ class Pry
2
+ module Helpers
3
+
4
+ module BaseHelpers
5
+
6
+ module_function
7
+
8
+ def silence_warnings
9
+ old_verbose = $VERBOSE
10
+ $VERBOSE = nil
11
+ begin
12
+ yield
13
+ ensure
14
+ $VERBOSE = old_verbose
15
+ end
16
+ end
17
+
18
+ # Acts like send but ignores any methods defined below Object or Class in the
19
+ # inheritance hierarchy.
20
+ # This is required to introspect methods on objects like Net::HTTP::Get that
21
+ # have overridden the `method` method.
22
+ def safe_send(obj, method, *args, &block)
23
+ (Module === obj ? Module : Object).instance_method(method).bind(obj).call(*args, &block)
24
+ end
25
+ public :safe_send
26
+
27
+ def find_command(name, set = Pry::Commands)
28
+ command_match = set.find do |_, command|
29
+ (listing = command.options[:listing]) == name && listing != nil
30
+ end
31
+ command_match.last if command_match
32
+ end
33
+
34
+ def not_a_real_file?(file)
35
+ file =~ /(\(.*\))|<.*>/ || file =~ /__unknown__/ || file == "" || file == "-e"
36
+ end
37
+
38
+ def command_dependencies_met?(options)
39
+ return true if !options[:requires_gem]
40
+ Array(options[:requires_gem]).all? do |g|
41
+ Rubygem.installed?(g)
42
+ end
43
+ end
44
+
45
+ def use_ansi_codes?
46
+ windows_ansi? || ENV['TERM'] && ENV['TERM'] != "dumb"
47
+ end
48
+
49
+ def colorize_code(code)
50
+ CodeRay.scan(code, :ruby).term
51
+ end
52
+
53
+ def highlight(string, regexp, highlight_color=:bright_yellow)
54
+ string.gsub(regexp) { |match| "<#{highlight_color}>#{match}</#{highlight_color}>" }
55
+ end
56
+
57
+ # formatting
58
+ def heading(text)
59
+ text = "#{text}\n--"
60
+ "\e[1m#{text}\e[0m"
61
+ end
62
+
63
+ # have fun on the Windows platform.
64
+ def windows?
65
+ RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
66
+ end
67
+
68
+ # are we able to use ansi on windows?
69
+ def windows_ansi?
70
+ defined?(Win32::Console) || ENV['ANSICON'] || (windows? && mri_2?)
71
+ end
72
+
73
+ def jruby?
74
+ RbConfig::CONFIG['ruby_install_name'] == 'jruby'
75
+ end
76
+
77
+ def jruby_19?
78
+ jruby? && RbConfig::CONFIG['ruby_version'] == '1.9'
79
+ end
80
+
81
+ def rbx?
82
+ RbConfig::CONFIG['ruby_install_name'] == 'rbx'
83
+ end
84
+
85
+ def mri?
86
+ RbConfig::CONFIG['ruby_install_name'] == 'ruby'
87
+ end
88
+
89
+ def mri_19?
90
+ mri? && RUBY_VERSION =~ /^1\.9/
91
+ end
92
+
93
+ def mri_2?
94
+ mri? && RUBY_VERSION =~ /^2/
95
+ end
96
+
97
+ def mri_20?
98
+ mri? && RUBY_VERSION =~ /^2\.0/
99
+ end
100
+
101
+ def mri_21?
102
+ mri? && RUBY_VERSION =~ /^2\.1/
103
+ end
104
+
105
+ # Send the given text through the best available pager (if Pry.config.pager is
106
+ # enabled). Infers where to send the output if used as a mixin.
107
+ # DEPRECATED.
108
+ def stagger_output(text, out = nil)
109
+ Pry.new.pager.page text
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,156 @@
1
+ class Pry
2
+ module Helpers
3
+
4
+ module CommandHelpers
5
+ include OptionsHelpers
6
+
7
+ module_function
8
+
9
+ # Open a temp file and yield it to the block, closing it after
10
+ # @return [String] The path of the temp file
11
+ def temp_file(ext='.rb')
12
+ file = Tempfile.new(['pry', ext])
13
+ yield file
14
+ ensure
15
+ file.close(true) if file
16
+ end
17
+
18
+ def internal_binding?(target)
19
+ m = target.eval("::Kernel.__method__").to_s
20
+ # class_eval is here because of http://jira.codehaus.org/browse/JRUBY-6753
21
+ ["__binding__", "__pry__", "class_eval"].include?(m)
22
+ end
23
+
24
+ def get_method_or_raise(name, target, opts={}, omit_help=false)
25
+ meth = Pry::Method.from_str(name, target, opts)
26
+
27
+ if name && !meth
28
+ command_error("The method '#{name}' could not be found.", omit_help, MethodNotFound)
29
+ end
30
+
31
+ (opts[:super] || 0).times do
32
+ if meth.super
33
+ meth = meth.super
34
+ else
35
+ command_error("'#{meth.name_with_owner}' has no super method.", omit_help, MethodNotFound)
36
+ end
37
+ end
38
+
39
+ if !meth || (!name && internal_binding?(target))
40
+ command_error("No method name given, and context is not a method.", omit_help, MethodNotFound)
41
+ end
42
+
43
+ set_file_and_dir_locals(meth.source_file)
44
+ meth
45
+ end
46
+
47
+ def command_error(message, omit_help, klass=CommandError)
48
+ message += " Type `#{command_name} --help` for help." unless omit_help
49
+ raise klass, message
50
+ end
51
+
52
+ # Remove any common leading whitespace from every line in `text`.
53
+ #
54
+ # This can be used to make a HEREDOC line up with the left margin, without
55
+ # sacrificing the indentation level of the source code.
56
+ #
57
+ # e.g.
58
+ # opt.banner unindent <<-USAGE
59
+ # Lorem ipsum dolor sit amet, consectetur adipisicing elit,
60
+ # sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
61
+ # "Ut enim ad minim veniam."
62
+ # USAGE
63
+ #
64
+ # Heavily based on textwrap.dedent from Python, which is:
65
+ # Copyright (C) 1999-2001 Gregory P. Ward.
66
+ # Copyright (C) 2002, 2003 Python Software Foundation.
67
+ # Written by Greg Ward <gward@python.net>
68
+ #
69
+ # Licensed under <http://docs.python.org/license.html>
70
+ # From <http://hg.python.org/cpython/file/6b9f0a6efaeb/Lib/textwrap.py>
71
+ #
72
+ # @param [String] text The text from which to remove indentation
73
+ # @return [String] The text with indentation stripped.
74
+ def unindent(text, left_padding = 0)
75
+ # Empty blank lines
76
+ text = text.sub(/^[ \t]+$/, '')
77
+
78
+ # Find the longest common whitespace to all indented lines
79
+ # Ignore lines containing just -- or ++ as these seem to be used by
80
+ # comment authors as delimeters.
81
+ margin = text.scan(/^[ \t]*(?!--\n|\+\+\n)(?=[^ \t\n])/).inject do |current_margin, next_indent|
82
+ if next_indent.start_with?(current_margin)
83
+ current_margin
84
+ elsif current_margin.start_with?(next_indent)
85
+ next_indent
86
+ else
87
+ ""
88
+ end
89
+ end
90
+
91
+ text.gsub(/^#{margin}/, ' ' * left_padding)
92
+ end
93
+
94
+ # Restrict a string to the given range of lines (1-indexed)
95
+ # @param [String] content The string.
96
+ # @param [Range, Fixnum] lines The line(s) to restrict it to.
97
+ # @return [String] The resulting string.
98
+ def restrict_to_lines(content, lines)
99
+ line_range = one_index_range_or_number(lines)
100
+ Array(content.lines.to_a[line_range]).join
101
+ end
102
+
103
+ def one_index_number(line_number)
104
+ if line_number > 0
105
+ line_number - 1
106
+ else
107
+ line_number
108
+ end
109
+ end
110
+
111
+ # convert a 1-index range to a 0-indexed one
112
+ def one_index_range(range)
113
+ Range.new(one_index_number(range.begin), one_index_number(range.end))
114
+ end
115
+
116
+ def one_index_range_or_number(range_or_number)
117
+ case range_or_number
118
+ when Range
119
+ one_index_range(range_or_number)
120
+ else
121
+ one_index_number(range_or_number)
122
+ end
123
+ end
124
+
125
+ def absolute_index_number(line_number, array_length)
126
+ if line_number >= 0
127
+ line_number
128
+ else
129
+ [array_length + line_number, 0].max
130
+ end
131
+ end
132
+
133
+ def absolute_index_range(range_or_number, array_length)
134
+ case range_or_number
135
+ when Range
136
+ a = absolute_index_number(range_or_number.begin, array_length)
137
+ b = absolute_index_number(range_or_number.end, array_length)
138
+ else
139
+ a = b = absolute_index_number(range_or_number, array_length)
140
+ end
141
+
142
+ Range.new(a, b)
143
+ end
144
+
145
+ def set_file_and_dir_locals(file_name, _pry_=_pry_(), target=target())
146
+ return if !target or !file_name
147
+ _pry_.last_file = File.expand_path(file_name)
148
+ _pry_.inject_local("_file_", _pry_.last_file, target)
149
+
150
+ _pry_.last_dir = File.dirname(_pry_.last_file)
151
+ _pry_.inject_local("_dir_", _pry_.last_dir, target)
152
+ end
153
+ end
154
+
155
+ end
156
+ end