pry 0.9.12.6 → 0.10.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (186) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +702 -0
  3. data/LICENSE +2 -2
  4. data/{README.markdown → README.md} +37 -31
  5. data/lib/pry.rb +38 -151
  6. data/lib/pry/cli.rb +35 -17
  7. data/lib/pry/code.rb +24 -63
  8. data/lib/pry/code/code_file.rb +103 -0
  9. data/lib/pry/code/code_range.rb +2 -1
  10. data/lib/pry/code/loc.rb +2 -2
  11. data/lib/pry/code_object.rb +40 -21
  12. data/lib/pry/color_printer.rb +55 -0
  13. data/lib/pry/command.rb +12 -9
  14. data/lib/pry/command_set.rb +81 -38
  15. data/lib/pry/commands.rb +1 -1
  16. data/lib/pry/commands/amend_line.rb +2 -2
  17. data/lib/pry/commands/bang.rb +1 -1
  18. data/lib/pry/commands/cat.rb +11 -2
  19. data/lib/pry/commands/cat/exception_formatter.rb +5 -6
  20. data/lib/pry/commands/cat/file_formatter.rb +15 -32
  21. data/lib/pry/commands/cd.rb +14 -3
  22. data/lib/pry/commands/change_inspector.rb +27 -0
  23. data/lib/pry/commands/change_prompt.rb +26 -0
  24. data/lib/pry/commands/code_collector.rb +4 -4
  25. data/lib/pry/commands/easter_eggs.rb +3 -3
  26. data/lib/pry/commands/edit.rb +10 -22
  27. data/lib/pry/commands/edit/exception_patcher.rb +2 -2
  28. data/lib/pry/commands/edit/file_and_line_locator.rb +0 -2
  29. data/lib/pry/commands/exit_program.rb +0 -1
  30. data/lib/pry/commands/find_method.rb +16 -22
  31. data/lib/pry/commands/gem_install.rb +5 -2
  32. data/lib/pry/commands/gem_open.rb +1 -1
  33. data/lib/pry/commands/gist.rb +10 -11
  34. data/lib/pry/commands/help.rb +14 -14
  35. data/lib/pry/commands/hist.rb +27 -8
  36. data/lib/pry/commands/install_command.rb +14 -12
  37. data/lib/pry/commands/list_inspectors.rb +35 -0
  38. data/lib/pry/commands/list_prompts.rb +35 -0
  39. data/lib/pry/commands/ls.rb +72 -296
  40. data/lib/pry/commands/ls/constants.rb +47 -0
  41. data/lib/pry/commands/ls/formatter.rb +49 -0
  42. data/lib/pry/commands/ls/globals.rb +48 -0
  43. data/lib/pry/commands/ls/grep.rb +21 -0
  44. data/lib/pry/commands/ls/instance_vars.rb +39 -0
  45. data/lib/pry/commands/ls/interrogatable.rb +18 -0
  46. data/lib/pry/commands/ls/jruby_hacks.rb +49 -0
  47. data/lib/pry/commands/ls/local_names.rb +35 -0
  48. data/lib/pry/commands/ls/local_vars.rb +39 -0
  49. data/lib/pry/commands/ls/ls_entity.rb +70 -0
  50. data/lib/pry/commands/ls/methods.rb +57 -0
  51. data/lib/pry/commands/ls/methods_helper.rb +46 -0
  52. data/lib/pry/commands/ls/self_methods.rb +32 -0
  53. data/lib/pry/commands/play.rb +44 -10
  54. data/lib/pry/commands/pry_backtrace.rb +1 -2
  55. data/lib/pry/commands/raise_up.rb +2 -2
  56. data/lib/pry/commands/reload_code.rb +16 -19
  57. data/lib/pry/commands/ri.rb +7 -3
  58. data/lib/pry/commands/shell_command.rb +18 -13
  59. data/lib/pry/commands/shell_mode.rb +2 -4
  60. data/lib/pry/commands/show_doc.rb +5 -0
  61. data/lib/pry/commands/show_info.rb +8 -13
  62. data/lib/pry/commands/show_source.rb +15 -3
  63. data/lib/pry/commands/simple_prompt.rb +1 -1
  64. data/lib/pry/commands/toggle_color.rb +8 -4
  65. data/lib/pry/commands/watch_expression.rb +105 -0
  66. data/lib/pry/commands/watch_expression/expression.rb +38 -0
  67. data/lib/pry/commands/whereami.rb +18 -10
  68. data/lib/pry/commands/wtf.rb +3 -3
  69. data/lib/pry/config.rb +20 -254
  70. data/lib/pry/config/behavior.rb +139 -0
  71. data/lib/pry/config/convenience.rb +26 -0
  72. data/lib/pry/config/default.rb +165 -0
  73. data/lib/pry/core_extensions.rb +31 -21
  74. data/lib/pry/editor.rb +107 -103
  75. data/lib/pry/exceptions.rb +77 -0
  76. data/lib/pry/helpers/base_helpers.rb +22 -109
  77. data/lib/pry/helpers/command_helpers.rb +10 -8
  78. data/lib/pry/helpers/documentation_helpers.rb +1 -2
  79. data/lib/pry/helpers/text.rb +4 -5
  80. data/lib/pry/history.rb +46 -45
  81. data/lib/pry/history_array.rb +6 -1
  82. data/lib/pry/hooks.rb +9 -29
  83. data/lib/pry/indent.rb +6 -6
  84. data/lib/pry/input_completer.rb +242 -0
  85. data/lib/pry/input_lock.rb +132 -0
  86. data/lib/pry/inspector.rb +27 -0
  87. data/lib/pry/last_exception.rb +61 -0
  88. data/lib/pry/method.rb +82 -87
  89. data/lib/pry/{commands/edit/method_patcher.rb → method/patcher.rb} +41 -38
  90. data/lib/pry/module_candidate.rb +4 -14
  91. data/lib/pry/object_path.rb +82 -0
  92. data/lib/pry/output.rb +50 -0
  93. data/lib/pry/pager.rb +191 -47
  94. data/lib/pry/plugins.rb +1 -1
  95. data/lib/pry/prompt.rb +26 -0
  96. data/lib/pry/pry_class.rb +149 -230
  97. data/lib/pry/pry_instance.rb +302 -413
  98. data/lib/pry/rbx_path.rb +1 -1
  99. data/lib/pry/repl.rb +202 -0
  100. data/lib/pry/repl_file_loader.rb +20 -26
  101. data/lib/pry/rubygem.rb +13 -5
  102. data/lib/pry/terminal.rb +2 -1
  103. data/lib/pry/test/helper.rb +26 -41
  104. data/lib/pry/version.rb +1 -1
  105. data/lib/pry/wrapped_module.rb +45 -59
  106. metadata +61 -224
  107. data/.document +0 -2
  108. data/.gitignore +0 -16
  109. data/.travis.yml +0 -25
  110. data/.yardopts +0 -1
  111. data/CHANGELOG +0 -534
  112. data/CONTRIBUTORS +0 -55
  113. data/Gemfile +0 -12
  114. data/Rakefile +0 -140
  115. data/TODO +0 -117
  116. data/lib/pry/completion.rb +0 -321
  117. data/lib/pry/custom_completions.rb +0 -6
  118. data/lib/pry/rbx_method.rb +0 -13
  119. data/man/pry.1 +0 -195
  120. data/man/pry.1.html +0 -204
  121. data/man/pry.1.ronn +0 -141
  122. data/pry.gemspec +0 -29
  123. data/spec/Procfile +0 -3
  124. data/spec/cli_spec.rb +0 -78
  125. data/spec/code_object_spec.rb +0 -277
  126. data/spec/code_spec.rb +0 -219
  127. data/spec/command_helpers_spec.rb +0 -29
  128. data/spec/command_integration_spec.rb +0 -644
  129. data/spec/command_set_spec.rb +0 -627
  130. data/spec/command_spec.rb +0 -821
  131. data/spec/commands/amend_line_spec.rb +0 -247
  132. data/spec/commands/bang_spec.rb +0 -19
  133. data/spec/commands/cat_spec.rb +0 -164
  134. data/spec/commands/cd_spec.rb +0 -250
  135. data/spec/commands/disable_pry_spec.rb +0 -25
  136. data/spec/commands/edit_spec.rb +0 -727
  137. data/spec/commands/exit_all_spec.rb +0 -34
  138. data/spec/commands/exit_program_spec.rb +0 -19
  139. data/spec/commands/exit_spec.rb +0 -34
  140. data/spec/commands/find_method_spec.rb +0 -70
  141. data/spec/commands/gem_list_spec.rb +0 -26
  142. data/spec/commands/gist_spec.rb +0 -79
  143. data/spec/commands/help_spec.rb +0 -56
  144. data/spec/commands/hist_spec.rb +0 -181
  145. data/spec/commands/jump_to_spec.rb +0 -15
  146. data/spec/commands/ls_spec.rb +0 -181
  147. data/spec/commands/play_spec.rb +0 -140
  148. data/spec/commands/raise_up_spec.rb +0 -56
  149. data/spec/commands/save_file_spec.rb +0 -177
  150. data/spec/commands/show_doc_spec.rb +0 -510
  151. data/spec/commands/show_input_spec.rb +0 -17
  152. data/spec/commands/show_source_spec.rb +0 -782
  153. data/spec/commands/whereami_spec.rb +0 -203
  154. data/spec/completion_spec.rb +0 -241
  155. data/spec/control_d_handler_spec.rb +0 -58
  156. data/spec/documentation_helper_spec.rb +0 -73
  157. data/spec/editor_spec.rb +0 -79
  158. data/spec/exception_whitelist_spec.rb +0 -21
  159. data/spec/fixtures/candidate_helper1.rb +0 -11
  160. data/spec/fixtures/candidate_helper2.rb +0 -8
  161. data/spec/fixtures/example.erb +0 -5
  162. data/spec/fixtures/example_nesting.rb +0 -33
  163. data/spec/fixtures/show_source_doc_examples.rb +0 -15
  164. data/spec/fixtures/testrc +0 -2
  165. data/spec/fixtures/testrcbad +0 -2
  166. data/spec/fixtures/whereami_helper.rb +0 -6
  167. data/spec/helper.rb +0 -34
  168. data/spec/helpers/bacon.rb +0 -86
  169. data/spec/helpers/mock_pry.rb +0 -43
  170. data/spec/helpers/table_spec.rb +0 -105
  171. data/spec/history_array_spec.rb +0 -67
  172. data/spec/hooks_spec.rb +0 -522
  173. data/spec/indent_spec.rb +0 -301
  174. data/spec/input_stack_spec.rb +0 -90
  175. data/spec/method_spec.rb +0 -482
  176. data/spec/prompt_spec.rb +0 -60
  177. data/spec/pry_defaults_spec.rb +0 -419
  178. data/spec/pry_history_spec.rb +0 -99
  179. data/spec/pry_output_spec.rb +0 -95
  180. data/spec/pry_spec.rb +0 -515
  181. data/spec/run_command_spec.rb +0 -25
  182. data/spec/sticky_locals_spec.rb +0 -157
  183. data/spec/syntax_checking_spec.rb +0 -81
  184. data/spec/wrapped_module_spec.rb +0 -261
  185. data/wiki/Customizing-pry.md +0 -397
  186. data/wiki/Home.md +0 -4
@@ -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 'Playback a string variable or a method or a file as input.'
6
- command_options :requires_gem => "jist"
5
+ description 'Upload code, docs, history to https://gist.github.com/.'
6
+ command_options :requires_gem => "gist"
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 'jist'
19
+ require 'gist'
20
20
  end
21
21
 
22
22
  def options(opt)
23
23
  CodeCollector.inject_options(opt)
24
- opt.on :login, "Authenticate the jist gem with GitHub"
24
+ opt.on :login, "Authenticate the gist 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 Jist.login! if opts.present?(:login)
30
+ return ::Gist.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
- Jist.copy(content)
48
+ ::Gist.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 = Jist.gist(content, :filename => filename || "pry_gist.rb", :public => !!opts[:p])
84
+ response = ::Gist.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
- Jist.copy(url)
89
+ ::Gist.copy(url)
90
90
  message << ", which is now in the clipboard."
91
- rescue Jist::ClipboardError
91
+ rescue ::Gist::ClipboardError
92
92
  end
93
93
 
94
94
  output.puts message
@@ -98,5 +98,4 @@ 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'
102
101
  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 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.
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.
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]]
40
+ # @param [Hash<String, Array<Commands>>] groups
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
- stagger_output(help_text.join("\n\n"))
52
+ _pry_.pager.page 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)}\n" + commands.map do |command|
63
- " #{command.options[:listing].to_s.ljust(18)} #{command.description}"
62
+ "#{text.bold(name.capitalize)}\n" << commands.map do |command|
63
+ " #{command.options[:listing].to_s.ljust(18)} #{command.description.capitalize}"
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
- stagger_output command.new.help
124
+ _pry_.pager.page 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] the search term
134
- # @param [Hash] the hash to search
133
+ # @param [String] search the search term
134
+ # @param [Hash] 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
153
- # @return String
152
+ # @param [String] key
153
+ # @return [String]
154
154
  def normalize(key)
155
155
  key.downcase.gsub(/pry\W+/, '')
156
156
  end
@@ -6,6 +6,7 @@ class Pry
6
6
 
7
7
  banner <<-'BANNER'
8
8
  Usage: hist [--head|--tail]
9
+ hist --all
9
10
  hist --head N
10
11
  hist --tail N
11
12
  hist --show START..END
@@ -19,6 +20,7 @@ class Pry
19
20
  BANNER
20
21
 
21
22
  def options(opt)
23
+ opt.on :a, :all, "Display all history"
22
24
  opt.on :H, :head, "Display the first N items", :optional_argument => true, :as => Integer
23
25
  opt.on :T, :tail, "Display the last N items", :optional_argument => true, :as => Integer
24
26
  opt.on :s, :show, "Show the given range of lines", :optional_argument => true, :as => Range
@@ -28,11 +30,10 @@ class Pry
28
30
  opt.on :save, "Save history to a file", :argument => true, :as => Range
29
31
  opt.on :e, :'exclude-pry', "Exclude Pry commands from the history"
30
32
  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"
32
33
  end
33
34
 
34
35
  def process
35
- @history = Pry::Code(Pry.history.to_a)
36
+ @history = find_history
36
37
 
37
38
  if opts.present?(:show)
38
39
  @history = @history.between(opts[:show])
@@ -54,7 +55,9 @@ class Pry
54
55
  end
55
56
 
56
57
  if opts.present?(:'exclude-pry')
57
- @history = @history.select { |l, ln| !command_set.valid_command?(l) }
58
+ @history = @history.select do |loc|
59
+ !command_set.valid_command?(loc.line)
60
+ end
58
61
  end
59
62
 
60
63
  if opts.present?(:save)
@@ -75,7 +78,9 @@ class Pry
75
78
  @history = @history.with_line_numbers
76
79
  end
77
80
 
78
- render_output(@history, opts)
81
+ _pry_.pager.open do |pager|
82
+ @history.print_to_output(pager, true)
83
+ end
79
84
  end
80
85
 
81
86
  def process_save
@@ -113,10 +118,9 @@ class Pry
113
118
  # further.
114
119
  check_for_juxtaposed_replay(replay_sequence)
115
120
 
116
- _pry_.input_stack.push _pry_.input
117
- _pry_.input = StringIO.new(replay_sequence)
118
- # eval_string << "#{@history.raw}\n"
119
- # run "show-input" unless _pry_.complete_expression?(eval_string)
121
+ replay_sequence.lines.each do |line|
122
+ _pry_.eval line, :generated => true
123
+ end
120
124
  end
121
125
 
122
126
  # Checks +replay_sequence+ for the presence of neighboring replay calls.
@@ -154,6 +158,21 @@ class Pry
154
158
  false
155
159
  end
156
160
  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
157
176
  end
158
177
 
159
178
  Pry::Commands.add_command(Pry::Command::Hist)
@@ -15,35 +15,37 @@ class Pry
15
15
  require 'rubygems/dependency_installer' unless defined? Gem::DependencyInstaller
16
16
  command = find_command(name)
17
17
 
18
+ unless command
19
+ output.puts "Command #{ text.green(name) } is not found"
20
+ return
21
+ end
22
+
18
23
  if command_dependencies_met?(command.options)
19
- output.puts "Dependencies for #{command.name} are met. Nothing to do."
24
+ output.puts "Dependencies for #{ text.green(name) } are met. Nothing to do"
20
25
  return
21
26
  end
22
27
 
23
- output.puts "Attempting to install `#{name}` command..."
28
+ output.puts "Attempting to install #{ text.green(name) } command..."
24
29
  gems_to_install = Array(command.options[:requires_gem])
25
30
 
26
31
  gems_to_install.each do |g|
27
32
  next if Rubygem.installed?(g)
28
- output.puts "Installing `#{g}` gem..."
29
-
30
- begin
31
- Gem::DependencyInstaller.new.install(g)
32
- rescue Gem::GemNotFoundException
33
- raise CommandError, "Required Gem: `#{g}` not found. Aborting command installation."
34
- end
33
+ output.puts "Installing #{ text.green(g) } gem..."
34
+ Rubygem.install(g)
35
35
  end
36
36
 
37
- Gem.refresh
38
37
  gems_to_install.each do |g|
39
38
  begin
40
39
  require g
41
40
  rescue LoadError
42
- raise CommandError, "Required Gem: `#{g}` installed but not found?!. Aborting command installation."
41
+ fail_msg = "Required gem #{ text.green(g) } installed but not found."
42
+ fail_msg += " Aborting command installation\n"
43
+ fail_msg += 'Tips: 1. Check your PATH; 2. Run `bundle update`'
44
+ raise CommandError, fail_msg
43
45
  end
44
46
  end
45
47
 
46
- output.puts "Installation of `#{name}` successful! Type `help #{name}` for information"
48
+ output.puts "Installation of #{ text.green(name) } successful! Type `help #{name}` for information"
47
49
  end
48
50
  end
49
51
 
@@ -0,0 +1,35 @@
1
+ class Pry::Command::ListInspectors < Pry::ClassCommand
2
+ match 'list-inspectors'
3
+ group 'Input and Output'
4
+ description 'List the inspector procs available for use.'
5
+ banner <<-BANNER
6
+ Usage: list-inspectors
7
+
8
+ List the inspector procs available to print return values. You can use
9
+ change-inspector to switch between them.
10
+ BANNER
11
+
12
+ def process
13
+ output.puts heading("Available inspectors") + "\n"
14
+ inspector_map.each do |name, inspector|
15
+ output.write "Name: #{text.bold(name)}"
16
+ output.puts selected_inspector?(inspector) ? selected_text : ""
17
+ output.puts inspector[:description]
18
+ output.puts
19
+ end
20
+ end
21
+
22
+ private
23
+ def inspector_map
24
+ Pry::Inspector::MAP
25
+ end
26
+
27
+ def selected_text
28
+ text.red " (selected) "
29
+ end
30
+
31
+ def selected_inspector?(inspector)
32
+ _pry_.print == inspector[:value]
33
+ end
34
+ Pry::Commands.add_command(self)
35
+ end
@@ -0,0 +1,35 @@
1
+ class Pry::Command::ListPrompts < Pry::ClassCommand
2
+ match 'list-prompts'
3
+ group 'Input and Output'
4
+ description 'List the prompts available for use.'
5
+ banner <<-BANNER
6
+ Usage: list-prompts
7
+
8
+ List the available prompts. You can use change-prompt to switch between
9
+ them.
10
+ BANNER
11
+
12
+ def process
13
+ output.puts heading("Available prompts") + "\n"
14
+ prompt_map.each do |name, prompt|
15
+ output.write "Name: #{text.bold(name)}"
16
+ output.puts selected_prompt?(prompt) ? selected_text : ""
17
+ output.puts prompt[:description]
18
+ output.puts
19
+ end
20
+ end
21
+
22
+ private
23
+ def prompt_map
24
+ Pry::Prompt::MAP
25
+ end
26
+
27
+ def selected_text
28
+ text.red " (selected) "
29
+ end
30
+
31
+ def selected_prompt?(prompt)
32
+ _pry_.prompt == prompt[:value]
33
+ end
34
+ Pry::Commands.add_command(self)
35
+ end
@@ -1,38 +1,64 @@
1
+ require 'pry/commands/ls/ls_entity'
1
2
  class Pry
2
3
  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
+
3
26
  match 'ls'
4
27
  group 'Context'
5
28
  description 'Show the list of vars and methods in the current scope.'
6
29
  command_options :shellwords => false, :interpolate => false
7
30
 
8
- def options(opt)
9
- opt.banner unindent <<-'BANNER'
10
- Usage: ls [-m|-M|-p|-pM] [-q|-v] [-c|-i] [Object]
11
- ls [-g] [-l]
31
+ banner <<-'BANNER'
32
+ Usage: ls [-m|-M|-p|-pM] [-q|-v] [-c|-i] [Object]
33
+ ls [-g] [-l]
12
34
 
13
- ls shows you which methods, constants and variables are accessible to Pry. By
14
- default it shows you the local variables defined in the current shell, and any
15
- public methods or instance variables defined on the current object.
35
+ ls shows you which methods, constants and variables are accessible to Pry. By
36
+ default it shows you the local variables defined in the current shell, and any
37
+ public methods or instance variables defined on the current object.
16
38
 
17
- The colours used are configurable using Pry.config.ls.*_color, and the separator
18
- is Pry.config.ls.separator.
39
+ The colours used are configurable using Pry.config.ls.*_color, and the separator
40
+ is Pry.config.ls.separator.
19
41
 
20
- Pry.config.ls.ceiling is used to hide methods defined higher up in the
21
- inheritance chain, this is by default set to [Object, Module, Class] so that
22
- methods defined on all Objects are omitted. The -v flag can be used to ignore
23
- this setting and show all methods, while the -q can be used to set the ceiling
24
- much lower and show only methods defined on the object or its direct class.
25
- BANNER
42
+ Pry.config.ls.ceiling is used to hide methods defined higher up in the
43
+ inheritance chain, this is by default set to [Object, Module, Class] so that
44
+ methods defined on all Objects are omitted. The -v flag can be used to ignore
45
+ this setting and show all methods, while the -q can be used to set the ceiling
46
+ much lower and show only methods defined on the object or its direct class.
26
47
 
27
- opt.on :m, :methods, "Show public methods defined on the Object (default)"
28
- opt.on :M, "instance-methods", "Show methods defined in a Module or Class"
48
+ Also check out `find-method` command (run `help find-method`).
49
+ BANNER
50
+
51
+
52
+ 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"
29
55
  opt.on :p, :ppp, "Show public, protected (in yellow) and private (in green) methods"
30
56
  opt.on :q, :quiet, "Show only methods defined on object.singleton_class and object.class"
31
57
  opt.on :v, :verbose, "Show methods and constants on all super-classes (ignores Pry.config.ls.ceiling)"
32
58
  opt.on :g, :globals, "Show global variables, including those builtin to Ruby (in cyan)"
33
59
  opt.on :l, :locals, "Show hash of local vars, sorted by descending size"
34
- opt.on :c, :constants, "Show constants, highlighting classes (in blue), and exceptions (in purple).\n" +
35
- " " * 32 + "Constants that are pending autoload? are also shown (in yellow)"
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)"
36
62
  opt.on :i, :ivars, "Show instance variables (in blue) and class variables (in bright blue)"
37
63
  opt.on :G, :grep, "Filter output by regular expression", :argument => true
38
64
 
@@ -41,297 +67,47 @@ class Pry
41
67
  end
42
68
  end
43
69
 
44
- attr_reader :object_to_interrogate, :has_user_specified_any_options, :grep, :grep_regex
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
76
 
46
77
  def process
47
- @object_to_interrogate = args.empty? ? target_self : target.eval(args.join(" "))
48
-
49
- # exclude -q, -v and --grep because they don't specify what the user wants to see.
50
- @has_user_specified_any_options = (opts.present?(:methods) || opts.present?(:'instance-methods') || opts.present?(:ppp) ||
51
- opts.present?(:globals) || opts.present?(:locals) || opts.present?(:constants) ||
52
- opts.present?(:ivars))
53
-
54
- @grep_regex, @grep = [Regexp.new(opts[:G] || "."), lambda{ |x| x.grep(@grep_regex) }]
55
-
78
+ @interrogatee = args.empty? ? target_self : target.eval(args.join(' '))
56
79
  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
+ })
57
87
 
58
- all_output = [
59
- write_out_globals,
60
- write_out_constants,
61
- write_out_methods,
62
- write_out_self_methods,
63
- write_out_ivars,
64
- write_out_local_names,
65
- write_out_locals,
66
- ].compact.join("")
67
-
68
- stagger_output(all_output)
88
+ _pry_.pager.page ls_entity.entities_table
69
89
  end
70
90
 
71
91
  private
72
92
 
73
- # http://ruby.runpaint.org/globals, and running "puts global_variables.inspect".
74
- BUILTIN_GLOBALS = %w($" $$ $* $, $-0 $-F $-I $-K $-W $-a $-d $-i $-l $-p $-v $-w $. $/ $\\
75
- $: $; $< $= $> $0 $ARGV $CONSOLE $DEBUG $DEFAULT_INPUT $DEFAULT_OUTPUT
76
- $FIELD_SEPARATOR $FILENAME $FS $IGNORECASE $INPUT_LINE_NUMBER
77
- $INPUT_RECORD_SEPARATOR $KCODE $LOADED_FEATURES $LOAD_PATH $NR $OFS
78
- $ORS $OUTPUT_FIELD_SEPARATOR $OUTPUT_RECORD_SEPARATOR $PID $PROCESS_ID
79
- $PROGRAM_NAME $RS $VERBOSE $deferr $defout $stderr $stdin $stdout)
80
-
81
- # $SAFE and $? are thread-local, the exception stuff only works in a rescue clause,
82
- # everything else is basically a local variable with a $ in its name.
83
- PSEUDO_GLOBALS = %w($! $' $& $` $@ $? $+ $_ $~ $1 $2 $3 $4 $5 $6 $7 $8 $9
84
- $CHILD_STATUS $SAFE $ERROR_INFO $ERROR_POSITION $LAST_MATCH_INFO
85
- $LAST_PAREN_MATCH $LAST_READ_LINE $MATCH $POSTMATCH $PREMATCH)
86
-
87
- # Get all the methods that we'll want to output
88
- def all_methods(obj, instance_methods=false)
89
- methods = if instance_methods || opts.present?(:'instance-methods')
90
- Pry::Method.all_from_class(obj)
91
- else
92
- Pry::Method.all_from_obj(obj)
93
- end
94
-
95
- if jruby? && !opts.present?(:J)
96
- methods = trim_jruby_aliases(methods)
97
- end
98
-
99
- methods.select{ |method| opts.present?(:ppp) || method.visibility == :public }
100
- end
101
-
102
- # JRuby creates lots of aliases for methods imported from java in an attempt to
103
- # make life easier for ruby programmers.
104
- # (e.g. getFooBar becomes get_foo_bar and foo_bar, and maybe foo_bar? if it
105
- # returns a Boolean).
106
- # The full transformations are in the assignAliases method of:
107
- # https://github.com/jruby/jruby/blob/master/src/org/jruby/javasupport/JavaClass.java
108
- #
109
- # This has the unfortunate side-effect of making the output of ls even more
110
- # incredibly verbose than it normally would be for these objects; and so we filter
111
- # out all but the nicest of these aliases here.
112
- #
113
- # TODO: This is a little bit vague, better heuristics could be used.
114
- # JRuby also has a lot of scala-specific logic, which we don't copy.
115
- #
116
- def trim_jruby_aliases(methods)
117
- grouped = methods.group_by do |m|
118
- m.name.sub(/\A(is|get|set)(?=[A-Z_])/, '').gsub(/[_?=]/, '').downcase
119
- end
120
-
121
- grouped.map do |key, values|
122
- values = values.sort_by do |m|
123
- rubbishness(m.name)
124
- end
125
-
126
- found = []
127
- values.select do |x|
128
- (!found.any?{ |y| x == y }) && found << x
129
- end
130
- end.flatten(1)
131
- end
132
-
133
- # When removing jruby aliases, we want to keep the alias that is "least rubbish"
134
- # according to this metric.
135
- def rubbishness(name)
136
- name.each_char.map{ |x|
137
- case x
138
- when /[A-Z]/
139
- 1
140
- when '?', '=', '!'
141
- -2
142
- else
143
- 0
144
- end
145
- }.inject(&:+) + (name.size / 100.0)
146
- end
147
-
148
- def resolution_order(obj)
149
- opts.present?(:'instance-methods') ? Pry::Method.instance_resolution_order(obj) : Pry::Method.resolution_order(obj)
150
- end
151
-
152
- # Get a lambda that can be used with .take_while to prevent over-eager
153
- # traversal of the Object's ancestry graph.
154
- def below_ceiling(obj)
155
- ceiling = if opts.present?(:quiet)
156
- [opts.present?(:'instance-methods') ? obj.ancestors[1] : obj.class.ancestors[1]] + Pry.config.ls.ceiling
157
- elsif opts.present?(:verbose)
158
- []
159
- else
160
- Pry.config.ls.ceiling.dup
161
- end
162
-
163
- lambda { |klass| !ceiling.include?(klass) }
164
- end
165
-
166
- def raise_errors_if_arguments_are_weird
93
+ def error_list
94
+ any_args = args.any?
95
+ non_mod_interrogatee = !(Module === @interrogatee)
167
96
  [
168
- ["-l does not make sense with a specified Object", :locals, !args.empty?],
169
- ["-g does not make sense with a specified Object", :globals, !args.empty?],
170
- ["-q does not make sense with -v", :quiet, opts.present?(:verbose)],
171
- ["-M only makes sense with a Module or a Class", :'instance-methods', !interrogating_a_module?],
172
- ["-c only makes sense with a Module or a Class", :constants, !args.empty? && !interrogating_a_module?],
173
- ].each do |message, option, expression|
174
- raise Pry::CommandError, message if opts.present?(option) && expression
175
- end
176
- end
177
-
178
- def interrogating_a_module?
179
- (Module === object_to_interrogate)
180
- end
181
-
182
- def write_out_globals
183
- return unless opts.present?(:globals)
184
-
185
- output_section("global variables", grep[format_globals(target.eval("global_variables"))])
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
+ ]
186
103
  end
187
104
 
188
- def write_out_constants
189
- return unless opts.present?(:constants) || (!has_user_specified_any_options && interrogating_a_module?)
190
-
191
- mod = interrogating_a_module? ? object_to_interrogate : Object
192
- constants = WrappedModule.new(mod).constants(opts.present?(:verbose))
193
- output_section("constants", grep[format_constants(mod, constants)])
194
- end
195
-
196
- def write_out_methods
197
- return unless opts.present?(:methods) || opts.present?(:'instance-methods') || opts.present?(:ppp) || !has_user_specified_any_options
198
-
199
- # methods is a hash {Module/Class => [Pry::Methods]}
200
- methods = all_methods(object_to_interrogate).group_by(&:owner)
201
-
202
- output = ""
203
- # reverse the resolution order so that the most useful information appears right by the prompt
204
- resolution_order(object_to_interrogate).take_while(&below_ceiling(object_to_interrogate)).reverse.each do |klass|
205
- methods_here = format_methods((methods[klass] || []).select{ |m| m.name =~ grep_regex })
206
- output << output_section("#{Pry::WrappedModule.new(klass).method_prefix}methods", methods_here)
207
- end
208
- output
209
- end
210
-
211
- def write_out_self_methods
212
- return unless (!has_user_specified_any_options && interrogating_a_module?)
213
-
214
- methods = all_methods(object_to_interrogate, true).select{ |m| m.owner == object_to_interrogate && m.name =~ grep_regex }
215
- output_section("#{Pry::WrappedModule.new(object_to_interrogate).method_prefix}methods", format_methods(methods))
216
- end
217
-
218
- def write_out_ivars
219
- return unless opts.present?(:ivars) || !has_user_specified_any_options
220
-
221
- klass = (interrogating_a_module? ? object_to_interrogate : object_to_interrogate.class)
222
- ivars = Pry::Method.safe_send(object_to_interrogate, :instance_variables)
223
- kvars = Pry::Method.safe_send(klass, :class_variables)
224
- output_section("instance variables", format_variables(:instance_var, ivars)) +
225
- output_section("class variables", format_variables(:class_var, kvars))
226
- end
227
-
228
- def write_out_local_names
229
- return unless !has_user_specified_any_options && args.empty?
230
-
231
- output_section("locals", format_local_names(grep[target.eval("local_variables")]))
232
- end
233
-
234
- def write_out_locals
235
- return unless opts.present?(:locals)
236
-
237
- loc_names = target.eval('local_variables').reject do |e|
238
- _pry_.sticky_locals.keys.include? e.to_sym
239
- end
240
- name_value_pairs = loc_names.map do |name|
241
- [name, (target.eval name.to_s)]
242
- end
243
- format_locals(name_value_pairs).join("")
244
- end
245
-
246
- # Format and colourise a list of methods.
247
- def format_methods(methods)
248
- methods.sort_by(&:name).map do |method|
249
- if method.name == 'method_missing'
250
- color(:method_missing, 'method_missing')
251
- elsif method.visibility == :private
252
- color(:private_method, method.name)
253
- elsif method.visibility == :protected
254
- color(:protected_method, method.name)
255
- else
256
- color(:public_method, method.name)
257
- end
258
- end
259
- end
260
-
261
- def format_variables(type, vars)
262
- vars.sort_by(&:downcase).map{ |var| color(type, var) }
263
- end
264
-
265
- def format_constants(mod, constants)
266
- constants.sort_by(&:downcase).map do |name|
267
- if const = (!mod.autoload?(name) && (mod.const_get(name) || true) rescue nil)
268
- if (const < Exception rescue false)
269
- color(:exception_constant, name)
270
- elsif (Module === mod.const_get(name) rescue false)
271
- color(:class_constant, name)
272
- else
273
- color(:constant, name)
274
- end
275
- else
276
- color(:unloaded_constant, name)
277
- end
278
- end
279
- end
280
-
281
- def format_globals(globals)
282
- globals.sort_by(&:downcase).map do |name|
283
- if PSEUDO_GLOBALS.include?(name)
284
- color(:pseudo_global, name)
285
- elsif BUILTIN_GLOBALS.include?(name)
286
- color(:builtin_global, name)
287
- else
288
- color(:global_var, name)
289
- end
290
- end
291
- end
292
-
293
- def format_local_names(locals)
294
- locals.sort_by(&:downcase).map do |name|
295
- if _pry_.sticky_locals.include?(name.to_sym)
296
- color(:pry_var, name)
297
- else
298
- color(:local_var, name)
299
- end
300
- end
301
- end
302
-
303
- def format_locals(name_value_pairs)
304
- name_value_pairs.sort_by do |name, value|
305
- value.to_s.size
306
- end.reverse.map do |name, value|
307
- colorized_assignment_style(name, format_value(value))
105
+ 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
308
108
  end
309
109
  end
310
110
 
311
- def colorized_assignment_style(lhs, rhs, desired_width = 7)
312
- colorized_lhs = color(:local_var, lhs)
313
- color_escape_padding = colorized_lhs.size - lhs.size
314
- pad = desired_width + color_escape_padding
315
- "%-#{pad}s = %s" % [color(:local_var, colorized_lhs), rhs]
316
- end
317
-
318
- def format_value(value)
319
- accumulator = StringIO.new
320
- Pry.output_with_default_format(accumulator, value, :hashrocket => false)
321
- accumulator.string
322
- end
323
-
324
- # Add a new section to the output. Outputs nothing if the section would be empty.
325
- def output_section(heading, body)
326
- return "" if body.compact.empty?
327
- fancy_heading = text.bold(color(:heading, heading))
328
- Pry::Helpers.tablify_or_one_line(fancy_heading, body)
329
- end
330
-
331
- # Color output based on config.ls.*_color
332
- def color(type, str)
333
- text.send(Pry.config.ls.send(:"#{type}_color"), str)
334
- end
335
111
  end
336
112
 
337
113
  Pry::Commands.add_command(Pry::Command::Ls)