pry 0.10.2-i386-mingw32 → 1.0.0.pre1-i386-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 (189) hide show
  1. data/.document +2 -0
  2. data/.gitignore +16 -0
  3. data/.travis.yml +21 -0
  4. data/.yardopts +3 -0
  5. data/CHANGELOG +503 -0
  6. data/CONTRIBUTORS +55 -0
  7. data/Gemfile +9 -0
  8. data/Guardfile +62 -0
  9. data/LICENSE +2 -2
  10. data/{README.md → README.markdown} +31 -37
  11. data/Rakefile +144 -0
  12. data/TODO +117 -0
  13. data/lib/pry.rb +146 -33
  14. data/lib/pry/cli.rb +13 -35
  15. data/lib/pry/code.rb +63 -24
  16. data/lib/pry/code/loc.rb +2 -2
  17. data/lib/pry/code_object.rb +21 -40
  18. data/lib/pry/command.rb +6 -9
  19. data/lib/pry/command_set.rb +37 -80
  20. data/lib/pry/commands.rb +1 -1
  21. data/lib/pry/commands/amend_line.rb +1 -1
  22. data/lib/pry/commands/bang.rb +1 -1
  23. data/lib/pry/commands/cat.rb +2 -11
  24. data/lib/pry/commands/cat/abstract_formatter.rb +1 -1
  25. data/lib/pry/commands/cat/exception_formatter.rb +7 -6
  26. data/lib/pry/commands/cat/file_formatter.rb +32 -15
  27. data/lib/pry/commands/cat/input_expression_formatter.rb +1 -1
  28. data/lib/pry/commands/cd.rb +3 -14
  29. data/lib/pry/commands/code_collector.rb +4 -4
  30. data/lib/pry/commands/easter_eggs.rb +3 -3
  31. data/lib/pry/commands/edit.rb +22 -10
  32. data/lib/pry/commands/edit/exception_patcher.rb +1 -1
  33. data/lib/pry/commands/edit/file_and_line_locator.rb +2 -0
  34. data/lib/pry/{method/patcher.rb → commands/edit/method_patcher.rb} +37 -40
  35. data/lib/pry/commands/find_method.rb +22 -16
  36. data/lib/pry/commands/gem_install.rb +2 -5
  37. data/lib/pry/commands/gem_open.rb +1 -1
  38. data/lib/pry/commands/gist.rb +11 -10
  39. data/lib/pry/commands/help.rb +14 -14
  40. data/lib/pry/commands/hist.rb +5 -24
  41. data/lib/pry/commands/ls.rb +287 -56
  42. data/lib/pry/commands/play.rb +10 -44
  43. data/lib/pry/commands/pry_backtrace.rb +2 -1
  44. data/lib/pry/commands/raise_up.rb +1 -1
  45. data/lib/pry/commands/reload_code.rb +15 -31
  46. data/lib/pry/commands/ri.rb +3 -7
  47. data/lib/pry/commands/shell_command.rb +12 -17
  48. data/lib/pry/commands/shell_mode.rb +2 -2
  49. data/lib/pry/commands/show_doc.rb +0 -5
  50. data/lib/pry/commands/show_info.rb +10 -11
  51. data/lib/pry/commands/show_source.rb +3 -15
  52. data/lib/pry/commands/simple_prompt.rb +1 -1
  53. data/lib/pry/commands/toggle_color.rb +4 -8
  54. data/lib/pry/commands/whereami.rb +10 -18
  55. data/lib/pry/completion.rb +293 -0
  56. data/lib/pry/config.rb +233 -20
  57. data/lib/pry/core_extensions.rb +19 -29
  58. data/lib/pry/custom_completions.rb +6 -0
  59. data/lib/pry/editor.rb +103 -109
  60. data/lib/pry/helpers/base_helpers.rb +109 -22
  61. data/lib/pry/helpers/command_helpers.rb +8 -10
  62. data/lib/pry/helpers/documentation_helpers.rb +2 -1
  63. data/lib/pry/helpers/text.rb +5 -4
  64. data/lib/pry/history.rb +10 -21
  65. data/lib/pry/history_array.rb +0 -5
  66. data/lib/pry/hooks.rb +29 -9
  67. data/lib/pry/indent.rb +10 -5
  68. data/lib/pry/method.rb +86 -81
  69. data/lib/pry/method/weird_method_locator.rb +2 -4
  70. data/lib/pry/module_candidate.rb +14 -5
  71. data/lib/pry/pager.rb +48 -193
  72. data/lib/pry/plugins.rb +2 -2
  73. data/lib/pry/pry_class.rb +193 -104
  74. data/lib/pry/pry_instance.rb +154 -152
  75. data/lib/pry/rbx_method.rb +13 -0
  76. data/lib/pry/rbx_path.rb +1 -1
  77. data/lib/pry/repl.rb +14 -17
  78. data/lib/pry/repl_file_loader.rb +3 -8
  79. data/lib/pry/rubygem.rb +3 -3
  80. data/lib/pry/terminal.rb +3 -4
  81. data/lib/pry/test/helper.rb +11 -6
  82. data/lib/pry/version.rb +1 -1
  83. data/lib/pry/wrapped_module.rb +56 -49
  84. data/man/pry.1 +195 -0
  85. data/man/pry.1.html +204 -0
  86. data/man/pry.1.ronn +141 -0
  87. data/pry.gemspec +31 -0
  88. data/spec/Procfile +3 -0
  89. data/spec/cli_spec.rb +78 -0
  90. data/spec/code_object_spec.rb +277 -0
  91. data/spec/code_spec.rb +219 -0
  92. data/spec/command_helpers_spec.rb +29 -0
  93. data/spec/command_integration_spec.rb +562 -0
  94. data/spec/command_set_spec.rb +627 -0
  95. data/spec/command_spec.rb +821 -0
  96. data/spec/commands/amend_line_spec.rb +247 -0
  97. data/spec/commands/bang_spec.rb +18 -0
  98. data/spec/commands/cat_spec.rb +164 -0
  99. data/spec/commands/cd_spec.rb +250 -0
  100. data/spec/commands/disable_pry_spec.rb +25 -0
  101. data/spec/commands/edit_spec.rb +725 -0
  102. data/spec/commands/exit_all_spec.rb +27 -0
  103. data/spec/commands/exit_program_spec.rb +19 -0
  104. data/spec/commands/exit_spec.rb +28 -0
  105. data/spec/commands/find_method_spec.rb +70 -0
  106. data/spec/commands/gem_list_spec.rb +26 -0
  107. data/spec/commands/gist_spec.rb +79 -0
  108. data/spec/commands/help_spec.rb +56 -0
  109. data/spec/commands/hist_spec.rb +172 -0
  110. data/spec/commands/jump_to_spec.rb +15 -0
  111. data/spec/commands/ls_spec.rb +189 -0
  112. data/spec/commands/play_spec.rb +136 -0
  113. data/spec/commands/raise_up_spec.rb +56 -0
  114. data/spec/commands/save_file_spec.rb +177 -0
  115. data/spec/commands/show_doc_spec.rb +488 -0
  116. data/spec/commands/show_input_spec.rb +17 -0
  117. data/spec/commands/show_source_spec.rb +760 -0
  118. data/spec/commands/whereami_spec.rb +203 -0
  119. data/spec/completion_spec.rb +221 -0
  120. data/spec/control_d_handler_spec.rb +62 -0
  121. data/spec/documentation_helper_spec.rb +73 -0
  122. data/spec/editor_spec.rb +79 -0
  123. data/spec/exception_whitelist_spec.rb +21 -0
  124. data/spec/fixtures/candidate_helper1.rb +11 -0
  125. data/spec/fixtures/candidate_helper2.rb +8 -0
  126. data/spec/fixtures/example.erb +5 -0
  127. data/spec/fixtures/example_nesting.rb +33 -0
  128. data/spec/fixtures/show_source_doc_examples.rb +15 -0
  129. data/spec/fixtures/testlinkrc +2 -0
  130. data/spec/fixtures/testrc +2 -0
  131. data/spec/fixtures/testrcbad +2 -0
  132. data/spec/fixtures/whereami_helper.rb +6 -0
  133. data/spec/helper.rb +35 -0
  134. data/spec/helpers/bacon.rb +86 -0
  135. data/spec/helpers/mock_pry.rb +44 -0
  136. data/spec/helpers/repl_tester.rb +112 -0
  137. data/spec/helpers/table_spec.rb +105 -0
  138. data/spec/history_array_spec.rb +67 -0
  139. data/spec/hooks_spec.rb +522 -0
  140. data/spec/indent_spec.rb +301 -0
  141. data/spec/method_spec.rb +482 -0
  142. data/spec/prompt_spec.rb +61 -0
  143. data/spec/pry_defaults_spec.rb +420 -0
  144. data/spec/pry_history_spec.rb +69 -0
  145. data/spec/pry_output_spec.rb +95 -0
  146. data/spec/pry_repl_spec.rb +86 -0
  147. data/spec/pry_spec.rb +394 -0
  148. data/spec/pryrc_spec.rb +97 -0
  149. data/spec/run_command_spec.rb +25 -0
  150. data/spec/sticky_locals_spec.rb +147 -0
  151. data/spec/syntax_checking_spec.rb +81 -0
  152. data/spec/wrapped_module_spec.rb +261 -0
  153. data/wiki/Customizing-pry.md +397 -0
  154. data/wiki/Home.md +4 -0
  155. metadata +272 -61
  156. checksums.yaml +0 -7
  157. data/CHANGELOG.md +0 -714
  158. data/lib/pry/code/code_file.rb +0 -103
  159. data/lib/pry/color_printer.rb +0 -55
  160. data/lib/pry/commands/change_inspector.rb +0 -27
  161. data/lib/pry/commands/change_prompt.rb +0 -26
  162. data/lib/pry/commands/list_inspectors.rb +0 -35
  163. data/lib/pry/commands/list_prompts.rb +0 -35
  164. data/lib/pry/commands/ls/constants.rb +0 -47
  165. data/lib/pry/commands/ls/formatter.rb +0 -49
  166. data/lib/pry/commands/ls/globals.rb +0 -48
  167. data/lib/pry/commands/ls/grep.rb +0 -21
  168. data/lib/pry/commands/ls/instance_vars.rb +0 -39
  169. data/lib/pry/commands/ls/interrogatable.rb +0 -18
  170. data/lib/pry/commands/ls/jruby_hacks.rb +0 -49
  171. data/lib/pry/commands/ls/local_names.rb +0 -35
  172. data/lib/pry/commands/ls/local_vars.rb +0 -39
  173. data/lib/pry/commands/ls/ls_entity.rb +0 -70
  174. data/lib/pry/commands/ls/methods.rb +0 -57
  175. data/lib/pry/commands/ls/methods_helper.rb +0 -46
  176. data/lib/pry/commands/ls/self_methods.rb +0 -32
  177. data/lib/pry/commands/watch_expression.rb +0 -105
  178. data/lib/pry/commands/watch_expression/expression.rb +0 -38
  179. data/lib/pry/config/behavior.rb +0 -139
  180. data/lib/pry/config/convenience.rb +0 -25
  181. data/lib/pry/config/default.rb +0 -161
  182. data/lib/pry/exceptions.rb +0 -78
  183. data/lib/pry/input_completer.rb +0 -242
  184. data/lib/pry/input_lock.rb +0 -132
  185. data/lib/pry/inspector.rb +0 -27
  186. data/lib/pry/last_exception.rb +0 -61
  187. data/lib/pry/object_path.rb +0 -82
  188. data/lib/pry/output.rb +0 -50
  189. data/lib/pry/prompt.rb +0 -26
@@ -6,6 +6,8 @@ class Pry
6
6
  group 'Context'
7
7
  description 'Recursively search for a method within a Class/Module or the current namespace.'
8
8
  command_options :shellwords => false
9
+ command_options :requires_gem => 'ruby18_source_location' if mri_18?
10
+
9
11
 
10
12
  banner <<-'BANNER'
11
13
  Usage: find-method [-n|-c] METHOD [NAMESPACE]
@@ -24,9 +26,13 @@ class Pry
24
26
  find-method -c 'output.puts' Pry
25
27
  BANNER
26
28
 
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"
29
+ def setup
30
+ require 'ruby18_source_location' if mri_18?
31
+ end
32
+
33
+ def options(opti)
34
+ opti.on :n, :name, "Search for a method by name"
35
+ opti.on :c, :content, "Search for a method based on content in Regex form"
30
36
  end
31
37
 
32
38
  def process
@@ -76,7 +82,7 @@ class Pry
76
82
 
77
83
  # pretty-print a list of matching methods.
78
84
  #
79
- # @param [Array<Method>] matches
85
+ # @param Array[Method]
80
86
  def print_matches(matches)
81
87
  grouped = matches.group_by(&:owner)
82
88
  order = grouped.keys.sort_by{ |x| x.name || x.to_s }
@@ -99,7 +105,7 @@ class Pry
99
105
  # if `-c` was not given
100
106
  def additional_info(header, method)
101
107
  if opts.content?
102
- ": " << colorize_code(matched_method_lines(header, method))
108
+ ": " + colorize_code(matched_method_lines(header, method))
103
109
  else
104
110
  ""
105
111
  end
@@ -111,9 +117,9 @@ class Pry
111
117
 
112
118
  # Run the given block against every constant in the provided namespace.
113
119
  #
114
- # @param [Module] klass The namespace in which to start the search.
115
- # @param [Hash<Module,Boolean>] done The namespaces we've already visited (private)
116
- # @yieldparam klass Each class/module in the namespace.
120
+ # @param Module The namespace in which to start the search.
121
+ # @param Hash[Module,Boolean] The namespaces we've already visited (private)
122
+ # @yieldparam klazz Each class/module in the namespace.
117
123
  #
118
124
  def recurse_namespace(klass, done={}, &block)
119
125
  return if !(Module === klass) || done[klass]
@@ -139,10 +145,10 @@ class Pry
139
145
 
140
146
  # Gather all the methods in a namespace that pass the given block.
141
147
  #
142
- # @param [Module] namespace The namespace in which to search.
143
- # @yieldparam [Method] method The method to test
144
- # @yieldreturn [Boolean]
145
- # @return [Array<Method>]
148
+ # @param Module The namespace in which to search.
149
+ # @yieldparam Method The method to test
150
+ # @yieldreturn Boolean
151
+ # @return Array[Method]
146
152
  #
147
153
  def search_all_methods(namespace)
148
154
  done = Hash.new{ |h,k| h[k] = {} }
@@ -163,8 +169,8 @@ class Pry
163
169
  # Search for all methods with a name that matches the given regex
164
170
  # within a namespace.
165
171
  #
166
- # @param [Module] namespace The namespace to search
167
- # @return [Array<Method>]
172
+ # @param Module The namespace to search
173
+ # @return Array[Method]
168
174
  #
169
175
  def name_search(namespace)
170
176
  search_all_methods(namespace) do |meth|
@@ -175,8 +181,8 @@ class Pry
175
181
  # Search for all methods who's implementation matches the given regex
176
182
  # within a namespace.
177
183
  #
178
- # @param [Module] namespace The namespace to search
179
- # @return [Array<Method>]
184
+ # @param Module The namespace to search
185
+ # @return Array[Method]
180
186
  #
181
187
  def content_search(namespace)
182
188
  search_all_methods(namespace) do |meth|
@@ -8,8 +8,8 @@ class Pry
8
8
  banner <<-'BANNER'
9
9
  Usage: gem-install GEM_NAME
10
10
 
11
- Installs the given gem, refreshes the gem cache, and requires the gem for you
12
- based on a best guess from the gem name.
11
+ Installs the given gem and refreshes the gem cache so that you can immediately
12
+ 'require GEM_FILE'.
13
13
 
14
14
  gem-install pry-stack_explorer
15
15
  BANNER
@@ -22,9 +22,6 @@ class Pry
22
22
  Rubygem.install(gem)
23
23
  output.puts "Gem `#{ text.green(gem) }` installed."
24
24
  require gem
25
- rescue LoadError
26
- require_path = gem.split('-').join('/')
27
- require require_path
28
25
  end
29
26
  end
30
27
 
@@ -2,7 +2,7 @@ class Pry
2
2
  class Command::GemOpen < Pry::ClassCommand
3
3
  match 'gem-open'
4
4
  group 'Gems'
5
- description 'Opens the working directory of the gem in your editor.'
5
+ description 'Opens the working directory of the gem in your editor'
6
6
  command_options :argument_required => true
7
7
 
8
8
  banner <<-'BANNER'
@@ -2,8 +2,8 @@ class Pry
2
2
  class Command::Gist < Pry::ClassCommand
3
3
  match 'gist'
4
4
  group 'Misc'
5
- description 'Upload code, docs, history to https://gist.github.com/.'
6
- command_options :requires_gem => "gist"
5
+ description 'Playback a string variable or a method or a file as input.'
6
+ command_options :requires_gem => "jist"
7
7
 
8
8
  banner <<-'BANNER'
9
9
  Usage: gist [OPTIONS] [--help]
@@ -16,18 +16,18 @@ class Pry
16
16
  BANNER
17
17
 
18
18
  def setup
19
- require 'gist'
19
+ require 'jist'
20
20
  end
21
21
 
22
22
  def options(opt)
23
23
  CodeCollector.inject_options(opt)
24
- opt.on :login, "Authenticate the gist gem with GitHub"
24
+ opt.on :login, "Authenticate the jist gem with GitHub"
25
25
  opt.on :p, :public, "Create a public gist (default: false)", :default => false
26
26
  opt.on :clip, "Copy the selected content to clipboard instead, do NOT gist it", :default => false
27
27
  end
28
28
 
29
29
  def process
30
- return ::Gist.login! if opts.present?(:login)
30
+ return Jist.login! if opts.present?(:login)
31
31
  cc = CodeCollector.new(args, opts, _pry_)
32
32
 
33
33
  if cc.content =~ /\A\s*\z/
@@ -45,7 +45,7 @@ class Pry
45
45
  end
46
46
 
47
47
  def clipboard_content(content)
48
- ::Gist.copy(content)
48
+ Jist.copy(content)
49
49
  output.puts "Copied content to clipboard!"
50
50
  end
51
51
 
@@ -58,7 +58,7 @@ class Pry
58
58
  if code && code != ""
59
59
  content << code
60
60
  if code !~ /;\Z/
61
- content << "#{comment_expression_result_for_gist(_pry_.config.gist.inspecter.call(_pry_.output_array[corrected_index]))}"
61
+ content << "#{comment_expression_result_for_gist(Pry.config.gist.inspecter.call(_pry_.output_array[corrected_index]))}"
62
62
  end
63
63
  end
64
64
  end
@@ -81,14 +81,14 @@ class Pry
81
81
  end
82
82
 
83
83
  def gist_content(content, filename)
84
- response = ::Gist.gist(content, :filename => filename || "pry_gist.rb", :public => !!opts[:p])
84
+ response = Jist.gist(content, :filename => filename || "pry_gist.rb", :public => !!opts[:p])
85
85
  if response
86
86
  url = response['html_url']
87
87
  message = "Gist created at URL #{url}"
88
88
  begin
89
- ::Gist.copy(url)
89
+ Jist.copy(url)
90
90
  message << ", which is now in the clipboard."
91
- rescue ::Gist::ClipboardError
91
+ rescue Jist::ClipboardError
92
92
  end
93
93
 
94
94
  output.puts message
@@ -98,4 +98,5 @@ class Pry
98
98
 
99
99
  Pry::Commands.add_command(Pry::Command::Gist)
100
100
  Pry::Commands.alias_command 'clipit', 'gist --clip'
101
+ Pry::Commands.alias_command 'jist', 'gist'
101
102
  end
@@ -2,14 +2,14 @@ class Pry
2
2
  class Command::Help < Pry::ClassCommand
3
3
  match 'help'
4
4
  group 'Help'
5
- description 'Show a list of commands or information about a specific command.'
5
+ description 'Show a list of commands or information about a specific command'
6
6
 
7
7
  banner <<-'BANNER'
8
8
  Usage: help [COMMAND]
9
9
 
10
- With no arguments, help lists all the available commands along with their
11
- descriptions. When given a command name as an argument, shows the help
12
- for that command.
10
+ With no arguments, help lists all the available commands in the current
11
+ command-set along with their description. When given a command name as an
12
+ argument, shows the help for that command.
13
13
  BANNER
14
14
 
15
15
  # We only want to show commands that have descriptions, so that the
@@ -37,7 +37,7 @@ class Pry
37
37
 
38
38
  # Display the index view, with headings and short descriptions per command.
39
39
  #
40
- # @param [Hash<String, Array<Commands>>] groups
40
+ # @param Hash[String => Array[Commands]]
41
41
  def display_index(groups)
42
42
  help_text = []
43
43
 
@@ -49,18 +49,18 @@ class Pry
49
49
  end
50
50
  end
51
51
 
52
- _pry_.pager.page help_text.join("\n\n")
52
+ stagger_output(help_text.join("\n\n"))
53
53
  end
54
54
 
55
55
  # Given a group name and an array of commands,
56
56
  # return the help string for those commands.
57
57
  #
58
58
  # @param [String] name The group name.
59
- # @param [Array<Pry::Command>] commands
59
+ # @param [Array<Pry::Command>]] commands
60
60
  # @return [String] The generated help string.
61
61
  def help_text_for_commands(name, commands)
62
- "#{text.bold(name.capitalize)}\n" << commands.map do |command|
63
- " #{command.options[:listing].to_s.ljust(18)} #{command.description.capitalize}"
62
+ "#{text.bold(name)}\n" + commands.map do |command|
63
+ " #{command.options[:listing].to_s.ljust(18)} #{command.description}"
64
64
  end.join("\n")
65
65
  end
66
66
 
@@ -121,7 +121,7 @@ class Pry
121
121
  #
122
122
  # @param [Pry::Command] command
123
123
  def display_command(command)
124
- _pry_.pager.page command.new.help
124
+ stagger_output command.new.help
125
125
  end
126
126
 
127
127
  # Find a subset of a hash that matches the user's search term.
@@ -130,8 +130,8 @@ class Pry
130
130
  # otherwise a sub-Hash with every key that matches the search will
131
131
  # be returned.
132
132
  #
133
- # @param [String] search the search term
134
- # @param [Hash] hash the hash to search
133
+ # @param [String] the search term
134
+ # @param [Hash] the hash to search
135
135
  def search_hash(search, hash)
136
136
  matching = {}
137
137
 
@@ -149,8 +149,8 @@ class Pry
149
149
 
150
150
  # Clean search terms to make it easier to search group names
151
151
  #
152
- # @param [String] key
153
- # @return [String]
152
+ # @param String
153
+ # @return String
154
154
  def normalize(key)
155
155
  key.downcase.gsub(/pry\W+/, '')
156
156
  end
@@ -6,7 +6,6 @@ class Pry
6
6
 
7
7
  banner <<-'BANNER'
8
8
  Usage: hist [--head|--tail]
9
- hist --all
10
9
  hist --head N
11
10
  hist --tail N
12
11
  hist --show START..END
@@ -20,7 +19,6 @@ class Pry
20
19
  BANNER
21
20
 
22
21
  def options(opt)
23
- opt.on :a, :all, "Display all history"
24
22
  opt.on :H, :head, "Display the first N items", :optional_argument => true, :as => Integer
25
23
  opt.on :T, :tail, "Display the last N items", :optional_argument => true, :as => Integer
26
24
  opt.on :s, :show, "Show the given range of lines", :optional_argument => true, :as => Range
@@ -30,10 +28,12 @@ class Pry
30
28
  opt.on :save, "Save history to a file", :argument => true, :as => Range
31
29
  opt.on :e, :'exclude-pry', "Exclude Pry commands from the history"
32
30
  opt.on :n, :'no-numbers', "Omit line numbers"
31
+ opt.on :f, :flood, "Do not use a pager to view text longer than one screen"
33
32
  end
34
33
 
35
34
  def process
36
- @history = find_history
35
+ # The last value in history will be the 'hist' command itself
36
+ @history = Pry::Code(Pry.history.to_a[0..-2])
37
37
 
38
38
  if opts.present?(:show)
39
39
  @history = @history.between(opts[:show])
@@ -55,9 +55,7 @@ class Pry
55
55
  end
56
56
 
57
57
  if opts.present?(:'exclude-pry')
58
- @history = @history.select do |loc|
59
- !command_set.valid_command?(loc.line)
60
- end
58
+ @history = @history.select { |l, ln| !command_set.valid_command?(l) }
61
59
  end
62
60
 
63
61
  if opts.present?(:save)
@@ -78,9 +76,7 @@ class Pry
78
76
  @history = @history.with_line_numbers
79
77
  end
80
78
 
81
- _pry_.pager.open do |pager|
82
- @history.print_to_output(pager, true)
83
- end
79
+ render_output(@history, opts)
84
80
  end
85
81
 
86
82
  def process_save
@@ -158,21 +154,6 @@ class Pry
158
154
  false
159
155
  end
160
156
  end
161
-
162
- # Finds history depending on the given switch.
163
- #
164
- # @return [Pry::Code] if it finds `--all` (or `-a`) switch, returns all
165
- # entries in history. Without the switch returns only the entries from the
166
- # current Pry session.
167
- def find_history
168
- h = if opts.present?(:all)
169
- Pry.history.to_a
170
- else
171
- Pry.history.to_a.last(Pry.history.session_line_count)
172
- end
173
- # The last value in history will be the 'hist' command itself.
174
- Pry::Code(h[0..-2])
175
- end
176
157
  end
177
158
 
178
159
  Pry::Commands.add_command(Pry::Command::Hist)
@@ -1,28 +1,5 @@
1
- require 'pry/commands/ls/ls_entity'
2
1
  class Pry
3
2
  class Command::Ls < Pry::ClassCommand
4
- DEFAULT_OPTIONS = {
5
- :heading_color => :bright_blue,
6
- :public_method_color => :default,
7
- :private_method_color => :blue,
8
- :protected_method_color => :blue,
9
- :method_missing_color => :bright_red,
10
- :local_var_color => :yellow,
11
- :pry_var_color => :default, # e.g. _, _pry_, _file_
12
- :instance_var_color => :blue, # e.g. @foo
13
- :class_var_color => :bright_blue, # e.g. @@foo
14
- :global_var_color => :default, # e.g. $CODERAY_DEBUG, $eventmachine_library
15
- :builtin_global_color => :cyan, # e.g. $stdin, $-w, $PID
16
- :pseudo_global_color => :cyan, # e.g. $~, $1..$9, $LAST_MATCH_INFO
17
- :constant_color => :default, # e.g. VERSION, ARGF
18
- :class_constant_color => :blue, # e.g. Object, Kernel
19
- :exception_constant_color => :magenta, # e.g. Exception, RuntimeError
20
- :unloaded_constant_color => :yellow, # Any constant that is still in .autoload? state
21
- :separator => " ",
22
- :ceiling => [Object, Module, Class]
23
- }
24
-
25
-
26
3
  match 'ls'
27
4
  group 'Context'
28
5
  description 'Show the list of vars and methods in the current scope.'
@@ -44,21 +21,19 @@ class Pry
44
21
  methods defined on all Objects are omitted. The -v flag can be used to ignore
45
22
  this setting and show all methods, while the -q can be used to set the ceiling
46
23
  much lower and show only methods defined on the object or its direct class.
47
-
48
- Also check out `find-method` command (run `help find-method`).
49
24
  BANNER
50
25
 
51
26
 
52
27
  def options(opt)
53
- opt.on :m, :methods, "Show public methods defined on the Object"
54
- opt.on :M, "instance-methods", "Show public methods defined in a Module or Class"
28
+ opt.on :m, :methods, "Show public methods defined on the Object (default)"
29
+ opt.on :M, "instance-methods", "Show methods defined in a Module or Class"
55
30
  opt.on :p, :ppp, "Show public, protected (in yellow) and private (in green) methods"
56
31
  opt.on :q, :quiet, "Show only methods defined on object.singleton_class and object.class"
57
32
  opt.on :v, :verbose, "Show methods and constants on all super-classes (ignores Pry.config.ls.ceiling)"
58
33
  opt.on :g, :globals, "Show global variables, including those builtin to Ruby (in cyan)"
59
34
  opt.on :l, :locals, "Show hash of local vars, sorted by descending size"
60
- opt.on :c, :constants, "Show constants, highlighting classes (in blue), and exceptions (in purple).\n" <<
61
- " " * 32 << "Constants that are pending autoload? are also shown (in yellow)"
35
+ opt.on :c, :constants, "Show constants, highlighting classes (in blue), and exceptions (in purple).\n" +
36
+ " " * 32 + "Constants that are pending autoload? are also shown (in yellow)"
62
37
  opt.on :i, :ivars, "Show instance variables (in blue) and class variables (in bright blue)"
63
38
  opt.on :G, :grep, "Filter output by regular expression", :argument => true
64
39
 
@@ -67,47 +42,303 @@ class Pry
67
42
  end
68
43
  end
69
44
 
70
- # Exclude -q, -v and --grep because they,
71
- # don't specify what the user wants to see.
72
- def no_user_opts?
73
- !(opts[:methods] || opts['instance-methods'] || opts[:ppp] ||
74
- opts[:globals] || opts[:locals] || opts[:constants] || opts[:ivars])
75
- end
45
+ attr_reader :object_to_interrogate, :has_user_specified_any_options, :grep, :grep_regex
76
46
 
77
47
  def process
78
- @interrogatee = args.empty? ? target_self : target.eval(args.join(' '))
48
+ @object_to_interrogate = args.empty? ? target_self : target.eval(args.join(" "))
49
+
50
+ # exclude -q, -v and --grep because they don't specify what the user wants to see.
51
+ @has_user_specified_any_options = (opts.present?(:methods) || opts.present?(:'instance-methods') || opts.present?(:ppp) ||
52
+ opts.present?(:globals) || opts.present?(:locals) || opts.present?(:constants) ||
53
+ opts.present?(:ivars))
54
+
55
+ @grep_regex, @grep = [Regexp.new(opts[:G] || "."), lambda{ |x| x.grep(@grep_regex) }]
56
+
79
57
  raise_errors_if_arguments_are_weird
80
- ls_entity = LsEntity.new({
81
- :interrogatee => @interrogatee,
82
- :no_user_opts => no_user_opts?,
83
- :opts => opts,
84
- :args => args,
85
- :_pry_ => _pry_
86
- })
87
58
 
88
- _pry_.pager.page ls_entity.entities_table
59
+ all_output = [
60
+ write_out_globals,
61
+ write_out_constants,
62
+ write_out_methods,
63
+ write_out_self_methods,
64
+ write_out_ivars,
65
+ write_out_local_names,
66
+ write_out_locals,
67
+ ].compact.join("")
68
+
69
+ stagger_output(all_output)
89
70
  end
90
71
 
91
72
  private
92
73
 
93
- def error_list
94
- any_args = args.any?
95
- non_mod_interrogatee = !(Module === @interrogatee)
96
- [
97
- ['-l does not make sense with a specified Object', :locals, any_args],
98
- ['-g does not make sense with a specified Object', :globals, any_args],
99
- ['-q does not make sense with -v', :quiet, opts.present?(:verbose)],
100
- ['-M only makes sense with a Module or a Class', 'instance-methods', non_mod_interrogatee],
101
- ['-c only makes sense with a Module or a Class', :constants, any_args && non_mod_interrogatee]
102
- ]
74
+ # http://ruby.runpaint.org/globals, and running "puts global_variables.inspect".
75
+ BUILTIN_GLOBALS = %w($" $$ $* $, $-0 $-F $-I $-K $-W $-a $-d $-i $-l $-p $-v $-w $. $/ $\\
76
+ $: $; $< $= $> $0 $ARGV $CONSOLE $DEBUG $DEFAULT_INPUT $DEFAULT_OUTPUT
77
+ $FIELD_SEPARATOR $FILENAME $FS $IGNORECASE $INPUT_LINE_NUMBER
78
+ $INPUT_RECORD_SEPARATOR $KCODE $LOADED_FEATURES $LOAD_PATH $NR $OFS
79
+ $ORS $OUTPUT_FIELD_SEPARATOR $OUTPUT_RECORD_SEPARATOR $PID $PROCESS_ID
80
+ $PROGRAM_NAME $RS $VERBOSE $deferr $defout $stderr $stdin $stdout)
81
+
82
+ # $SAFE and $? are thread-local, the exception stuff only works in a rescue clause,
83
+ # everything else is basically a local variable with a $ in its name.
84
+ PSEUDO_GLOBALS = %w($! $' $& $` $@ $? $+ $_ $~ $1 $2 $3 $4 $5 $6 $7 $8 $9
85
+ $CHILD_STATUS $SAFE $ERROR_INFO $ERROR_POSITION $LAST_MATCH_INFO
86
+ $LAST_PAREN_MATCH $LAST_READ_LINE $MATCH $POSTMATCH $PREMATCH)
87
+
88
+ # Get all the methods that we'll want to output
89
+ def all_methods(obj, instance_methods=false)
90
+ methods = if instance_methods || opts.present?(:'instance-methods')
91
+ Pry::Method.all_from_class(obj)
92
+ else
93
+ Pry::Method.all_from_obj(obj)
94
+ end
95
+
96
+ if jruby? && !opts.present?(:J)
97
+ methods = trim_jruby_aliases(methods)
98
+ end
99
+
100
+ methods.select{ |method| opts.present?(:ppp) || method.visibility == :public }
101
+ end
102
+
103
+ # JRuby creates lots of aliases for methods imported from java in an attempt to
104
+ # make life easier for ruby programmers.
105
+ # (e.g. getFooBar becomes get_foo_bar and foo_bar, and maybe foo_bar? if it
106
+ # returns a Boolean).
107
+ # The full transformations are in the assignAliases method of:
108
+ # https://github.com/jruby/jruby/blob/master/src/org/jruby/javasupport/JavaClass.java
109
+ #
110
+ # This has the unfortunate side-effect of making the output of ls even more
111
+ # incredibly verbose than it normally would be for these objects; and so we filter
112
+ # out all but the nicest of these aliases here.
113
+ #
114
+ # TODO: This is a little bit vague, better heuristics could be used.
115
+ # JRuby also has a lot of scala-specific logic, which we don't copy.
116
+ #
117
+ def trim_jruby_aliases(methods)
118
+ grouped = methods.group_by do |m|
119
+ m.name.sub(/\A(is|get|set)(?=[A-Z_])/, '').gsub(/[_?=]/, '').downcase
120
+ end
121
+
122
+ grouped.map do |key, values|
123
+ values = values.sort_by do |m|
124
+ rubbishness(m.name)
125
+ end
126
+
127
+ found = []
128
+ values.select do |x|
129
+ (!found.any?{ |y| x == y }) && found << x
130
+ end
131
+ end.flatten(1)
132
+ end
133
+
134
+ # When removing jruby aliases, we want to keep the alias that is "least rubbish"
135
+ # according to this metric.
136
+ def rubbishness(name)
137
+ name.each_char.map{ |x|
138
+ case x
139
+ when /[A-Z]/
140
+ 1
141
+ when '?', '=', '!'
142
+ -2
143
+ else
144
+ 0
145
+ end
146
+ }.inject(&:+) + (name.size / 100.0)
147
+ end
148
+
149
+ def resolution_order(obj)
150
+ opts.present?(:'instance-methods') ? Pry::Method.instance_resolution_order(obj) : Pry::Method.resolution_order(obj)
151
+ end
152
+
153
+ # Get a lambda that can be used with .take_while to prevent over-eager
154
+ # traversal of the Object's ancestry graph.
155
+ def below_ceiling(obj)
156
+ ceiling = if opts.present?(:quiet)
157
+ [
158
+ if opts.present?(:'instance-methods')
159
+ Pry::Method.safe_send(obj, :ancestors)[1]
160
+ else
161
+ Pry::Method.safe_send(obj.class, :ancestors)[1]
162
+ end
163
+ ] + Pry.config.ls.ceiling
164
+ elsif opts.present?(:verbose)
165
+ []
166
+ else
167
+ Pry.config.ls.ceiling.dup
168
+ end
169
+
170
+ lambda { |klass| !ceiling.include?(klass) }
103
171
  end
104
172
 
105
173
  def raise_errors_if_arguments_are_weird
106
- error_list.each do |message, option, invalid_expr|
107
- raise Pry::CommandError, message if opts.present?(option) && invalid_expr
174
+ [
175
+ ["-l does not make sense with a specified Object", :locals, !args.empty?],
176
+ ["-g does not make sense with a specified Object", :globals, !args.empty?],
177
+ ["-q does not make sense with -v", :quiet, opts.present?(:verbose)],
178
+ ["-M only makes sense with a Module or a Class", :'instance-methods', !interrogating_a_module?],
179
+ ["-c only makes sense with a Module or a Class", :constants, !args.empty? && !interrogating_a_module?],
180
+ ].each do |message, option, expression|
181
+ raise Pry::CommandError, message if opts.present?(option) && expression
182
+ end
183
+ end
184
+
185
+ def interrogating_a_module?
186
+ (Module === object_to_interrogate)
187
+ end
188
+
189
+ def write_out_globals
190
+ return unless opts.present?(:globals)
191
+
192
+ output_section("global variables", grep[format_globals(target.eval("global_variables"))])
193
+ end
194
+
195
+ def write_out_constants
196
+ return unless opts.present?(:constants) || (!has_user_specified_any_options && interrogating_a_module?)
197
+
198
+ mod = interrogating_a_module? ? object_to_interrogate : Object
199
+ constants = WrappedModule.new(mod).constants(opts.present?(:verbose))
200
+ output_section("constants", grep[format_constants(mod, constants)])
201
+ end
202
+
203
+ def write_out_methods
204
+ return unless opts.present?(:methods) || opts.present?(:'instance-methods') || opts.present?(:ppp) || !has_user_specified_any_options
205
+
206
+ # methods is a hash {Module/Class => [Pry::Methods]}
207
+ methods = all_methods(object_to_interrogate).group_by(&:owner)
208
+
209
+ output = ""
210
+ # reverse the resolution order so that the most useful information appears right by the prompt
211
+ resolution_order(object_to_interrogate).take_while(&below_ceiling(object_to_interrogate)).reverse.each do |klass|
212
+ methods_here = format_methods((methods[klass] || []).select{ |m| m.name =~ grep_regex })
213
+ output << output_section("#{Pry::WrappedModule.new(klass).method_prefix}methods", methods_here)
214
+ end
215
+ output
216
+ end
217
+
218
+ def write_out_self_methods
219
+ return unless (!has_user_specified_any_options && interrogating_a_module?)
220
+
221
+ methods = all_methods(object_to_interrogate, true).select{ |m| m.owner == object_to_interrogate && m.name =~ grep_regex }
222
+ output_section("#{Pry::WrappedModule.new(object_to_interrogate).method_prefix}methods", format_methods(methods))
223
+ end
224
+
225
+ def write_out_ivars
226
+ return unless opts.present?(:ivars) || !has_user_specified_any_options
227
+
228
+ klass = (interrogating_a_module? ? object_to_interrogate : object_to_interrogate.class)
229
+ ivars = Pry::Method.safe_send(object_to_interrogate, :instance_variables)
230
+ kvars = Pry::Method.safe_send(klass, :class_variables)
231
+ output_section("instance variables", format_variables(:instance_var, ivars)) +
232
+ output_section("class variables", format_variables(:class_var, kvars))
233
+ end
234
+
235
+ def write_out_local_names
236
+ return unless !has_user_specified_any_options && args.empty?
237
+
238
+ output_section("locals", format_local_names(grep[target.eval("local_variables")]))
239
+ end
240
+
241
+ def write_out_locals
242
+ return unless opts.present?(:locals)
243
+
244
+ loc_names = target.eval('local_variables').reject do |e|
245
+ _pry_.sticky_locals.keys.include? e.to_sym
246
+ end
247
+ name_value_pairs = loc_names.map do |name|
248
+ [name, (target.eval name.to_s)]
108
249
  end
250
+ format_locals(name_value_pairs).join("")
251
+ end
252
+
253
+ # Format and colourise a list of methods.
254
+ def format_methods(methods)
255
+ methods.sort_by(&:name).map do |method|
256
+ if method.name == 'method_missing'
257
+ color(:method_missing, 'method_missing')
258
+ elsif method.visibility == :private
259
+ color(:private_method, method.name)
260
+ elsif method.visibility == :protected
261
+ color(:protected_method, method.name)
262
+ else
263
+ color(:public_method, method.name)
264
+ end
265
+ end
266
+ end
267
+
268
+ def format_variables(type, vars)
269
+ vars.sort_by(&:downcase).map{ |var| color(type, var) }
109
270
  end
110
271
 
272
+ def format_constants(mod, constants)
273
+ constants.sort_by(&:downcase).map do |name|
274
+ if const = (!mod.autoload?(name) && (mod.const_get(name) || true) rescue nil)
275
+ if (const < Exception rescue false)
276
+ color(:exception_constant, name)
277
+ elsif (Module === mod.const_get(name) rescue false)
278
+ color(:class_constant, name)
279
+ else
280
+ color(:constant, name)
281
+ end
282
+ else
283
+ color(:unloaded_constant, name)
284
+ end
285
+ end
286
+ end
287
+
288
+ def format_globals(globals)
289
+ globals.sort_by(&:downcase).map do |name|
290
+ if PSEUDO_GLOBALS.include?(name)
291
+ color(:pseudo_global, name)
292
+ elsif BUILTIN_GLOBALS.include?(name)
293
+ color(:builtin_global, name)
294
+ else
295
+ color(:global_var, name)
296
+ end
297
+ end
298
+ end
299
+
300
+ def format_local_names(locals)
301
+ locals.sort_by(&:downcase).map do |name|
302
+ if _pry_.sticky_locals.include?(name.to_sym)
303
+ color(:pry_var, name)
304
+ else
305
+ color(:local_var, name)
306
+ end
307
+ end
308
+ end
309
+
310
+ def format_locals(name_value_pairs)
311
+ name_value_pairs.sort_by do |name, value|
312
+ value.to_s.size
313
+ end.reverse.map do |name, value|
314
+ colorized_assignment_style(name, format_value(value))
315
+ end
316
+ end
317
+
318
+ def colorized_assignment_style(lhs, rhs, desired_width = 7)
319
+ colorized_lhs = color(:local_var, lhs)
320
+ color_escape_padding = colorized_lhs.size - lhs.size
321
+ pad = desired_width + color_escape_padding
322
+ "%-#{pad}s = %s" % [color(:local_var, colorized_lhs), rhs]
323
+ end
324
+
325
+ def format_value(value)
326
+ accumulator = StringIO.new
327
+ Pry.output_with_default_format(accumulator, value, :hashrocket => false)
328
+ accumulator.string
329
+ end
330
+
331
+ # Add a new section to the output. Outputs nothing if the section would be empty.
332
+ def output_section(heading, body)
333
+ return "" if body.compact.empty?
334
+ fancy_heading = text.bold(color(:heading, heading))
335
+ Pry::Helpers.tablify_or_one_line(fancy_heading, body)
336
+ end
337
+
338
+ # Color output based on config.ls.*_color
339
+ def color(type, str)
340
+ text.send(Pry.config.ls.send(:"#{type}_color"), str)
341
+ end
111
342
  end
112
343
 
113
344
  Pry::Commands.add_command(Pry::Command::Ls)