pry 0.10.2-i386-mswin32 → 1.0.0.pre1-i386-mswin32

Sign up to get free protection for your applications and to get access to all the features.
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)