pry 0.12.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +162 -1
  3. data/LICENSE +1 -1
  4. data/README.md +331 -269
  5. data/bin/pry +5 -0
  6. data/lib/pry.rb +132 -119
  7. data/lib/pry/basic_object.rb +8 -4
  8. data/lib/pry/block_command.rb +22 -0
  9. data/lib/pry/class_command.rb +194 -0
  10. data/lib/pry/cli.rb +43 -51
  11. data/lib/pry/code.rb +40 -28
  12. data/lib/pry/code/code_file.rb +28 -24
  13. data/lib/pry/code/code_range.rb +4 -2
  14. data/lib/pry/code/loc.rb +15 -8
  15. data/lib/pry/code_object.rb +40 -38
  16. data/lib/pry/color_printer.rb +47 -46
  17. data/lib/pry/command.rb +166 -369
  18. data/lib/pry/command_set.rb +76 -73
  19. data/lib/pry/command_state.rb +31 -0
  20. data/lib/pry/commands/amend_line.rb +86 -81
  21. data/lib/pry/commands/bang.rb +18 -14
  22. data/lib/pry/commands/bang_pry.rb +15 -11
  23. data/lib/pry/commands/cat.rb +61 -54
  24. data/lib/pry/commands/cat/abstract_formatter.rb +23 -18
  25. data/lib/pry/commands/cat/exception_formatter.rb +71 -60
  26. data/lib/pry/commands/cat/file_formatter.rb +55 -49
  27. data/lib/pry/commands/cat/input_expression_formatter.rb +35 -30
  28. data/lib/pry/commands/cd.rb +40 -35
  29. data/lib/pry/commands/change_inspector.rb +29 -22
  30. data/lib/pry/commands/change_prompt.rb +44 -39
  31. data/lib/pry/commands/clear_screen.rb +16 -10
  32. data/lib/pry/commands/code_collector.rb +148 -133
  33. data/lib/pry/commands/disable_pry.rb +23 -19
  34. data/lib/pry/commands/easter_eggs.rb +19 -30
  35. data/lib/pry/commands/edit.rb +184 -161
  36. data/lib/pry/commands/edit/exception_patcher.rb +21 -17
  37. data/lib/pry/commands/edit/file_and_line_locator.rb +34 -23
  38. data/lib/pry/commands/exit.rb +39 -35
  39. data/lib/pry/commands/exit_all.rb +24 -20
  40. data/lib/pry/commands/exit_program.rb +20 -16
  41. data/lib/pry/commands/find_method.rb +168 -160
  42. data/lib/pry/commands/fix_indent.rb +16 -12
  43. data/lib/pry/commands/help.rb +140 -133
  44. data/lib/pry/commands/hist.rb +151 -150
  45. data/lib/pry/commands/import_set.rb +20 -16
  46. data/lib/pry/commands/jump_to.rb +25 -21
  47. data/lib/pry/commands/list_inspectors.rb +35 -28
  48. data/lib/pry/commands/ls.rb +124 -102
  49. data/lib/pry/commands/ls/constants.rb +59 -42
  50. data/lib/pry/commands/ls/formatter.rb +50 -46
  51. data/lib/pry/commands/ls/globals.rb +38 -34
  52. data/lib/pry/commands/ls/grep.rb +17 -13
  53. data/lib/pry/commands/ls/instance_vars.rb +29 -27
  54. data/lib/pry/commands/ls/interrogatable.rb +18 -12
  55. data/lib/pry/commands/ls/jruby_hacks.rb +47 -41
  56. data/lib/pry/commands/ls/local_names.rb +26 -22
  57. data/lib/pry/commands/ls/local_vars.rb +38 -28
  58. data/lib/pry/commands/ls/ls_entity.rb +47 -51
  59. data/lib/pry/commands/ls/methods.rb +44 -43
  60. data/lib/pry/commands/ls/methods_helper.rb +46 -42
  61. data/lib/pry/commands/ls/self_methods.rb +23 -22
  62. data/lib/pry/commands/nesting.rb +21 -17
  63. data/lib/pry/commands/play.rb +93 -82
  64. data/lib/pry/commands/pry_backtrace.rb +22 -17
  65. data/lib/pry/commands/pry_version.rb +15 -11
  66. data/lib/pry/commands/raise_up.rb +27 -22
  67. data/lib/pry/commands/reload_code.rb +60 -48
  68. data/lib/pry/commands/reset.rb +16 -12
  69. data/lib/pry/commands/ri.rb +55 -45
  70. data/lib/pry/commands/save_file.rb +45 -43
  71. data/lib/pry/commands/shell_command.rb +51 -51
  72. data/lib/pry/commands/shell_mode.rb +21 -17
  73. data/lib/pry/commands/show_doc.rb +80 -68
  74. data/lib/pry/commands/show_info.rb +189 -171
  75. data/lib/pry/commands/show_input.rb +16 -11
  76. data/lib/pry/commands/show_source.rb +110 -45
  77. data/lib/pry/commands/stat.rb +35 -31
  78. data/lib/pry/commands/switch_to.rb +21 -15
  79. data/lib/pry/commands/toggle_color.rb +20 -16
  80. data/lib/pry/commands/watch_expression.rb +89 -86
  81. data/lib/pry/commands/watch_expression/expression.rb +32 -27
  82. data/lib/pry/commands/whereami.rb +156 -148
  83. data/lib/pry/commands/wtf.rb +75 -50
  84. data/lib/pry/config.rb +307 -25
  85. data/lib/pry/config/attributable.rb +22 -0
  86. data/lib/pry/config/lazy_value.rb +29 -0
  87. data/lib/pry/config/memoized_value.rb +34 -0
  88. data/lib/pry/config/value.rb +24 -0
  89. data/lib/pry/control_d_handler.rb +28 -0
  90. data/lib/pry/core_extensions.rb +9 -7
  91. data/lib/pry/editor.rb +48 -21
  92. data/lib/pry/env.rb +18 -0
  93. data/lib/pry/exception_handler.rb +43 -0
  94. data/lib/pry/exceptions.rb +13 -16
  95. data/lib/pry/forwardable.rb +5 -1
  96. data/lib/pry/helpers.rb +2 -0
  97. data/lib/pry/helpers/base_helpers.rb +68 -197
  98. data/lib/pry/helpers/command_helpers.rb +50 -61
  99. data/lib/pry/helpers/documentation_helpers.rb +20 -13
  100. data/lib/pry/helpers/options_helpers.rb +14 -7
  101. data/lib/pry/helpers/platform.rb +7 -5
  102. data/lib/pry/helpers/table.rb +33 -26
  103. data/lib/pry/helpers/text.rb +17 -14
  104. data/lib/pry/history.rb +48 -56
  105. data/lib/pry/hooks.rb +21 -12
  106. data/lib/pry/indent.rb +54 -50
  107. data/lib/pry/input_completer.rb +248 -230
  108. data/lib/pry/input_lock.rb +8 -9
  109. data/lib/pry/inspector.rb +36 -24
  110. data/lib/pry/last_exception.rb +45 -45
  111. data/lib/pry/method.rb +141 -94
  112. data/lib/pry/method/disowned.rb +16 -4
  113. data/lib/pry/method/patcher.rb +12 -3
  114. data/lib/pry/method/weird_method_locator.rb +68 -44
  115. data/lib/pry/object_path.rb +33 -25
  116. data/lib/pry/output.rb +121 -35
  117. data/lib/pry/pager.rb +186 -180
  118. data/lib/pry/prompt.rb +123 -54
  119. data/lib/pry/pry_class.rb +61 -103
  120. data/lib/pry/pry_instance.rb +217 -215
  121. data/lib/pry/repl.rb +18 -22
  122. data/lib/pry/repl_file_loader.rb +27 -21
  123. data/lib/pry/ring.rb +11 -6
  124. data/lib/pry/slop.rb +574 -563
  125. data/lib/pry/slop/commands.rb +164 -169
  126. data/lib/pry/slop/option.rb +172 -168
  127. data/lib/pry/syntax_highlighter.rb +26 -0
  128. data/lib/pry/system_command_handler.rb +17 -0
  129. data/lib/pry/testable.rb +59 -61
  130. data/lib/pry/testable/evalable.rb +21 -12
  131. data/lib/pry/testable/mockable.rb +18 -10
  132. data/lib/pry/testable/pry_tester.rb +71 -56
  133. data/lib/pry/testable/utility.rb +29 -21
  134. data/lib/pry/testable/variables.rb +49 -43
  135. data/lib/pry/version.rb +3 -1
  136. data/lib/pry/warning.rb +27 -0
  137. data/lib/pry/wrapped_module.rb +51 -42
  138. data/lib/pry/wrapped_module/candidate.rb +21 -14
  139. metadata +35 -35
  140. data/lib/pry/commands.rb +0 -6
  141. data/lib/pry/commands/disabled_commands.rb +0 -2
  142. data/lib/pry/commands/gem_cd.rb +0 -26
  143. data/lib/pry/commands/gem_install.rb +0 -32
  144. data/lib/pry/commands/gem_list.rb +0 -33
  145. data/lib/pry/commands/gem_open.rb +0 -29
  146. data/lib/pry/commands/gem_readme.rb +0 -25
  147. data/lib/pry/commands/gem_search.rb +0 -40
  148. data/lib/pry/commands/gem_stats.rb +0 -83
  149. data/lib/pry/commands/gist.rb +0 -102
  150. data/lib/pry/commands/install_command.rb +0 -54
  151. data/lib/pry/config/behavior.rb +0 -255
  152. data/lib/pry/config/convenience.rb +0 -28
  153. data/lib/pry/config/default.rb +0 -159
  154. data/lib/pry/config/memoization.rb +0 -48
  155. data/lib/pry/platform.rb +0 -91
  156. data/lib/pry/plugins.rb +0 -122
  157. data/lib/pry/rubygem.rb +0 -84
  158. data/lib/pry/terminal.rb +0 -91
@@ -1,24 +1,28 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Pry
2
- class Command::Edit
3
- class ExceptionPatcher
4
- attr_accessor :_pry_
5
- attr_accessor :state
6
- attr_accessor :file_and_line
4
+ class Command
5
+ class Edit
6
+ class ExceptionPatcher
7
+ attr_accessor :pry_instance
8
+ attr_accessor :state
9
+ attr_accessor :file_and_line
7
10
 
8
- def initialize(_pry_, state, exception_file_and_line)
9
- @_pry_ = _pry_
10
- @state = state
11
- @file_and_line = exception_file_and_line
12
- end
11
+ def initialize(pry_instance, state, exception_file_and_line)
12
+ @pry_instance = pry_instance
13
+ @state = state
14
+ @file_and_line = exception_file_and_line
15
+ end
13
16
 
14
- # perform the patch
15
- def perform_patch
16
- file_name, _ = file_and_line
17
- lines = state.dynamical_ex_file || File.read(file_name)
17
+ # perform the patch
18
+ def perform_patch
19
+ file_name, = file_and_line
20
+ lines = state.dynamical_ex_file || File.read(file_name)
18
21
 
19
- source = Pry::Editor.new(_pry_).edit_tempfile_with_content(lines)
20
- _pry_.evaluate_ruby source
21
- state.dynamical_ex_file = source.split("\n")
22
+ source = Pry::Editor.new(pry_instance).edit_tempfile_with_content(lines)
23
+ pry_instance.evaluate_ruby source
24
+ state.dynamical_ex_file = source.split("\n")
25
+ end
22
26
  end
23
27
  end
24
28
  end
@@ -1,34 +1,45 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Pry
2
- class Command::Edit
3
- module FileAndLineLocator
4
- class << self
5
- def from_binding(target)
6
- [target.eval("__FILE__"), target.eval("__LINE__")]
7
- end
4
+ class Command
5
+ class Edit
6
+ module FileAndLineLocator
7
+ class << self
8
+ def from_binding(target)
9
+ if target.respond_to?(:source_location)
10
+ target.source_location
11
+ else
12
+ target.eval("[__FILE__, __LINE__]")
13
+ end
14
+ end
15
+
16
+ def from_code_object(code_object, filename_argument)
17
+ unless File.exist?(code_object.source_file.to_s)
18
+ raise CommandError, "Cannot find a file for #{filename_argument}!"
19
+ end
8
20
 
9
- def from_code_object(code_object, filename_argument)
10
- if File.exist?(code_object.source_file.to_s)
11
21
  [code_object.source_file, code_object.source_line]
12
- else
13
- raise CommandError, "Cannot find a file for #{filename_argument}!"
14
22
  end
15
- end
16
23
 
17
- def from_exception(exception, backtrace_level)
18
- raise CommandError, "No exception found." if exception.nil?
24
+ def from_exception(exception, backtrace_level)
25
+ raise CommandError, "No exception found." if exception.nil?
19
26
 
20
- file_name, line = exception.bt_source_location_for(backtrace_level)
21
- raise CommandError, "Exception has no associated file." if file_name.nil?
22
- raise CommandError, "Cannot edit exceptions raised in REPL." if Pry.eval_path == file_name
27
+ file_name, line = exception.bt_source_location_for(backtrace_level)
28
+ raise CommandError, "Exception has no associated file." if file_name.nil?
23
29
 
24
- [file_name, line]
25
- end
30
+ if Pry.eval_path == file_name
31
+ raise CommandError, "Cannot edit exceptions raised in REPL."
32
+ end
33
+
34
+ [file_name, line]
35
+ end
26
36
 
27
- # when file and line are passed as a single arg, e.g my_file.rb:30
28
- def from_filename_argument(filename_argument)
29
- f = File.expand_path(filename_argument)
30
- l = f.sub!(/:(\d+)$/, "") ? $1.to_i : 1
31
- [f, l]
37
+ # when file and line are passed as a single arg, e.g my_file.rb:30
38
+ def from_filename_argument(filename_argument)
39
+ f = File.expand_path(filename_argument)
40
+ l = f.sub!(/:(\d+)$/, "") ? Regexp.last_match(1).to_i : 1
41
+ [f, l]
42
+ end
32
43
  end
33
44
  end
34
45
  end
@@ -1,43 +1,47 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Pry
2
- class Command::Exit < Pry::ClassCommand
3
- match 'exit'
4
- group 'Navigating Pry'
5
- description 'Pop the previous binding.'
6
- command_options keep_retval: true
7
-
8
- banner <<-'BANNER'
9
- Usage: exit [OPTIONS] [--help]
10
- Aliases: quit
11
-
12
- Pop the previous binding (does NOT exit program). It can be useful to exit a
13
- context with a user-provided value. For instance an exit value can be used to
14
- determine program flow.
15
-
16
- exit "pry this"
17
- exit
18
-
19
- https://github.com/pry/pry/wiki/State-navigation#wiki-Exit_with_value
20
- BANNER
21
-
22
- def process
23
- if _pry_.binding_stack.one?
24
- _pry_.run_command "exit-all #{arg_string}"
25
- else
26
- # otherwise just pop a binding and return user supplied value
27
- process_pop_and_return
4
+ class Command
5
+ class Exit < Pry::ClassCommand
6
+ match 'exit'
7
+ group 'Navigating Pry'
8
+ description 'Pop the previous binding.'
9
+ command_options keep_retval: true
10
+
11
+ banner <<-'BANNER'
12
+ Usage: exit [OPTIONS] [--help]
13
+ Aliases: quit
14
+
15
+ Pop the previous binding (does NOT exit program). It can be useful to exit a
16
+ context with a user-provided value. For instance an exit value can be used to
17
+ determine program flow.
18
+
19
+ exit "pry this"
20
+ exit
21
+
22
+ https://github.com/pry/pry/wiki/State-navigation#wiki-Exit_with_value
23
+ BANNER
24
+
25
+ def process
26
+ if pry_instance.binding_stack.one?
27
+ pry_instance.run_command "exit-all #{arg_string}"
28
+ else
29
+ # otherwise just pop a binding and return user supplied value
30
+ process_pop_and_return
31
+ end
28
32
  end
29
- end
30
33
 
31
- def process_pop_and_return
32
- popped_object = _pry_.binding_stack.pop.eval('self')
34
+ def process_pop_and_return
35
+ popped_object = pry_instance.binding_stack.pop.eval('self')
33
36
 
34
- # return a user-specified value if given otherwise return the object
35
- return target.eval(arg_string) unless arg_string.empty?
37
+ # return a user-specified value if given otherwise return the object
38
+ return target.eval(arg_string) unless arg_string.empty?
36
39
 
37
- popped_object
40
+ popped_object
41
+ end
38
42
  end
39
- end
40
43
 
41
- Pry::Commands.add_command(Pry::Command::Exit)
42
- Pry::Commands.alias_command 'quit', 'exit'
44
+ Pry::Commands.add_command(Pry::Command::Exit)
45
+ Pry::Commands.alias_command 'quit', 'exit'
46
+ end
43
47
  end
@@ -1,29 +1,33 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Pry
2
- class Command::ExitAll < Pry::ClassCommand
3
- match 'exit-all'
4
- group 'Navigating Pry'
5
- description 'End the current Pry session.'
4
+ class Command
5
+ class ExitAll < Pry::ClassCommand
6
+ match 'exit-all'
7
+ group 'Navigating Pry'
8
+ description 'End the current Pry session.'
6
9
 
7
- banner <<-'BANNER'
8
- Usage: exit-all [--help]
9
- Aliases: !!@
10
+ banner <<-'BANNER'
11
+ Usage: exit-all [--help]
12
+ Aliases: !!@
10
13
 
11
- End the current Pry session (popping all bindings and returning to caller).
12
- Accepts optional return value.
13
- BANNER
14
+ End the current Pry session (popping all bindings and returning to caller).
15
+ Accepts optional return value.
16
+ BANNER
14
17
 
15
- def process
16
- # calculate user-given value
17
- exit_value = target.eval(arg_string)
18
+ def process
19
+ # calculate user-given value
20
+ exit_value = target.eval(arg_string)
18
21
 
19
- # clear the binding stack
20
- _pry_.binding_stack.clear
22
+ # clear the binding stack
23
+ pry_instance.binding_stack.clear
21
24
 
22
- # break out of the repl loop
23
- throw(:breakout, exit_value)
25
+ # break out of the repl loop
26
+ throw(:breakout, exit_value)
27
+ end
24
28
  end
25
- end
26
29
 
27
- Pry::Commands.add_command(Pry::Command::ExitAll)
28
- Pry::Commands.alias_command '!!@', 'exit-all'
30
+ Pry::Commands.add_command(Pry::Command::ExitAll)
31
+ Pry::Commands.alias_command '!!@', 'exit-all'
32
+ end
29
33
  end
@@ -1,23 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Pry
2
- class Command::ExitProgram < Pry::ClassCommand
3
- match 'exit-program'
4
- group 'Navigating Pry'
5
- description 'End the current program.'
4
+ class Command
5
+ class ExitProgram < Pry::ClassCommand
6
+ match 'exit-program'
7
+ group 'Navigating Pry'
8
+ description 'End the current program.'
6
9
 
7
- banner <<-'BANNER'
8
- Usage: exit-program [--help]
9
- Aliases: quit-program
10
- !!!
10
+ banner <<-'BANNER'
11
+ Usage: exit-program [--help]
12
+ Aliases: quit-program
13
+ !!!
11
14
 
12
- End the current program.
13
- BANNER
15
+ End the current program.
16
+ BANNER
14
17
 
15
- def process
16
- Kernel.exit target.eval(arg_string).to_i
18
+ def process
19
+ Kernel.exit target.eval(arg_string).to_i
20
+ end
17
21
  end
18
- end
19
22
 
20
- Pry::Commands.add_command(Pry::Command::ExitProgram)
21
- Pry::Commands.alias_command 'quit-program', 'exit-program'
22
- Pry::Commands.alias_command '!!!', 'exit-program'
23
+ Pry::Commands.add_command(Pry::Command::ExitProgram)
24
+ Pry::Commands.alias_command 'quit-program', 'exit-program'
25
+ Pry::Commands.alias_command '!!!', 'exit-program'
26
+ end
23
27
  end
@@ -1,191 +1,199 @@
1
- class Pry
2
- class Command::FindMethod < Pry::ClassCommand
3
- extend Pry::Helpers::BaseHelpers
4
-
5
- match 'find-method'
6
- group 'Context'
7
- description 'Recursively search for a method within a Class/Module or the current namespace.'
8
- command_options shellwords: false
9
-
10
- banner <<-'BANNER'
11
- Usage: find-method [-n|-c] METHOD [NAMESPACE]
12
-
13
- Recursively search for a method within a Class/Module or the current namespace.
14
- Use the `-n` switch (the default) to search for methods whose name matches the
15
- given regex. Use the `-c` switch to search for methods that contain the given
16
- code.
17
-
18
- # Find all methods whose name match /re/ inside
19
- # the Pry namespace. Matches Pry#repl, etc.
20
- find-method re Pry
21
-
22
- # Find all methods that contain the code:
23
- # output.puts inside the Pry namespace.
24
- find-method -c 'output.puts' Pry
25
- BANNER
26
-
27
- def options(opt)
28
- opt.on :n, :name, "Search for a method by name"
29
- opt.on :c, :content, "Search for a method based on content in Regex form"
30
- end
31
-
32
- def process
33
- return if args.size < 1
1
+ # frozen_string_literal: true
34
2
 
35
- klass = search_class
36
-
37
- matches = opts.content? ? content_search(klass) : name_search(klass)
38
- show_search_results(matches)
39
- end
3
+ class Pry
4
+ class Command
5
+ class FindMethod < Pry::ClassCommand
6
+ extend Pry::Helpers::BaseHelpers
7
+
8
+ match 'find-method'
9
+ group 'Context'
10
+ description 'Recursively search for a method within a Class/Module or ' \
11
+ 'the current namespace.'
12
+ command_options shellwords: false
13
+
14
+ banner <<-'BANNER'
15
+ Usage: find-method [-n|-c] METHOD [NAMESPACE]
16
+
17
+ Recursively search for a method within a Class/Module or the current namespace.
18
+ Use the `-n` switch (the default) to search for methods whose name matches the
19
+ given regex. Use the `-c` switch to search for methods that contain the given
20
+ code.
21
+
22
+ # Find all methods whose name match /re/ inside
23
+ # the Pry namespace. Matches Pry#repl, etc.
24
+ find-method re Pry
25
+
26
+ # Find all methods that contain the code:
27
+ # output.puts inside the Pry namespace.
28
+ find-method -c 'output.puts' Pry
29
+ BANNER
30
+
31
+ def options(opt)
32
+ opt.on :n, :name, "Search for a method by name"
33
+ opt.on :c, :content, "Search for a method based on content in Regex form"
34
+ end
40
35
 
41
- private
36
+ def process
37
+ return if args.empty?
42
38
 
43
- # @return [Regexp] The pattern to search for.
44
- def pattern
45
- @pattern ||= ::Regexp.new args[0]
46
- end
39
+ klass = search_class
47
40
 
48
- # Output the result of the search.
49
- #
50
- # @param [Array] matches
51
- def show_search_results(matches)
52
- if matches.empty?
53
- output.puts bold("No Methods Matched")
54
- else
55
- print_matches(matches)
41
+ matches = opts.content? ? content_search(klass) : name_search(klass)
42
+ show_search_results(matches)
56
43
  end
57
- end
58
44
 
59
- # The class to search for methods.
60
- # We only search classes, so if the search object is an
61
- # instance, return its class. If no search object is given
62
- # search `target_self`.
63
- def search_class
64
- klass = if args[1]
65
- target.eval(args[1])
66
- else
67
- target_self
68
- end
69
-
70
- klass.is_a?(Module) ? klass : klass.class
71
- end
72
-
73
- # pretty-print a list of matching methods.
74
- #
75
- # @param [Array<Method>] matches
76
- def print_matches(matches)
77
- grouped = matches.group_by(&:owner)
78
- order = grouped.keys.sort_by { |x| x.name || x.to_s }
45
+ private
79
46
 
80
- order.each do |klass|
81
- print_matches_for_class(klass, grouped)
47
+ # @return [Regexp] The pattern to search for.
48
+ def pattern
49
+ @pattern ||= ::Regexp.new args[0]
82
50
  end
83
- end
84
51
 
85
- # Print matched methods for a class
86
- def print_matches_for_class(klass, grouped)
87
- output.puts bold(klass.name)
88
- grouped[klass].each do |method|
89
- header = method.name_with_owner
90
- output.puts header + additional_info(header, method)
52
+ # Output the result of the search.
53
+ #
54
+ # @param [Array] matches
55
+ def show_search_results(matches)
56
+ if matches.empty?
57
+ output.puts bold("No Methods Matched")
58
+ else
59
+ print_matches(matches)
60
+ end
91
61
  end
92
- end
93
62
 
94
- # Return the matched lines of method source if `-c` is given or ""
95
- # if `-c` was not given
96
- def additional_info(header, method)
97
- if opts.content?
98
- ": " << colorize_code(matched_method_lines(header, method))
99
- else
100
- ""
63
+ # The class to search for methods.
64
+ # We only search classes, so if the search object is an
65
+ # instance, return its class. If no search object is given
66
+ # search `target_self`.
67
+ def search_class
68
+ klass = if args[1]
69
+ target.eval(args[1])
70
+ else
71
+ target_self
72
+ end
73
+
74
+ klass.is_a?(Module) ? klass : klass.class
101
75
  end
102
- end
103
76
 
104
- def matched_method_lines(header, method)
105
- method.source.split(/\n/).select { |x| x =~ pattern }.join("\n#{' ' * header.length}")
106
- end
77
+ # pretty-print a list of matching methods.
78
+ #
79
+ # @param [Array<Method>] matches
80
+ def print_matches(matches)
81
+ grouped = matches.group_by(&:owner)
82
+ order = grouped.keys.sort_by { |x| x.name || x.to_s }
107
83
 
108
- # Run the given block against every constant in the provided namespace.
109
- #
110
- # @param [Module] klass The namespace in which to start the search.
111
- # @param [Hash<Module,Boolean>] done The namespaces we've already visited (private)
112
- # @yieldparam klass Each class/module in the namespace.
113
- #
114
- def recurse_namespace(klass, done = {}, &block)
115
- return if !(Module === klass) || done[klass]
116
-
117
- done[klass] = true
118
-
119
- yield klass
120
-
121
- klass.constants.each do |name|
122
- next if klass.autoload?(name)
123
-
124
- begin
125
- const = klass.const_get(name)
126
- rescue RescuableException
127
- # constant loading is an inexact science at the best of times,
128
- # this often happens when a constant was .autoload? but someone
129
- # tried to load it. It's now not .autoload? but will still raise
130
- # a NameError when you access it.
131
- else
132
- recurse_namespace(const, done, &block)
84
+ order.each do |klass|
85
+ print_matches_for_class(klass, grouped)
133
86
  end
134
87
  end
135
- end
136
88
 
137
- # Gather all the methods in a namespace that pass the given block.
138
- #
139
- # @param [Module] namespace The namespace in which to search.
140
- # @yieldparam [Method] method The method to test
141
- # @yieldreturn [Boolean]
142
- # @return [Array<Method>]
143
- #
144
- def search_all_methods(namespace)
145
- done = Hash.new { |h,k| h[k] = {} }
146
- matches = []
89
+ # Print matched methods for a class
90
+ def print_matches_for_class(klass, grouped)
91
+ output.puts bold(klass.name)
92
+ grouped[klass].each do |method|
93
+ header = method.name_with_owner
94
+ output.puts header + additional_info(header, method)
95
+ end
96
+ end
147
97
 
148
- recurse_namespace(namespace) do |klass|
149
- (Pry::Method.all_from_class(klass) + Pry::Method.all_from_obj(klass)).each do |method|
150
- next if done[method.owner][method.name]
98
+ # Return the matched lines of method source if `-c` is given or ""
99
+ # if `-c` was not given
100
+ def additional_info(header, method)
101
+ if opts.content?
102
+ ': ' + colorize_code(matched_method_lines(header, method))
103
+ else
104
+ ""
105
+ end
106
+ end
151
107
 
152
- done[method.owner][method.name] = true
108
+ def matched_method_lines(header, method)
109
+ method.source.split(/\n/).select { |x| x =~ pattern }.join(
110
+ "\n#{' ' * header.length}"
111
+ )
112
+ end
153
113
 
154
- matches << method if yield method
114
+ # Run the given block against every constant in the provided namespace.
115
+ #
116
+ # @param [Module] klass The namespace in which to start the search.
117
+ # @param [Hash<Module,Boolean>] done The namespaces we've already visited (private)
118
+ # @yieldparam klass Each class/module in the namespace.
119
+ #
120
+ def recurse_namespace(klass, done = {}, &block)
121
+ return if !klass.is_a?(Module) || done[klass]
122
+
123
+ done[klass] = true
124
+
125
+ yield klass
126
+
127
+ klass.constants.each do |name|
128
+ next if klass.autoload?(name)
129
+
130
+ begin
131
+ const = klass.const_get(name)
132
+ rescue RescuableException # rubocop:disable Lint/HandleExceptions
133
+ # constant loading is an inexact science at the best of times,
134
+ # this often happens when a constant was .autoload? but someone
135
+ # tried to load it. It's now not .autoload? but will still raise
136
+ # a NameError when you access it.
137
+ else
138
+ recurse_namespace(const, done, &block)
139
+ end
155
140
  end
156
141
  end
157
142
 
158
- matches
159
- end
143
+ # Gather all the methods in a namespace that pass the given block.
144
+ #
145
+ # @param [Module] namespace The namespace in which to search.
146
+ # @yieldparam [Method] method The method to test
147
+ # @yieldreturn [Boolean]
148
+ # @return [Array<Method>]
149
+ #
150
+ def search_all_methods(namespace)
151
+ done = Hash.new { |h, k| h[k] = {} }
152
+ matches = []
153
+
154
+ recurse_namespace(namespace) do |klass|
155
+ methods = Pry::Method.all_from_class(klass) + Pry::Method.all_from_obj(klass)
156
+ methods.each do |method|
157
+ next if done[method.owner][method.name]
158
+
159
+ done[method.owner][method.name] = true
160
+
161
+ matches << method if yield method
162
+ end
163
+ end
160
164
 
161
- # Search for all methods with a name that matches the given regex
162
- # within a namespace.
163
- #
164
- # @param [Module] namespace The namespace to search
165
- # @return [Array<Method>]
166
- #
167
- def name_search(namespace)
168
- search_all_methods(namespace) do |meth|
169
- meth.name =~ pattern
165
+ matches
166
+ end
167
+
168
+ # Search for all methods with a name that matches the given regex
169
+ # within a namespace.
170
+ #
171
+ # @param [Module] namespace The namespace to search
172
+ # @return [Array<Method>]
173
+ #
174
+ def name_search(namespace)
175
+ search_all_methods(namespace) do |meth|
176
+ meth.name =~ pattern
177
+ end
170
178
  end
171
- end
172
179
 
173
- # Search for all methods who's implementation matches the given regex
174
- # within a namespace.
175
- #
176
- # @param [Module] namespace The namespace to search
177
- # @return [Array<Method>]
178
- #
179
- def content_search(namespace)
180
- search_all_methods(namespace) do |meth|
181
- begin
182
- meth.source =~ pattern
183
- rescue RescuableException
184
- false
180
+ # Search for all methods who's implementation matches the given regex
181
+ # within a namespace.
182
+ #
183
+ # @param [Module] namespace The namespace to search
184
+ # @return [Array<Method>]
185
+ #
186
+ def content_search(namespace)
187
+ search_all_methods(namespace) do |meth|
188
+ begin
189
+ meth.source =~ pattern
190
+ rescue RescuableException
191
+ false
192
+ end
185
193
  end
186
194
  end
187
195
  end
188
- end
189
196
 
190
- Pry::Commands.add_command(Pry::Command::FindMethod)
197
+ Pry::Commands.add_command(Pry::Command::FindMethod)
198
+ end
191
199
  end