pry 0.10.0.pre2-universal-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -0,0 +1,32 @@
1
+ class Pry
2
+ # N.B. using a regular expresion here so that "raise-up 'foo'" does the right thing.
3
+ class Command::RaiseUp < Pry::ClassCommand
4
+ match(/raise-up(!?\b.*)/)
5
+ group 'Context'
6
+ description 'Raise an exception out of the current pry instance.'
7
+ command_options :listing => 'raise-up'
8
+
9
+ banner <<-BANNER
10
+ Raise up, like exit, allows you to quit pry. Instead of returning a value
11
+ however, it raises an exception. If you don't provide the exception to be
12
+ raised, it will use the most recent exception (in pry `_ex_`).
13
+
14
+ When called as raise-up! (with an exclamation mark), this command raises the
15
+ exception through any nested prys you have created by "cd"ing into objects.
16
+
17
+ raise-up "get-me-out-of-here"
18
+
19
+ # This is equivalent to the command above.
20
+ raise "get-me-out-of-here"
21
+ raise-up
22
+ BANNER
23
+
24
+ def process
25
+ return _pry.pager.page help if captures[0] =~ /(-h|--help)\b/
26
+ # Handle 'raise-up', 'raise-up "foo"', 'raise-up RuntimeError, 'farble' in a rubyesque manner
27
+ target.eval("_pry_.raise_up#{captures[0]}")
28
+ end
29
+ end
30
+
31
+ Pry::Commands.add_command(Pry::Command::RaiseUp)
32
+ end
@@ -0,0 +1,62 @@
1
+ class Pry
2
+ class Command::ReloadCode < Pry::ClassCommand
3
+ match 'reload-code'
4
+ group 'Misc'
5
+ description 'Reload the source file that contains the specified code object.'
6
+
7
+ banner <<-'BANNER'
8
+ Reload the source file that contains the specified code object.
9
+
10
+ e.g reload-code MyClass#my_method #=> reload a method
11
+ reload-code MyClass #=> reload a class
12
+ reload-code my-command #=> reload a pry command
13
+ reload-code self #=> reload the current object
14
+ reload-code #=> reload the current file or object
15
+ BANNER
16
+
17
+ def process
18
+ if !args.empty?
19
+ reload_object(args.join(" "))
20
+ elsif internal_binding?(target)
21
+ reload_object("self")
22
+ else
23
+ reload_current_file
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def current_file
30
+ File.expand_path target.eval("__FILE__")
31
+ end
32
+
33
+ def reload_current_file
34
+ if !File.exists?(current_file)
35
+ raise CommandError, "Current file: #{current_file} cannot be found on disk!"
36
+ end
37
+
38
+ load current_file
39
+ output.puts "The current file: #{current_file} was reloaded!"
40
+ end
41
+
42
+ def reload_object(identifier)
43
+ code_object = Pry::CodeObject.lookup(identifier, _pry_)
44
+ check_for_reloadability(code_object, identifier)
45
+ load code_object.source_file
46
+ output.puts "#{identifier} was reloaded!"
47
+ end
48
+
49
+ def check_for_reloadability(code_object, identifier)
50
+ if !code_object || !code_object.source_file
51
+ raise CommandError, "Cannot locate #{identifier}!"
52
+ elsif !File.exists?(code_object.source_file)
53
+ raise CommandError,
54
+ "Cannot reload #{identifier} as it has no associated file on disk. " \
55
+ "File found was: #{code_object.source_file}"
56
+ end
57
+ end
58
+ end
59
+
60
+ Pry::Commands.add_command(Pry::Command::ReloadCode)
61
+ Pry::Commands.alias_command 'reload-method', 'reload-code'
62
+ end
@@ -0,0 +1,18 @@
1
+ class Pry
2
+ class Command::Reset < Pry::ClassCommand
3
+ match 'reset'
4
+ group 'Context'
5
+ description 'Reset the REPL to a clean state.'
6
+
7
+ banner <<-'BANNER'
8
+ Reset the REPL to a clean state.
9
+ BANNER
10
+
11
+ def process
12
+ output.puts 'Pry reset.'
13
+ exec 'pry'
14
+ end
15
+ end
16
+
17
+ Pry::Commands.add_command(Pry::Command::Reset)
18
+ end
@@ -0,0 +1,60 @@
1
+ class Pry
2
+ class Command::Ri < Pry::ClassCommand
3
+ match 'ri'
4
+ group 'Introspection'
5
+ description 'View ri documentation.'
6
+
7
+ banner <<-'BANNER'
8
+ Usage: ri [spec]
9
+
10
+ View ri documentation. Relies on the "rdoc" gem being installed.
11
+ See also "show-doc" command.
12
+
13
+ ri Array#each
14
+ BANNER
15
+
16
+ def process(spec)
17
+ # Lazily load RI
18
+ require 'rdoc/ri/driver'
19
+
20
+ unless defined? RDoc::RI::PryDriver
21
+
22
+ # Subclass RI so that it formats its output nicely, and uses `lesspipe`.
23
+ subclass = Class.new(RDoc::RI::Driver) # the hard way.
24
+
25
+ subclass.class_eval do
26
+ def initialize(pager, opts)
27
+ @pager = pager
28
+ super opts
29
+ end
30
+ def page
31
+ paging_text = StringIO.new
32
+ yield paging_text
33
+ @pager.page(paging_text.string)
34
+ end
35
+
36
+ def formatter(io)
37
+ if @formatter_klass
38
+ @formatter_klass.new
39
+ else
40
+ RDoc::Markup::ToAnsi.new
41
+ end
42
+ end
43
+ end
44
+
45
+ RDoc::RI.const_set :PryDriver, subclass # hook it up!
46
+ end
47
+
48
+ # Spin-up an RI insance.
49
+ ri = RDoc::RI::PryDriver.new _pry_.pager, :use_stdout => true, :interactive => false
50
+
51
+ begin
52
+ ri.display_names [spec] # Get the documentation (finally!)
53
+ rescue RDoc::RI::Driver::NotFoundError => e
54
+ output.puts "error: '#{e.name}' not found"
55
+ end
56
+ end
57
+ end
58
+
59
+ Pry::Commands.add_command(Pry::Command::Ri)
60
+ end
@@ -0,0 +1,61 @@
1
+ require 'pry/commands/code_collector'
2
+
3
+ class Pry
4
+ class Command::SaveFile < Pry::ClassCommand
5
+ match 'save-file'
6
+ group 'Input and Output'
7
+ description 'Export to a file using content from the REPL.'
8
+
9
+ banner <<-'BANNER'
10
+ Usage: save-file [OPTIONS] --to [FILE]
11
+
12
+ Export to a file using content from the REPL.
13
+
14
+ save-file my_method --to hello.rb
15
+ save-file -i 1..10 --to hello.rb --append
16
+ save-file show-method --to my_command.rb
17
+ save-file sample_file.rb --lines 2..10 --to output_file.rb
18
+ BANNER
19
+
20
+ def options(opt)
21
+ CodeCollector.inject_options(opt)
22
+
23
+ opt.on :to=, "Specify the output file path"
24
+ opt.on :a, :append, "Append output to file"
25
+ end
26
+
27
+ def process
28
+ @cc = CodeCollector.new(args, opts, _pry_)
29
+ raise CommandError, "Found no code to save." if @cc.content.empty?
30
+
31
+ if !file_name
32
+ display_content
33
+ else
34
+ save_file
35
+ end
36
+ end
37
+
38
+ def file_name
39
+ opts[:to] || nil
40
+ end
41
+
42
+ def save_file
43
+ File.open(file_name, mode) do |f|
44
+ f.puts @cc.content
45
+ end
46
+ output.puts "#{file_name} successfully saved"
47
+ end
48
+
49
+ def display_content
50
+ output.puts @cc.content
51
+ output.puts "\n\n--\nPlease use `--to FILE` to export to a file."
52
+ output.puts "No file saved!\n--"
53
+ end
54
+
55
+ def mode
56
+ opts.present?(:append) ? "a" : "w"
57
+ end
58
+ end
59
+
60
+ Pry::Commands.add_command(Pry::Command::SaveFile)
61
+ end
@@ -0,0 +1,48 @@
1
+ class Pry
2
+ class Command::ShellCommand < Pry::ClassCommand
3
+ match(/\.(.*)/)
4
+ group 'Input and Output'
5
+ description "All text following a '.' is forwarded to the shell."
6
+ command_options :listing => '.<shell command>', :use_prefix => false,
7
+ :takes_block => true
8
+
9
+ banner <<-'BANNER'
10
+ Usage: .COMMAND_NAME
11
+
12
+ All text following a "." is forwarded to the shell.
13
+
14
+ .ls -aF
15
+ .uname
16
+ BANNER
17
+
18
+ def process(cmd)
19
+ if cmd =~ /^cd\s*(.*)/i
20
+ process_cd parse_destination($1)
21
+ else
22
+ pass_block(cmd)
23
+ if command_block
24
+ command_block.call `#{cmd}`
25
+ else
26
+ _pry_.config.system.call(output, cmd, _pry_)
27
+ end
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def parse_destination(dest)
34
+ return "~" if dest.empty?
35
+ return dest unless dest == "-"
36
+ state.old_pwd || raise(CommandError, "No prior directory available")
37
+ end
38
+
39
+ def process_cd(dest)
40
+ state.old_pwd = Dir.pwd
41
+ Dir.chdir File.expand_path(dest)
42
+ rescue Errno::ENOENT
43
+ raise CommandError, "No such directory: #{dest}"
44
+ end
45
+ end
46
+
47
+ Pry::Commands.add_command(Pry::Command::ShellCommand)
48
+ end
@@ -0,0 +1,25 @@
1
+ class Pry
2
+ class Command::ShellMode < Pry::ClassCommand
3
+ match 'shell-mode'
4
+ group 'Input and Output'
5
+ description 'Toggle shell mode. Bring in pwd prompt and file completion.'
6
+
7
+ banner <<-'BANNER'
8
+ Toggle shell mode. Bring in pwd prompt and file completion.
9
+ BANNER
10
+
11
+ def process
12
+ case _pry_.prompt
13
+ when Pry::SHELL_PROMPT
14
+ _pry_.pop_prompt
15
+ _pry_.custom_completions = _pry_.config.file_completions
16
+ else
17
+ _pry_.push_prompt Pry::SHELL_PROMPT
18
+ _pry_.custom_completions = _pry_.config.command_completions
19
+ end
20
+ end
21
+ end
22
+
23
+ Pry::Commands.add_command(Pry::Command::ShellMode)
24
+ Pry::Commands.alias_command 'file-mode', 'shell-mode'
25
+ end
@@ -0,0 +1,83 @@
1
+ require 'pry/commands/show_info'
2
+
3
+ class Pry
4
+ class Command::ShowDoc < Command::ShowInfo
5
+ include Pry::Helpers::DocumentationHelpers
6
+
7
+ match 'show-doc'
8
+ group 'Introspection'
9
+ description 'Show the documentation for a method or class.'
10
+
11
+ banner <<-BANNER
12
+ Usage: show-doc [OPTIONS] [METH]
13
+ Aliases: ?
14
+
15
+ Show the documentation for a method or class. Tries instance methods first and
16
+ then methods by default.
17
+
18
+ show-doc hi_method # docs for hi_method
19
+ show-doc Pry # for Pry class
20
+ show-doc Pry -a # for all definitions of Pry class (all monkey patches)
21
+ BANNER
22
+
23
+ # The docs for code_object prepared for display.
24
+ def content_for(code_object)
25
+ Code.new(render_doc_markup_for(code_object),
26
+ start_line_for(code_object), :text).
27
+ with_line_numbers(use_line_numbers?).to_s
28
+ end
29
+
30
+ # process the markup (if necessary) and apply colors
31
+ def render_doc_markup_for(code_object)
32
+ docs = docs_for(code_object)
33
+
34
+ if code_object.command?
35
+ # command '--help' shouldn't use markup highlighting
36
+ docs
37
+ else
38
+ if docs.empty?
39
+ raise CommandError, "No docs found for: #{
40
+ obj_name ? obj_name : 'current context'
41
+ }"
42
+ end
43
+ process_comment_markup(docs)
44
+ end
45
+ end
46
+
47
+ # Return docs for the code_object, adjusting for whether the code_object
48
+ # has yard docs available, in which case it returns those.
49
+ # (note we only have to check yard docs for modules since they can
50
+ # have multiple docs, but methods can only be doc'd once so we
51
+ # dont need to check them)
52
+ def docs_for(code_object)
53
+ if code_object.module_with_yard_docs?
54
+ # yard docs
55
+ code_object.yard_doc
56
+ else
57
+ # normal docs (i.e comments above method/module/command)
58
+ code_object.doc
59
+ end
60
+ end
61
+
62
+ # Which sections to include in the 'header', can toggle: :owner,
63
+ # :signature and visibility.
64
+ def header_options
65
+ super.merge :signature => true
66
+ end
67
+
68
+ # figure out start line of docs by back-calculating based on
69
+ # number of lines in the comment and the start line of the code_object
70
+ # @return [Fixnum] start line of docs
71
+ def start_line_for(code_object)
72
+ if code_object.command? || opts.present?(:'base-one')
73
+ 1
74
+ else
75
+ code_object.source_line.nil? ? 1 :
76
+ (code_object.source_line - code_object.doc.lines.count)
77
+ end
78
+ end
79
+ end
80
+
81
+ Pry::Commands.add_command(Pry::Command::ShowDoc)
82
+ Pry::Commands.alias_command '?', 'show-doc'
83
+ end
@@ -0,0 +1,195 @@
1
+ class Pry
2
+ class Command::ShowInfo < Pry::ClassCommand
3
+ extend Pry::Helpers::BaseHelpers
4
+
5
+ command_options :shellwords => false, :interpolate => false
6
+
7
+ def options(opt)
8
+ opt.on :s, :super, "Select the 'super' method. Can be repeated to traverse the ancestors", :as => :count
9
+ opt.on :l, "line-numbers", "Show line numbers"
10
+ opt.on :b, "base-one", "Show line numbers but start numbering at 1 (useful for `amend-line` and `play` commands)"
11
+ opt.on :a, :all, "Show all definitions and monkeypatches of the module/class"
12
+ end
13
+
14
+ def process
15
+ code_object = Pry::CodeObject.lookup(obj_name, _pry_, :super => opts[:super])
16
+ raise CommandError, no_definition_message if !code_object
17
+ @original_code_object = code_object
18
+
19
+ if show_all_modules?(code_object)
20
+ # show all monkey patches for a module
21
+
22
+ result = content_and_headers_for_all_module_candidates(code_object)
23
+ else
24
+ # show a specific code object
25
+ co = code_object_with_accessible_source(code_object)
26
+ result = content_and_header_for_code_object(co)
27
+ end
28
+
29
+ set_file_and_dir_locals(code_object.source_file)
30
+ _pry_.pager.page result
31
+ end
32
+
33
+ # This method checks whether the `code_object` is a WrappedModule,
34
+ # if it is, then it returns the first candidate (monkeypatch) with
35
+ # accessible source (or docs). If `code_object` is not a WrappedModule (i.e a
36
+ # method or a command) then the `code_object` itself is just
37
+ # returned.
38
+ #
39
+ # @return [Pry::WrappedModule, Pry::Method, Pry::Command]
40
+ def code_object_with_accessible_source(code_object)
41
+ if code_object.is_a?(WrappedModule)
42
+ candidate = code_object.candidates.find(&:source)
43
+ if candidate
44
+ return candidate
45
+ else
46
+ raise CommandError, no_definition_message if !valid_superclass?(code_object)
47
+
48
+ @used_super = true
49
+ code_object_with_accessible_source(code_object.super)
50
+ end
51
+ else
52
+ code_object
53
+ end
54
+ end
55
+
56
+ def valid_superclass?(code_object)
57
+ code_object.super && code_object.super.wrapped != Object
58
+ end
59
+
60
+ def content_and_header_for_code_object(code_object)
61
+ header(code_object) << content_for(code_object)
62
+ end
63
+
64
+ def content_and_headers_for_all_module_candidates(mod)
65
+ result = "Found #{mod.number_of_candidates} candidates for `#{mod.name}` definition:\n"
66
+ mod.number_of_candidates.times do |v|
67
+ candidate = mod.candidate(v)
68
+ begin
69
+ result << "\nCandidate #{v+1}/#{mod.number_of_candidates}: #{candidate.source_file} @ line #{candidate.source_line}:\n"
70
+ content = content_for(candidate)
71
+
72
+ result << "Number of lines: #{content.lines.count}\n\n" << content
73
+ rescue Pry::RescuableException
74
+ result << "\nNo content found.\n"
75
+ next
76
+ end
77
+ end
78
+ result
79
+ end
80
+
81
+ def no_definition_message
82
+ "Couldn't locate a definition for #{obj_name}!"
83
+ end
84
+
85
+ # Generate a header (meta-data information) for all the code
86
+ # object types: methods, modules, commands, procs...
87
+ def header(code_object)
88
+ file_name, line_num = file_and_line_for(code_object)
89
+ h = "\n#{Pry::Helpers::Text.bold('From:')} #{file_name} "
90
+ h << code_object_header(code_object, line_num)
91
+ h << "\n#{Pry::Helpers::Text.bold('Number of lines:')} " <<
92
+ "#{content_for(code_object).lines.count}\n\n"
93
+ h << Helpers::Text.bold('** Warning:') << " Cannot find code for #{@original_code_object.nonblank_name}. Showing superclass #{code_object.nonblank_name} instead. **\n\n" if @used_super
94
+ h
95
+ end
96
+
97
+ def code_object_header(code_object, line_num)
98
+ if code_object.real_method_object?
99
+ method_header(code_object, line_num)
100
+
101
+ # It sucks we have to test for both Pry::WrappedModule and WrappedModule::Candidate,
102
+ # probably indicates a deep refactor needs to happen in those classes.
103
+ elsif code_object.is_a?(Pry::WrappedModule) || code_object.is_a?(Pry::WrappedModule::Candidate)
104
+ module_header(code_object, line_num)
105
+ else
106
+ ""
107
+ end
108
+ end
109
+
110
+ def method_header(code_object, line_num)
111
+ h = ""
112
+ h << (code_object.c_method? ? "(C Method):" : "@ line #{line_num}:")
113
+ h << method_sections(code_object)[:owner]
114
+ h << method_sections(code_object)[:visibility]
115
+ h << method_sections(code_object)[:signature]
116
+ h
117
+ end
118
+
119
+ def module_header(code_object, line_num)
120
+ h = ""
121
+ h << "@ line #{line_num}:\n"
122
+ h << text.bold(code_object.module? ? "Module" : "Class")
123
+ h << " #{text.bold('name:')} #{code_object.nonblank_name}"
124
+
125
+ if code_object.number_of_candidates > 1
126
+ h << (text.bold("\nNumber of monkeypatches: ") << code_object.number_of_candidates.to_s)
127
+ h << ". Use the `-a` option to display all available monkeypatches"
128
+ end
129
+ h
130
+ end
131
+
132
+ def method_sections(code_object)
133
+ {
134
+ :owner => "\n#{text.bold("Owner:")} #{code_object.owner || "N/A"}\n",
135
+ :visibility => "#{text.bold("Visibility:")} #{code_object.visibility}",
136
+ :signature => "\n#{text.bold("Signature:")} #{code_object.signature}"
137
+ }.merge(header_options) { |key, old, new| (new && old).to_s }
138
+ end
139
+
140
+ def header_options
141
+ {
142
+ :owner => true,
143
+ :visibility => true,
144
+ :signature => nil
145
+ }
146
+ end
147
+
148
+ def show_all_modules?(code_object)
149
+ code_object.is_a?(Pry::WrappedModule) && opts.present?(:all)
150
+ end
151
+
152
+ def obj_name
153
+ @obj_name ||= args.empty? ? nil : args.join(' ')
154
+ end
155
+
156
+ def use_line_numbers?
157
+ opts.present?(:b) || opts.present?(:l)
158
+ end
159
+
160
+ def start_line_for(code_object)
161
+ if opts.present?(:'base-one')
162
+ 1
163
+ else
164
+ code_object.source_line || 1
165
+ end
166
+ end
167
+
168
+ # takes into account possible yard docs, and returns yard_file / yard_line
169
+ # Also adjusts for start line of comments (using start_line_for), which it has to infer
170
+ # by subtracting number of lines of comment from start line of code_object
171
+ def file_and_line_for(code_object)
172
+ if code_object.module_with_yard_docs?
173
+ [code_object.yard_file, code_object.yard_line]
174
+ else
175
+ [code_object.source_file, start_line_for(code_object)]
176
+ end
177
+ end
178
+
179
+ def complete(input)
180
+ if input =~ /([^ ]*)#([a-z0-9_]*)\z/
181
+ prefix, search = [$1, $2]
182
+ methods = begin
183
+ Pry::Method.all_from_class(binding.eval(prefix))
184
+ rescue RescuableException
185
+ return super
186
+ end
187
+ methods.map do |method|
188
+ [prefix, method.name].join('#') if method.name.start_with?(search)
189
+ end.compact
190
+ else
191
+ super
192
+ end
193
+ end
194
+ end
195
+ end