pry 0.9.10 → 0.9.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (194) hide show
  1. data/.travis.yml +3 -1
  2. data/CHANGELOG +60 -1
  3. data/CONTRIBUTORS +43 -25
  4. data/Gemfile +7 -0
  5. data/Guardfile +62 -0
  6. data/README.markdown +4 -4
  7. data/Rakefile +34 -35
  8. data/lib/pry.rb +107 -54
  9. data/lib/pry/cli.rb +34 -11
  10. data/lib/pry/code.rb +165 -182
  11. data/lib/pry/code/code_range.rb +70 -0
  12. data/lib/pry/code/loc.rb +92 -0
  13. data/lib/pry/code_object.rb +153 -0
  14. data/lib/pry/command.rb +160 -22
  15. data/lib/pry/command_set.rb +37 -26
  16. data/lib/pry/commands.rb +4 -27
  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 +53 -0
  21. data/lib/pry/commands/cat/abstract_formatter.rb +27 -0
  22. data/lib/pry/commands/cat/exception_formatter.rb +78 -0
  23. data/lib/pry/commands/cat/file_formatter.rb +84 -0
  24. data/lib/pry/commands/cat/input_expression_formatter.rb +43 -0
  25. data/lib/pry/commands/cd.rb +30 -0
  26. data/lib/pry/commands/code_collector.rb +165 -0
  27. data/lib/pry/commands/deprecated_commands.rb +2 -0
  28. data/lib/pry/commands/disable_pry.rb +27 -0
  29. data/lib/pry/commands/easter_eggs.rb +112 -0
  30. data/lib/pry/commands/edit.rb +206 -0
  31. data/lib/pry/commands/edit/exception_patcher.rb +25 -0
  32. data/lib/pry/commands/edit/file_and_line_locator.rb +38 -0
  33. data/lib/pry/commands/edit/method_patcher.rb +122 -0
  34. data/lib/pry/commands/exit.rb +42 -0
  35. data/lib/pry/commands/exit_all.rb +29 -0
  36. data/lib/pry/commands/exit_program.rb +24 -0
  37. data/lib/pry/commands/find_method.rb +199 -0
  38. data/lib/pry/commands/fix_indent.rb +19 -0
  39. data/lib/pry/commands/gem_cd.rb +26 -0
  40. data/lib/pry/commands/gem_install.rb +29 -0
  41. data/lib/pry/commands/gem_list.rb +33 -0
  42. data/lib/pry/commands/gem_open.rb +29 -0
  43. data/lib/pry/commands/gist.rb +95 -0
  44. data/lib/pry/commands/help.rb +164 -0
  45. data/lib/pry/commands/hist.rb +161 -0
  46. data/lib/pry/commands/import_set.rb +22 -0
  47. data/lib/pry/commands/install_command.rb +51 -0
  48. data/lib/pry/commands/jump_to.rb +29 -0
  49. data/lib/pry/commands/ls.rb +339 -0
  50. data/lib/pry/commands/nesting.rb +25 -0
  51. data/lib/pry/commands/play.rb +69 -0
  52. data/lib/pry/commands/pry_backtrace.rb +26 -0
  53. data/lib/pry/commands/pry_version.rb +17 -0
  54. data/lib/pry/commands/raise_up.rb +32 -0
  55. data/lib/pry/commands/reload_code.rb +39 -0
  56. data/lib/pry/commands/reset.rb +18 -0
  57. data/lib/pry/commands/ri.rb +56 -0
  58. data/lib/pry/commands/save_file.rb +61 -0
  59. data/lib/pry/commands/shell_command.rb +43 -0
  60. data/lib/pry/commands/shell_mode.rb +27 -0
  61. data/lib/pry/commands/show_doc.rb +78 -0
  62. data/lib/pry/commands/show_info.rb +139 -0
  63. data/lib/pry/commands/show_input.rb +17 -0
  64. data/lib/pry/commands/show_source.rb +37 -0
  65. data/lib/pry/commands/simple_prompt.rb +22 -0
  66. data/lib/pry/commands/stat.rb +40 -0
  67. data/lib/pry/commands/switch_to.rb +23 -0
  68. data/lib/pry/commands/toggle_color.rb +20 -0
  69. data/lib/pry/commands/whereami.rb +114 -0
  70. data/lib/pry/commands/wtf.rb +57 -0
  71. data/lib/pry/completion.rb +120 -46
  72. data/lib/pry/config.rb +11 -0
  73. data/lib/pry/core_extensions.rb +27 -16
  74. data/lib/pry/editor.rb +129 -0
  75. data/lib/pry/helpers.rb +1 -0
  76. data/lib/pry/helpers/base_helpers.rb +89 -119
  77. data/lib/pry/helpers/command_helpers.rb +6 -121
  78. data/lib/pry/helpers/table.rb +100 -0
  79. data/lib/pry/helpers/text.rb +4 -4
  80. data/lib/pry/history_array.rb +5 -0
  81. data/lib/pry/hooks.rb +1 -3
  82. data/lib/pry/indent.rb +104 -30
  83. data/lib/pry/method.rb +66 -22
  84. data/lib/pry/module_candidate.rb +26 -15
  85. data/lib/pry/pager.rb +70 -0
  86. data/lib/pry/plugins.rb +1 -2
  87. data/lib/pry/pry_class.rb +63 -22
  88. data/lib/pry/pry_instance.rb +58 -37
  89. data/lib/pry/rubygem.rb +74 -0
  90. data/lib/pry/terminal_info.rb +43 -0
  91. data/lib/pry/test/helper.rb +185 -0
  92. data/lib/pry/version.rb +1 -1
  93. data/lib/pry/wrapped_module.rb +58 -24
  94. data/pry.gemspec +21 -37
  95. data/{test/test_cli.rb → spec/cli_spec.rb} +0 -0
  96. data/spec/code_object_spec.rb +277 -0
  97. data/{test/test_code.rb → spec/code_spec.rb} +19 -1
  98. data/{test/test_command_helpers.rb → spec/command_helpers_spec.rb} +0 -0
  99. data/{test/test_command_integration.rb → spec/command_integration_spec.rb} +38 -46
  100. data/{test/test_command_set.rb → spec/command_set_spec.rb} +18 -1
  101. data/{test/test_command.rb → spec/command_spec.rb} +250 -149
  102. data/spec/commands/amend_line_spec.rb +247 -0
  103. data/spec/commands/bang_spec.rb +19 -0
  104. data/spec/commands/cat_spec.rb +164 -0
  105. data/spec/commands/cd_spec.rb +250 -0
  106. data/spec/commands/disable_pry_spec.rb +25 -0
  107. data/spec/commands/edit_spec.rb +727 -0
  108. data/spec/commands/exit_all_spec.rb +34 -0
  109. data/spec/commands/exit_program_spec.rb +19 -0
  110. data/spec/commands/exit_spec.rb +34 -0
  111. data/{test/test_default_commands/test_find_method.rb → spec/commands/find_method_spec.rb} +27 -7
  112. data/spec/commands/gem_list_spec.rb +26 -0
  113. data/spec/commands/gist_spec.rb +75 -0
  114. data/{test/test_default_commands/test_help.rb → spec/commands/help_spec.rb} +8 -9
  115. data/spec/commands/hist_spec.rb +181 -0
  116. data/spec/commands/jump_to_spec.rb +15 -0
  117. data/spec/commands/ls_spec.rb +177 -0
  118. data/spec/commands/play_spec.rb +140 -0
  119. data/spec/commands/raise_up_spec.rb +56 -0
  120. data/spec/commands/save_file_spec.rb +177 -0
  121. data/spec/commands/show_doc_spec.rb +378 -0
  122. data/spec/commands/show_input_spec.rb +17 -0
  123. data/spec/commands/show_source_spec.rb +597 -0
  124. data/spec/commands/whereami_spec.rb +154 -0
  125. data/spec/completion_spec.rb +233 -0
  126. data/spec/control_d_handler_spec.rb +58 -0
  127. data/spec/editor_spec.rb +79 -0
  128. data/{test/test_exception_whitelist.rb → spec/exception_whitelist_spec.rb} +0 -0
  129. data/{test → spec/fixtures}/candidate_helper1.rb +0 -0
  130. data/{test → spec/fixtures}/candidate_helper2.rb +0 -0
  131. data/{test/test_default_commands → spec/fixtures}/example.erb +0 -0
  132. data/spec/fixtures/example_nesting.rb +33 -0
  133. data/spec/fixtures/show_source_doc_examples.rb +15 -0
  134. data/{test → spec/fixtures}/testrc +0 -0
  135. data/{test → spec/fixtures}/testrcbad +0 -0
  136. data/spec/helper.rb +34 -0
  137. data/spec/helpers/bacon.rb +86 -0
  138. data/spec/helpers/mock_pry.rb +43 -0
  139. data/spec/helpers/table_spec.rb +83 -0
  140. data/{test/test_history_array.rb → spec/history_array_spec.rb} +21 -19
  141. data/{test/test_hooks.rb → spec/hooks_spec.rb} +0 -0
  142. data/{test/test_indent.rb → spec/indent_spec.rb} +24 -0
  143. data/{test/test_input_stack.rb → spec/input_stack_spec.rb} +4 -0
  144. data/{test/test_method.rb → spec/method_spec.rb} +65 -1
  145. data/{test/test_prompt.rb → spec/prompt_spec.rb} +0 -0
  146. data/{test/test_pry_defaults.rb → spec/pry_defaults_spec.rb} +14 -14
  147. data/{test/test_pry_history.rb → spec/pry_history_spec.rb} +15 -0
  148. data/spec/pry_output_spec.rb +95 -0
  149. data/{test/test_pry.rb → spec/pry_spec.rb} +74 -32
  150. data/{test/test_sticky_locals.rb → spec/sticky_locals_spec.rb} +27 -25
  151. data/{test/test_syntax_checking.rb → spec/syntax_checking_spec.rb} +17 -1
  152. data/{test/test_wrapped_module.rb → spec/wrapped_module_spec.rb} +92 -5
  153. metadata +236 -112
  154. data/examples/example_basic.rb +0 -15
  155. data/examples/example_command_override.rb +0 -32
  156. data/examples/example_commands.rb +0 -36
  157. data/examples/example_hooks.rb +0 -9
  158. data/examples/example_image_edit.rb +0 -67
  159. data/examples/example_input.rb +0 -7
  160. data/examples/example_input2.rb +0 -29
  161. data/examples/example_output.rb +0 -11
  162. data/examples/example_print.rb +0 -6
  163. data/examples/example_prompt.rb +0 -9
  164. data/examples/helper.rb +0 -6
  165. data/lib/pry/default_commands/cd.rb +0 -81
  166. data/lib/pry/default_commands/commands.rb +0 -62
  167. data/lib/pry/default_commands/context.rb +0 -98
  168. data/lib/pry/default_commands/easter_eggs.rb +0 -95
  169. data/lib/pry/default_commands/editing.rb +0 -420
  170. data/lib/pry/default_commands/find_method.rb +0 -169
  171. data/lib/pry/default_commands/gems.rb +0 -84
  172. data/lib/pry/default_commands/gist.rb +0 -187
  173. data/lib/pry/default_commands/help.rb +0 -127
  174. data/lib/pry/default_commands/hist.rb +0 -120
  175. data/lib/pry/default_commands/input_and_output.rb +0 -306
  176. data/lib/pry/default_commands/introspection.rb +0 -410
  177. data/lib/pry/default_commands/ls.rb +0 -272
  178. data/lib/pry/default_commands/misc.rb +0 -38
  179. data/lib/pry/default_commands/navigating_pry.rb +0 -110
  180. data/lib/pry/default_commands/whereami.rb +0 -92
  181. data/lib/pry/extended_commands/experimental.rb +0 -7
  182. data/test/helper.rb +0 -223
  183. data/test/test_completion.rb +0 -62
  184. data/test/test_control_d_handler.rb +0 -45
  185. data/test/test_default_commands/test_cd.rb +0 -321
  186. data/test/test_default_commands/test_context.rb +0 -288
  187. data/test/test_default_commands/test_documentation.rb +0 -315
  188. data/test/test_default_commands/test_gems.rb +0 -18
  189. data/test/test_default_commands/test_input.rb +0 -428
  190. data/test/test_default_commands/test_introspection.rb +0 -511
  191. data/test/test_default_commands/test_ls.rb +0 -151
  192. data/test/test_default_commands/test_shell.rb +0 -343
  193. data/test/test_default_commands/test_show_source.rb +0 -432
  194. data/test/test_pry_output.rb +0 -41
@@ -57,12 +57,18 @@ class Pry
57
57
  end
58
58
 
59
59
  def parse_options(args=ARGV.dup)
60
- raise NoOptionsError, "No command line options defined! Use Pry::CLI.add_options to add command line options." if !options
60
+ unless options
61
+ raise NoOptionsError, "No command line options defined! Use Pry::CLI.add_options to add command line options."
62
+ end
61
63
 
62
64
  self.input_args = args
63
65
 
64
66
  opts = Slop.parse!(args, :help => true, :multiple_switches => false, &options)
65
- option_processors.each { |processor| processor.call(opts) } if option_processors # option processors are optional
67
+
68
+ # Option processors are optional.
69
+ if option_processors
70
+ option_processors.each { |processor| processor.call(opts) }
71
+ end
66
72
 
67
73
  self
68
74
  end
@@ -73,8 +79,20 @@ class Pry
73
79
  end
74
80
  end
75
81
 
82
+
83
+ # String that is built to be executed on start (created by -e and -exec switches)
84
+ exec_string = ""
85
+
76
86
  # Bring in options defined by plugins
77
- Pry::CLI.add_plugin_options
87
+ Slop.new do
88
+ on "no-plugins" do
89
+ Pry.config.should_load_plugins = false
90
+ end
91
+ end.parse(ARGV.dup)
92
+
93
+ if Pry.config.should_load_plugins
94
+ Pry::CLI.add_plugin_options
95
+ end
78
96
 
79
97
  # The default Pry command line options (before plugin options are included)
80
98
  Pry::CLI.add_options do
@@ -84,7 +102,9 @@ See: `https://github.com/pry` for more information.
84
102
  Copyright (c) 2011 John Mair (banisterfiend)
85
103
  --
86
104
  }
87
- on :e, :exec, "A line of code to execute in context before the session starts", :argument => true
105
+ on :e, :exec, "A line of code to execute in context before the session starts", :argument => true do |input|
106
+ exec_string << input + "\n"
107
+ end
88
108
 
89
109
  on "no-pager", "Disable pager for long output" do
90
110
  Pry.config.pager = false
@@ -133,8 +153,12 @@ Copyright (c) 2011 John Mair (banisterfiend)
133
153
  Pry.config.requires << file
134
154
  end
135
155
 
136
- on :I, "Add a path to the $LOAD_PATH", :argument => true do |path|
137
- $LOAD_PATH << path
156
+ on :I, "Add a path to the $LOAD_PATH", :argument => true, :as => Array, :delimiter => ":" do |load_path|
157
+ load_path.map! do |path|
158
+ /\A\.\// =~ path ? path : File.expand_path(path)
159
+ end
160
+
161
+ $LOAD_PATH.unshift(*load_path)
138
162
  end
139
163
 
140
164
  on :v, :version, "Display the Pry version" do
@@ -161,13 +185,12 @@ end.process_options do |opts|
161
185
  full_name = File.expand_path(Pry::CLI.input_args.first)
162
186
  Pry.load_file_through_repl(full_name)
163
187
  exit
164
- elsif opts[:exec]
165
- exec_string = opts[:exec] + "\n"
166
- else
167
- exec_string = ""
188
+ end
189
+
190
+ if Pry.config.should_load_plugins
191
+ parser = Slop.new
168
192
  end
169
193
 
170
194
  # Start the session (running any code passed with -e, if there is any)
171
195
  Pry.start(context, :input => StringIO.new(exec_string))
172
196
  end
173
-
@@ -1,3 +1,6 @@
1
+ require 'pry/code/loc'
2
+ require 'pry/code/code_range'
3
+
1
4
  class Pry
2
5
  class << self
3
6
  # Convert the given object into an instance of `Pry::Code`, if it isn't
@@ -26,29 +29,42 @@ class Pry
26
29
  # arbitrary chaining of formatting methods without mutating the original
27
30
  # object.
28
31
  class Code
32
+
33
+ # List of all supported languages.
34
+ # @return [Hash]
35
+ EXTENSIONS = {
36
+ %w(.py) => :python,
37
+ %w(.js) => :javascript,
38
+ %w(.css) => :css,
39
+ %w(.xml) => :xml,
40
+ %w(.php) => :php,
41
+ %w(.html) => :html,
42
+ %w(.diff) => :diff,
43
+ %w(.java) => :java,
44
+ %w(.json) => :json,
45
+ %w(.c .h) => :c,
46
+ %w(.rhtml) => :rhtml,
47
+ %w(.yaml .yml) => :yaml,
48
+ %w(.cpp .hpp .cc .h cxx) => :cpp,
49
+ %w(.rb .ru .irbrc .gemspec .pryrc) => :ruby,
50
+ }
51
+
29
52
  class << self
30
53
  include MethodSource::CodeHelpers
31
54
 
32
55
  # Instantiate a `Code` object containing code loaded from a file or
33
56
  # Pry's line buffer.
34
57
  #
35
- # @param [String] fn The name of a file, or "(pry)".
58
+ # @param [String] filename The name of a file, or "(pry)".
36
59
  # @param [Symbol] code_type The type of code the file contains.
37
60
  # @return [Code]
38
- def from_file(fn, code_type = nil)
39
- if fn == Pry.eval_path
40
- f = Pry.line_buffer.drop(1)
41
- else
42
- if File.readable?(fn)
43
- f = File.open(fn, 'r')
44
- code_type = type_from_filename(fn)
45
- else
46
- raise MethodSource::SourceNotFoundError, "Cannot open #{fn.inspect} for reading."
47
- end
48
- end
49
- new(f, 1, code_type || :ruby)
50
- ensure
51
- f.close if f.respond_to?(:close)
61
+ def from_file(filename, code_type = type_from_filename(filename))
62
+ code = if filename == Pry.eval_path
63
+ Pry.line_buffer.drop(1)
64
+ else
65
+ File.read(abs_path(filename))
66
+ end
67
+ new(code, 1, code_type)
52
68
  end
53
69
 
54
70
  # Instantiate a `Code` object containing code extracted from a
@@ -56,10 +72,10 @@ class Pry
56
72
  #
57
73
  # @param [::Method, UnboundMethod, Proc, Pry::Method] meth The method
58
74
  # object.
59
- # @param [Fixnum, nil] start_line The line number to start on, or nil to
75
+ # @param [Integer, nil] start_line The line number to start on, or nil to
60
76
  # use the method's original line numbers.
61
77
  # @return [Code]
62
- def from_method(meth, start_line=nil)
78
+ def from_method(meth, start_line = nil)
63
79
  meth = Pry::Method(meth)
64
80
  start_line ||= meth.source_line || 1
65
81
  new(meth.source, start_line, meth.source_type)
@@ -68,48 +84,45 @@ class Pry
68
84
  # Attempt to extract the source code for module (or class) `mod`.
69
85
  #
70
86
  # @param [Module, Class] mod The module (or class) of interest.
71
- # @param [Fixnum, nil] start_line The line number to start on, or nil to use the
72
- # method's original line numbers.
73
- # @param [Fixnum] candidate_rank The module candidate (by rank)
87
+ # @param [Integer, nil] start_line The line number to start on, or nil to
88
+ # use the method's original line numbers.
89
+ # @param [Integer] candidate_rank The module candidate (by rank)
74
90
  # to use (see `Pry::WrappedModule::Candidate` for more information).
75
91
  # @return [Code]
76
- def from_module(mod, start_line=nil, candidate_rank=0)
92
+ def from_module(mod, start_line = nil, candidate_rank = 0)
77
93
  candidate = Pry::WrappedModule(mod).candidate(candidate_rank)
78
-
79
94
  start_line ||= candidate.line
80
95
  new(candidate.source, start_line, :ruby)
81
96
  end
82
97
 
83
98
  protected
84
- # Guess the CodeRay type of a file from its extension, or nil if
85
- # unknown.
86
- #
87
- # @param [String] filename
88
- # @return [Symbol, nil]
89
- def type_from_filename(filename)
90
- map = {
91
- %w(.c .h) => :c,
92
- %w(.cpp .hpp .cc .h cxx) => :cpp,
93
- %w(.rb .ru .irbrc .gemspec .pryrc) => :ruby,
94
- %w(.py) => :python,
95
- %w(.diff) => :diff,
96
- %w(.css) => :css,
97
- %w(.html) => :html,
98
- %w(.yaml .yml) => :yaml,
99
- %w(.xml) => :xml,
100
- %w(.php) => :php,
101
- %w(.js) => :javascript,
102
- %w(.java) => :java,
103
- %w(.rhtml) => :rhtml,
104
- %w(.json) => :json
105
- }
106
-
107
- _, type = map.find do |k, _|
108
- k.any? { |ext| ext == File.extname(filename) }
109
- end
110
-
111
- type
99
+
100
+ # Guess the CodeRay type of a file from its extension, or nil if
101
+ # unknown.
102
+ #
103
+ # @param [String] filename
104
+ # @param [Symbol] default (:ruby) the file type to assume if none could be
105
+ # detected.
106
+ # @return [Symbol, nil]
107
+ def type_from_filename(filename, default = :ruby)
108
+ _, type = Pry::Code::EXTENSIONS.find do |k, _|
109
+ k.any? { |ext| ext == File.extname(filename) }
112
110
  end
111
+
112
+ type || default
113
+ end
114
+
115
+ # @param [String] filename
116
+ # @raise [MethodSource::SourceNotFoundError] if the +filename+ is not
117
+ # readable for some reason.
118
+ # @return [String] absolute path for the given +filename+.
119
+ def abs_path(filename)
120
+ abs_path = [File.expand_path(filename, Dir.pwd),
121
+ File.expand_path(filename, Pry::INITIAL_PWD)
122
+ ].detect { |abs_path| File.readable?(abs_path) }
123
+ abs_path or raise MethodSource::SourceNotFoundError,
124
+ "Cannot open #{filename.inspect} for reading."
125
+ end
113
126
  end
114
127
 
115
128
  # @return [Symbol] The type of code stored in this wrapper.
@@ -121,37 +134,39 @@ class Pry
121
134
  # empty `Code` object and then use `#push` to insert the lines.
122
135
  #
123
136
  # @param [Array<String>, String, IO] lines
124
- # @param [Fixnum?] start_line
137
+ # @param [Integer?] start_line
125
138
  # @param [Symbol?] code_type
126
- def initialize(lines=[], start_line=1, code_type=:ruby)
139
+ def initialize(lines = [], start_line = 1, code_type = :ruby)
127
140
  if lines.is_a? String
128
141
  lines = lines.lines
129
142
  end
130
-
131
- @lines = lines.each_with_index.map { |l, i| [l.chomp, i + start_line.to_i] }
143
+ @lines = lines.each_with_index.map { |line, lineno|
144
+ LOC.new(line, lineno + start_line.to_i) }
132
145
  @code_type = code_type
133
146
  end
134
147
 
135
- # Append the given line. `line_num` is one more than the last existing
148
+ # Append the given line. +lineno+ is one more than the last existing
136
149
  # line, unless specified otherwise.
137
150
  #
138
151
  # @param [String] line
139
- # @param [Fixnum?] line_num
152
+ # @param [Integer?] lineno
140
153
  # @return [String] The inserted line.
141
- def push(line, line_num=nil)
142
- line_num = @lines.last.last + 1 unless line_num
143
- @lines.push([line.chomp, line_num])
154
+ def push(line, lineno = nil)
155
+ if lineno.nil?
156
+ lineno = @lines.last.lineno + 1
157
+ end
158
+ @lines.push(LOC.new(line, lineno))
144
159
  line
145
160
  end
146
161
  alias << push
147
162
 
148
163
  # Filter the lines using the given block.
149
164
  #
150
- # @yield [line]
165
+ # @yield [LOC]
151
166
  # @return [Code]
152
- def select(&blk)
167
+ def select(&block)
153
168
  alter do
154
- @lines = @lines.select(&blk)
169
+ @lines = @lines.select(&block)
155
170
  end
156
171
  end
157
172
 
@@ -159,92 +174,74 @@ class Pry
159
174
  # `Range` object or a first and last line number (inclusive). Negative
160
175
  # indices count from the end of the array of lines.
161
176
  #
162
- # @param [Range, Fixnum] start_line
163
- # @param [Fixnum?] end_line
177
+ # @param [Range, Integer] start_line
178
+ # @param [Integer?] end_line
164
179
  # @return [Code]
165
- def between(start_line, end_line=nil)
180
+ def between(start_line, end_line = nil)
166
181
  return self unless start_line
167
182
 
168
- if start_line.is_a? Range
169
- end_line = start_line.last
170
- end_line -= 1 if start_line.exclude_end?
171
-
172
- start_line = start_line.first
173
- else
174
- end_line ||= start_line
175
- end
176
-
177
- if start_line > 0
178
- start_idx = @lines.index { |l| l.last >= start_line } || @lines.length
179
- else
180
- start_idx = start_line
181
- end
182
-
183
- if end_line > 0
184
- end_idx = (@lines.index { |l| l.last > end_line } || 0) - 1
185
- else
186
- end_idx = end_line
187
- end
183
+ code_range = CodeRange.new(start_line, end_line)
188
184
 
189
185
  alter do
190
- @lines = @lines[start_idx..end_idx] || []
186
+ @lines = @lines[code_range.indices_range(@lines)] || []
191
187
  end
192
188
  end
193
189
 
194
- # Take `num_lines` from `start_line`, forward or backwards
190
+ # Take `num_lines` from `start_line`, forward or backwards.
195
191
  #
196
- # @param [Fixnum] start_line
197
- # @param [Fixnum] num_lines
192
+ # @param [Integer] start_line
193
+ # @param [Integer] num_lines
198
194
  # @return [Code]
199
195
  def take_lines(start_line, num_lines)
200
- if start_line >= 0
201
- start_idx = @lines.index { |l| l.last >= start_line } || @lines.length
202
- else
203
- start_idx = @lines.length + start_line
204
- end
196
+ start_idx =
197
+ if start_line >= 0
198
+ @lines.index { |loc| loc.lineno >= start_line } || @lines.length
199
+ else
200
+ @lines.length + start_line
201
+ end
205
202
 
206
203
  alter do
207
204
  @lines = @lines.slice(start_idx, num_lines)
208
205
  end
209
206
  end
210
207
 
211
- # Remove all lines except for the `lines` up to and excluding `line_num`.
208
+ # Remove all lines except for the +lines+ up to and excluding +lineno+.
212
209
  #
213
- # @param [Fixnum] line_num
214
- # @param [Fixnum] lines
210
+ # @param [Integer] lineno
211
+ # @param [Integer] lines
215
212
  # @return [Code]
216
- def before(line_num, lines=1)
217
- return self unless line_num
213
+ def before(lineno, lines = 1)
214
+ return self unless lineno
218
215
 
219
- select do |l, ln|
220
- ln >= line_num - lines && ln < line_num
216
+ select do |loc|
217
+ loc.lineno >= lineno - lines && loc.lineno < lineno
221
218
  end
222
219
  end
223
220
 
224
- # Remove all lines except for the `lines` on either side of and including
225
- # `line_num`.
221
+ # Remove all lines except for the +lines+ on either side of and including
222
+ # +lineno+.
226
223
  #
227
- # @param [Fixnum] line_num
228
- # @param [Fixnum] lines
224
+ # @param [Integer] lineno
225
+ # @param [Integer] lines
229
226
  # @return [Code]
230
- def around(line_num, lines=1)
231
- return self unless line_num
227
+ def around(lineno, lines = 1)
228
+ return self unless lineno
232
229
 
233
- select do |l, ln|
234
- ln >= line_num - lines && ln <= line_num + lines
230
+ select do |loc|
231
+ loc.lineno >= lineno - lines && loc.lineno <= lineno + lines
235
232
  end
236
233
  end
237
234
 
238
- # Remove all lines except for the `lines` after and excluding `line_num`.
235
+ # Remove all lines except for the +lines+ after and excluding +lineno+.
239
236
  #
240
- # @param [Fixnum] line_num
241
- # @param [Fixnum] lines
237
+ # @param [Integer] lineno
238
+ # @param [Integer] lines
242
239
  # @return [Code]
243
- def after(line_num, lines=1)
244
- return self unless line_num
240
+ def after(lineno, lines = 1)
241
+ return self unless lineno
245
242
 
246
- select do |l, ln|
247
- ln > line_num && ln <= line_num + lines
243
+ select do |loc|
244
+ loc.lineno > lineno && loc.lineno <= lineno + lines
248
245
  end
249
246
  end
250
247
 
@@ -256,8 +253,8 @@ class Pry
256
253
  return self unless pattern
257
254
  pattern = Regexp.new(pattern)
258
255
 
259
- select do |l, ln|
260
- l =~ pattern
256
+ select do |loc|
257
+ loc.line =~ pattern
261
258
  end
262
259
  end
263
260
 
@@ -265,30 +262,30 @@ class Pry
265
262
  #
266
263
  # @param [Boolean?] y_n
267
264
  # @return [Code]
268
- def with_line_numbers(y_n=true)
265
+ def with_line_numbers(y_n = true)
269
266
  alter do
270
267
  @with_line_numbers = y_n
271
268
  end
272
269
  end
273
270
 
274
- # Format output with a marker next to the given `line_num`, unless `line_num`
275
- # is falsy.
271
+ # Format output with a marker next to the given +lineno+, unless +lineno+ is
272
+ # falsy.
276
273
  #
277
- # @param [Fixnum?] line_num
274
+ # @param [Integer?] lineno
278
275
  # @return [Code]
279
- def with_marker(line_num=1)
276
+ def with_marker(lineno = 1)
280
277
  alter do
281
- @with_marker = !!line_num
282
- @marker_line_num = line_num
278
+ @with_marker = !!lineno
279
+ @marker_lineno = lineno
283
280
  end
284
281
  end
285
282
 
286
283
  # Format output with the specified number of spaces in front of every line,
287
284
  # unless `spaces` is falsy.
288
285
  #
289
- # @param [Fixnum?] spaces
286
+ # @param [Integer?] spaces
290
287
  # @return [Code]
291
- def with_indentation(spaces=0)
288
+ def with_indentation(spaces = 0)
292
289
  alter do
293
290
  @with_indentation = !!spaces
294
291
  @indentation_num = spaces
@@ -300,72 +297,59 @@ class Pry
300
297
  Object.instance_method(:to_s).bind(self).call
301
298
  end
302
299
 
303
- # Based on the configuration of the object, return a formatted String
304
- # representation.
305
- #
306
- # @return [String]
307
- def to_s
308
- lines = @lines.map(&:dup)
309
-
310
- if Pry.color
311
- lines.each do |l|
312
- l[0] = CodeRay.scan(l[0], @code_type).term
313
- end
314
- end
315
-
316
- if @with_line_numbers
317
- max_width = lines.last.last.to_s.length if lines.length > 0
318
- lines.each do |l|
319
- padded_line_num = l[1].to_s.rjust(max_width)
320
- l[0] = "#{Pry::Helpers::BaseHelpers.colorize_code(padded_line_num.to_s)}: #{l[0]}"
321
- end
322
- end
323
-
324
- if @with_marker
325
- lines.each do |l|
326
- if l[1] == @marker_line_num
327
- l[0] = " => #{l[0]}"
328
- else
329
- l[0] = " #{l[0]}"
330
- end
331
- end
332
- end
333
-
334
- if @with_indentation
335
- lines.each do |l|
336
- l[0] = "#{' ' * @indentation_num}#{l[0]}"
337
- end
338
- end
300
+ # @return [Integer] the number of digits in the last line.
301
+ def max_lineno_width
302
+ @lines.length > 0 ? @lines.last.lineno.to_s.length : 0
303
+ end
339
304
 
340
- lines.map { |l| "#{l.first}\n" }.join
305
+ # @return [String] a formatted representation (based on the configuration of
306
+ # the object).
307
+ def to_s
308
+ @lines.map { |loc|
309
+ loc = loc.dup
310
+ loc.colorize(@code_type) if Pry.color
311
+ loc.add_line_number(max_lineno_width) if @with_line_numbers
312
+ loc.add_marker(@marker_lineno) if @with_marker
313
+ loc.indent(@indentation_num) if @with_indentation
314
+ loc.line
315
+ }.join("\n") + "\n"
341
316
  end
342
317
 
343
318
  # Get the comment that describes the expression on the given line number.
344
319
  #
345
- # @param [Fixnum] line_number (1-based)
346
- # @return [String] the code.
320
+ # @param [Integer] line_number (1-based)
321
+ # @return [String] the code.
347
322
  def comment_describing(line_number)
348
323
  self.class.comment_describing(raw, line_number)
349
324
  end
350
325
 
351
326
  # Get the multiline expression that starts on the given line number.
352
327
  #
353
- # @param [Fixnum] line_number (1-based)
354
- # @return [String] the code.
355
- def expression_at(line_number, consume=0)
328
+ # @param [Integer] line_number (1-based)
329
+ # @return [String] the code.
330
+ def expression_at(line_number, consume = 0)
356
331
  self.class.expression_at(raw, line_number, :consume => consume)
357
332
  end
358
333
 
334
+ # Get the (approximate) Module.nesting at the give line number.
335
+ #
336
+ # @param [Integer] line_number line number starting from 1
337
+ # @param [Module] top_module the module in which this code exists
338
+ # @return [Array<Module>] a list of open modules.
339
+ def nesting_at(line_number, top_module = Object)
340
+ Pry::Indent.nesting_at(raw, line_number)
341
+ end
342
+
359
343
  # Return an unformatted String of the code.
360
344
  #
361
345
  # @return [String]
362
346
  def raw
363
- @lines.map(&:first).join("\n") + "\n"
347
+ @lines.map(&:line).join("\n") + "\n"
364
348
  end
365
349
 
366
350
  # Return the number of lines stored.
367
351
  #
368
- # @return [Fixnum]
352
+ # @return [Integer]
369
353
  def length
370
354
  @lines ? @lines.length : 0
371
355
  end
@@ -377,26 +361,25 @@ class Pry
377
361
  # @return [Boolean]
378
362
  def ==(other)
379
363
  if other.is_a?(Code)
380
- @other_lines = other.instance_variable_get(:@lines)
381
- @lines.each_with_index.all? do |(l, ln), i|
382
- l == @other_lines[i].first && ln == @other_lines[i].last
383
- end
364
+ other_lines = other.instance_variable_get(:@lines)
365
+ @lines.each_with_index.all? { |loc, i| loc == other_lines[i] }
384
366
  else
385
367
  to_s.chomp == other.to_s.chomp
386
368
  end
387
369
  end
388
370
 
389
371
  # Forward any missing methods to the output of `#to_s`.
390
- def method_missing(name, *args, &blk)
391
- to_s.send(name, *args, &blk)
372
+ def method_missing(name, *args, &block)
373
+ to_s.send(name, *args, &block)
392
374
  end
393
375
  undef =~
394
376
 
395
377
  protected
396
- # An abstraction of the `dup.instance_eval` pattern used throughout this
397
- # class.
398
- def alter(&blk)
399
- dup.tap { |o| o.instance_eval(&blk) }
400
- end
378
+
379
+ # An abstraction of the `dup.instance_eval` pattern used throughout this
380
+ # class.
381
+ def alter(&block)
382
+ dup.tap { |o| o.instance_eval(&block) }
383
+ end
401
384
  end
402
385
  end