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
@@ -1,38 +0,0 @@
1
- class Pry
2
- class Command::WatchExpression
3
- class Expression
4
- attr_reader :target, :source, :value, :previous_value, :_pry_
5
-
6
- def initialize(_pry_, target, source)
7
- @_pry_ = _pry_
8
- @target = target
9
- @source = Code.new(source).strip
10
- end
11
-
12
- def eval!
13
- @previous_value = @value
14
- @value = Pry::ColorPrinter.pp(target_eval(target, source), "")
15
- end
16
-
17
- def to_s
18
- "#{Code.new(source).highlighted.strip} => #{value}"
19
- end
20
-
21
- # Has the value of the expression changed?
22
- #
23
- # We use the pretty-printed string represenation to detect differences
24
- # as this avoids problems with dup (causes too many differences) and == (causes too few)
25
- def changed?
26
- (value != previous_value)
27
- end
28
-
29
- private
30
-
31
- def target_eval(target, source)
32
- target.eval(source)
33
- rescue => e
34
- e
35
- end
36
- end
37
- end
38
- end
@@ -1,139 +0,0 @@
1
- module Pry::Config::Behavior
2
- ASSIGNMENT = "=".freeze
3
- NODUP = [TrueClass, FalseClass, NilClass, Symbol, Numeric, Module, Proc].freeze
4
- INSPECT_REGEXP = /#{Regexp.escape "default=#<"}/
5
-
6
- module Builder
7
- def from_hash(hash, default = nil)
8
- new(default).tap do |config|
9
- config.merge!(hash)
10
- end
11
- end
12
- end
13
-
14
- def self.included(klass)
15
- unless defined?(RESERVED_KEYS)
16
- const_set :RESERVED_KEYS, instance_methods(false).map(&:to_s).freeze
17
- end
18
- klass.extend(Builder)
19
- end
20
-
21
- def initialize(default = Pry.config)
22
- @default = default
23
- @lookup = {}
24
- end
25
-
26
- #
27
- # @return [Pry::Config::Behavior]
28
- # returns the default used if a matching value for a key isn't found in self
29
- #
30
- def default
31
- @default
32
- end
33
-
34
- def [](key)
35
- @lookup[key.to_s]
36
- end
37
-
38
- def []=(key, value)
39
- key = key.to_s
40
- if RESERVED_KEYS.include?(key)
41
- raise ArgumentError, "few things are reserved by pry, but using '#{key}' as a configuration key is."
42
- end
43
- @lookup[key] = value
44
- end
45
-
46
- def method_missing(name, *args, &block)
47
- key = name.to_s
48
- if key[-1] == ASSIGNMENT
49
- short_key = key[0..-2]
50
- self[short_key] = args[0]
51
- elsif key?(key)
52
- self[key]
53
- elsif @default.respond_to?(name)
54
- value = @default.public_send(name, *args, &block)
55
- # FIXME: refactor Pry::Hook so that it stores config on the config object,
56
- # so that we can use the normal strategy.
57
- self[key] = value = value.dup if key == 'hooks'
58
- value
59
- else
60
- nil
61
- end
62
- end
63
-
64
- def merge!(other)
65
- other = try_convert_to_hash(other)
66
- raise TypeError, "unable to convert argument into a Hash" unless other
67
- other.each do |key, value|
68
- self[key] = value
69
- end
70
- end
71
-
72
- def ==(other)
73
- @lookup == try_convert_to_hash(other)
74
- end
75
- alias_method :eql?, :==
76
-
77
- def respond_to_missing?(key, include_private=false)
78
- key?(key) or @default.respond_to?(key) or super(key, include_private)
79
- end
80
-
81
- def key?(key)
82
- key = key.to_s
83
- @lookup.key?(key)
84
- end
85
-
86
- def clear
87
- @lookup.clear
88
- true
89
- end
90
- alias_method :refresh, :clear
91
-
92
- def forget(key)
93
- @lookup.delete(key.to_s)
94
- end
95
-
96
- def keys
97
- @lookup.keys
98
- end
99
-
100
- def to_hash
101
- @lookup.dup
102
- end
103
- alias_method :to_h, :to_hash
104
-
105
-
106
- def inspect
107
- key_str = keys.map { |key| "'#{key}'" }.join(",")
108
- "#<#{_clip_inspect(self)} local_keys=[#{key_str}] default=#{@default.inspect}>"
109
- end
110
-
111
- def pretty_print(q)
112
- q.text inspect[1..-1].gsub(INSPECT_REGEXP, "default=<")
113
- end
114
-
115
- private
116
- def _clip_inspect(obj)
117
- "#{obj.class}:0x%x" % obj.object_id << 1
118
- end
119
-
120
- def _dup(value)
121
- if NODUP.any? { |klass| klass === value }
122
- value
123
- else
124
- value.dup
125
- end
126
- end
127
-
128
- def try_convert_to_hash(obj)
129
- if Hash === obj
130
- obj
131
- elsif obj.respond_to?(:to_h)
132
- obj.to_h
133
- elsif obj.respond_to?(:to_hash)
134
- obj.to_hash
135
- else
136
- nil
137
- end
138
- end
139
- end
@@ -1,25 +0,0 @@
1
- module Pry::Config::Convenience
2
- SHORTCUTS = [
3
- :input,
4
- :output,
5
- :commands,
6
- :print,
7
- :exception_handler,
8
- :hooks,
9
- :color,
10
- :pager,
11
- :editor,
12
- :memory_size,
13
- :extra_sticky_locals
14
- ]
15
-
16
-
17
- def config_shortcut(*names)
18
- names.each do |name|
19
- reader = name
20
- setter = "#{name}="
21
- define_method(reader) { config.public_send(name) }
22
- define_method(setter) { |value| config.public_send(setter, value) }
23
- end
24
- end
25
- end
@@ -1,161 +0,0 @@
1
- class Pry::Config::Default
2
- include Pry::Config::Behavior
3
-
4
- default = {
5
- input: proc {
6
- lazy_readline
7
- },
8
- output: proc {
9
- $stdout
10
- },
11
- commands: proc {
12
- Pry::Commands
13
- },
14
- prompt_name: proc {
15
- Pry::DEFAULT_PROMPT_NAME
16
- },
17
- prompt: proc {
18
- Pry::DEFAULT_PROMPT
19
- },
20
- prompt_safe_objects: proc {
21
- Pry::DEFAULT_PROMPT_SAFE_OBJECTS
22
- },
23
- print: proc {
24
- Pry::DEFAULT_PRINT
25
- },
26
- quiet: proc {
27
- false
28
- },
29
- exception_handler: proc {
30
- Pry::DEFAULT_EXCEPTION_HANDLER
31
- },
32
- exception_whitelist: proc {
33
- Pry::DEFAULT_EXCEPTION_WHITELIST
34
- },
35
- hooks: proc {
36
- Pry::DEFAULT_HOOKS
37
- },
38
- pager: proc {
39
- true
40
- },
41
- system: proc {
42
- Pry::DEFAULT_SYSTEM
43
- },
44
- color: proc {
45
- Pry::Helpers::BaseHelpers.use_ansi_codes?
46
- },
47
- default_window_size: proc {
48
- 5
49
- },
50
- editor: proc {
51
- Pry.default_editor_for_platform
52
- }, # TODO: Pry::Platform.editor
53
- should_load_rc: proc {
54
- true
55
- },
56
- should_load_local_rc: proc {
57
- true
58
- },
59
- should_trap_interrupts: proc {
60
- Pry::Helpers::BaseHelpers.jruby?
61
- }, # TODO: Pry::Platform.jruby?
62
- disable_auto_reload: proc {
63
- false
64
- },
65
- command_prefix: proc {
66
- ""
67
- },
68
- auto_indent: proc {
69
- Pry::Helpers::BaseHelpers.use_ansi_codes?
70
- },
71
- correct_indent: proc {
72
- true
73
- },
74
- collision_warning: proc {
75
- false
76
- },
77
- output_prefix: proc {
78
- "=> "
79
- },
80
- requires: proc {
81
- []
82
- },
83
- should_load_requires: proc {
84
- true
85
- },
86
- should_load_plugins: proc {
87
- true
88
- },
89
- windows_console_warning: proc {
90
- true
91
- },
92
- control_d_handler: proc {
93
- Pry::DEFAULT_CONTROL_D_HANDLER
94
- },
95
- memory_size: proc {
96
- 100
97
- },
98
- extra_sticky_locals: proc {
99
- {}
100
- },
101
- command_completions: proc {
102
- proc { commands.keys }
103
- },
104
- file_completions: proc {
105
- proc { Dir["."] }
106
- },
107
- ls: proc {
108
- Pry::Config.from_hash(Pry::Command::Ls::DEFAULT_OPTIONS)
109
- },
110
- completer: proc {
111
- require "pry/input_completer"
112
- Pry::InputCompleter
113
- }
114
- }
115
-
116
- def initialize
117
- super(nil)
118
- configure_gist
119
- configure_history
120
- end
121
-
122
- default.each do |key, value|
123
- define_method(key) do
124
- if default[key].equal?(value)
125
- default[key] = instance_eval(&value)
126
- end
127
- default[key]
128
- end
129
- end
130
-
131
- private
132
- # TODO:
133
- # all of this configure_* stuff is a relic of old code.
134
- # we should try move this code to being command-local.
135
- def configure_gist
136
- self["gist"] = Pry::Config.from_hash(inspecter: proc(&:pretty_inspect))
137
- end
138
-
139
- def configure_history
140
- self["history"] = Pry::Config.from_hash "should_save" => true,
141
- "should_load" => true
142
- history.file = File.expand_path("~/.pry_history") rescue nil
143
- if history.file.nil?
144
- self.should_load_rc = false
145
- history.should_save = false
146
- history.should_load = false
147
- end
148
- end
149
-
150
- def lazy_readline
151
- require 'readline'
152
- Readline
153
- rescue LoadError
154
- warn "Sorry, you can't use Pry without Readline or a compatible library."
155
- warn "Possible solutions:"
156
- warn " * Rebuild Ruby with Readline support using `--with-readline`"
157
- warn " * Use the rb-readline gem, which is a pure-Ruby port of Readline"
158
- warn " * Use the pry-coolline gem, a pure-ruby alternative to Readline"
159
- raise
160
- end
161
- end
@@ -1,78 +0,0 @@
1
- class Pry
2
-
3
- # As a REPL, we often want to catch any unexpected exceptions that may have
4
- # been raised; however we don't want to go overboard and prevent the user
5
- # from exiting Pry when they want to.
6
- module RescuableException
7
- def self.===(exception)
8
- case exception
9
- # Catch when the user hits ^C (Interrupt < SignalException), and assume
10
- # that they just wanted to stop the in-progress command (just like bash
11
- # etc.)
12
- when Interrupt
13
- true
14
- # Don't catch signals (particularly not SIGTERM) as these are unlikely
15
- # to be intended for pry itself. We should also make sure that
16
- # Kernel#exit works.
17
- when *Pry.config.exception_whitelist
18
- false
19
- # All other exceptions will be caught.
20
- else
21
- true
22
- end
23
- end
24
- end
25
-
26
- # Catches SecurityErrors if $SAFE is set
27
- module Pry::TooSafeException
28
- def self.===(exception)
29
- $SAFE > 0 && SecurityError === exception
30
- end
31
- end
32
-
33
- # An Exception Tag (cf. Exceptional Ruby) that instructs Pry to show the error
34
- # in a more user-friendly manner. This should be used when the exception
35
- # happens within Pry itself as a direct consequence of the user typing
36
- # something wrong.
37
- #
38
- # This allows us to distinguish between the user typing:
39
- #
40
- # pry(main)> def )
41
- # SyntaxError: unexpected )
42
- #
43
- # pry(main)> method_that_evals("def )")
44
- # SyntaxError: (eval):1: syntax error, unexpected ')'
45
- # from ./a.rb:2 in `eval'
46
- module UserError; end
47
-
48
- # When we try to get a binding for an object, we try to define a method on
49
- # that Object's singleton class. This doesn't work for "frozen" Object's, and
50
- # the exception is just a vanilla RuntimeError.
51
- module FrozenObjectException
52
- def self.===(exception)
53
- ["can't modify frozen class/module",
54
- "can't modify frozen Class",
55
- "can't modify frozen object"
56
- ].include?(exception.message)
57
- end
58
- end
59
-
60
- # Don't catch these exceptions
61
- DEFAULT_EXCEPTION_WHITELIST = [SystemExit,
62
- SignalException,
63
- Pry::TooSafeException]
64
-
65
- # CommandErrors are caught by the REPL loop and displayed to the user. They
66
- # indicate an exceptional condition that's fatal to the current command.
67
- class CommandError < StandardError; end
68
- class MethodNotFound < CommandError; end
69
-
70
- # indicates obsolete API
71
- class ObsoleteError < StandardError; end
72
-
73
- # This is to keep from breaking under Rails 3.2 for people who are doing that
74
- # IRB = Pry thing.
75
- module ExtendCommandBundle
76
- end
77
-
78
- end
@@ -1,242 +0,0 @@
1
- # taken from irb
2
- # Implements tab completion for Readline in Pry
3
- class Pry::InputCompleter
4
- NUMERIC_REGEXP = /^(-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)\.([^.]*)$/
5
- ARRAY_REGEXP = /^([^\]]*\])\.([^.]*)$/
6
- SYMBOL_REGEXP = /^(:[^:.]*)$/
7
- SYMBOL_METHOD_CALL_REGEXP = /^(:[^:.]+)\.([^.]*)$/
8
- REGEX_REGEXP = /^(\/[^\/]*\/)\.([^.]*)$/
9
- PROC_OR_HASH_REGEXP = /^([^\}]*\})\.([^.]*)$/
10
- TOPLEVEL_LOOKUP_REGEXP = /^::([A-Z][^:\.\(]*)$/
11
- CONSTANT_REGEXP = /^([A-Z][A-Za-z0-9]*)$/
12
- CONSTANT_OR_METHOD_REGEXP = /^([A-Z].*)::([^:.]*)$/
13
- HEX_REGEXP = /^(-?0x[0-9a-fA-F_]+)\.([^.]*)$/
14
- GLOBALVARIABLE_REGEXP = /^(\$[^.]*)$/
15
- VARIABLE_REGEXP = /^([^."].*)\.([^.]*)$/
16
-
17
- ReservedWords = [
18
- "BEGIN", "END",
19
- "alias", "and",
20
- "begin", "break",
21
- "case", "class",
22
- "def", "defined", "do",
23
- "else", "elsif", "end", "ensure",
24
- "false", "for",
25
- "if", "in",
26
- "module",
27
- "next", "nil", "not",
28
- "or",
29
- "redo", "rescue", "retry", "return",
30
- "self", "super",
31
- "then", "true",
32
- "undef", "unless", "until",
33
- "when", "while",
34
- "yield" ]
35
-
36
- Operators = [
37
- "%", "&", "*", "**", "+", "-", "/",
38
- "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>",
39
- "[]", "[]=", "^", "!", "!=", "!~"
40
- ]
41
-
42
- WORD_ESCAPE_STR = " \t\n\"\\'`><=;|&{("
43
-
44
- def initialize(input, pry = nil)
45
- @pry = pry
46
- @input = input
47
- @input.basic_word_break_characters = WORD_ESCAPE_STR if @input.respond_to?(:basic_word_break_characters=)
48
- @input.completion_append_character = nil if @input.respond_to?(:completion_append_character=)
49
- end
50
-
51
- #
52
- # Return a new completion proc for use by Readline.
53
- #
54
- def call(str, options = {})
55
- custom_completions = options[:custom_completions] || []
56
- # if there are multiple contexts e.g. cd 1/2/3
57
- # get new target for 1/2 and find candidates for 3
58
- path, input = build_path(str)
59
-
60
- if path.call.empty?
61
- target = options[:target]
62
- else
63
- # Assume the user is tab-completing the 'cd' command
64
- begin
65
- target = Pry::ObjectPath.new(path.call, @pry.binding_stack).resolve.last
66
- # but if that doesn't work, assume they're doing division with no spaces
67
- rescue Pry::CommandError
68
- target = options[:target]
69
- end
70
- end
71
-
72
- begin
73
- bind = target
74
- # Complete stdlib symbols
75
- case input
76
- when REGEX_REGEXP # Regexp
77
- receiver = $1
78
- message = Regexp.quote($2)
79
- candidates = Regexp.instance_methods.collect(&:to_s)
80
- select_message(path, receiver, message, candidates)
81
- when ARRAY_REGEXP # Array
82
- receiver = $1
83
- message = Regexp.quote($2)
84
- candidates = Array.instance_methods.collect(&:to_s)
85
- select_message(path, receiver, message, candidates)
86
- when PROC_OR_HASH_REGEXP # Proc or Hash
87
- receiver = $1
88
- message = Regexp.quote($2)
89
- candidates = Proc.instance_methods.collect(&:to_s)
90
- candidates |= Hash.instance_methods.collect(&:to_s)
91
- select_message(path, receiver, message, candidates)
92
- when SYMBOL_REGEXP # Symbol
93
- if Symbol.respond_to?(:all_symbols)
94
- sym = Regexp.quote($1)
95
- candidates = Symbol.all_symbols.collect{|s| ":" << s.id2name}
96
- candidates.grep(/^#{sym}/)
97
- else
98
- []
99
- end
100
- when TOPLEVEL_LOOKUP_REGEXP # Absolute Constant or class methods
101
- receiver = $1
102
- candidates = Object.constants.collect(&:to_s)
103
- candidates.grep(/^#{receiver}/).collect{|e| "::" << e}
104
- when CONSTANT_REGEXP # Constant
105
- message = $1
106
- begin
107
- context = target.eval("self")
108
- context = context.class unless context.respond_to? :constants
109
- candidates = context.constants.collect(&:to_s)
110
- rescue
111
- candidates = []
112
- end
113
- candidates = candidates.grep(/^#{message}/).collect(&path)
114
- when CONSTANT_OR_METHOD_REGEXP # Constant or class methods
115
- receiver = $1
116
- message = Regexp.quote($2)
117
- begin
118
- candidates = eval("#{receiver}.constants.collect(&:to_s)", bind)
119
- candidates |= eval("#{receiver}.methods.collect(&:to_s)", bind)
120
- rescue Pry::RescuableException
121
- candidates = []
122
- end
123
- candidates.grep(/^#{message}/).collect{|e| receiver + "::" + e}
124
- when SYMBOL_METHOD_CALL_REGEXP # method call on a Symbol
125
- receiver = $1
126
- message = Regexp.quote($2)
127
- candidates = Symbol.instance_methods.collect(&:to_s)
128
- select_message(path, receiver, message, candidates)
129
- when NUMERIC_REGEXP
130
- # Numeric
131
- receiver = $1
132
- message = Regexp.quote($5)
133
- begin
134
- candidates = eval(receiver, bind).methods.collect(&:to_s)
135
- rescue Pry::RescuableException
136
- candidates = []
137
- end
138
- select_message(path, receiver, message, candidates)
139
- when HEX_REGEXP
140
- # Numeric(0xFFFF)
141
- receiver = $1
142
- message = Regexp.quote($2)
143
- begin
144
- candidates = eval(receiver, bind).methods.collect(&:to_s)
145
- rescue Pry::RescuableException
146
- candidates = []
147
- end
148
- select_message(path, receiver, message, candidates)
149
- when GLOBALVARIABLE_REGEXP # global
150
- regmessage = Regexp.new(Regexp.quote($1))
151
- candidates = global_variables.collect(&:to_s).grep(regmessage)
152
- when VARIABLE_REGEXP # variable
153
- receiver = $1
154
- message = Regexp.quote($2)
155
-
156
- gv = eval("global_variables", bind).collect(&:to_s)
157
- lv = eval("local_variables", bind).collect(&:to_s)
158
- cv = eval("self.class.constants", bind).collect(&:to_s)
159
-
160
- if (gv | lv | cv).include?(receiver) or /^[A-Z]/ =~ receiver && /\./ !~ receiver
161
- # foo.func and foo is local var. OR
162
- # Foo::Bar.func
163
- begin
164
- candidates = eval("#{receiver}.methods", bind).collect(&:to_s)
165
- rescue Pry::RescuableException
166
- candidates = []
167
- end
168
- else
169
- # func1.func2
170
- candidates = []
171
- ObjectSpace.each_object(Module){|m|
172
- begin
173
- name = m.name.to_s
174
- rescue Pry::RescuableException
175
- name = ""
176
- end
177
- next if name != "IRB::Context" and
178
- /^(IRB|SLex|RubyLex|RubyToken)/ =~ name
179
-
180
- # jruby doesn't always provide #instance_methods() on each
181
- # object.
182
- if m.respond_to?(:instance_methods)
183
- candidates.concat m.instance_methods(false).collect(&:to_s)
184
- end
185
- }
186
- candidates.sort!
187
- candidates.uniq!
188
- end
189
- select_message(path, receiver, message, candidates)
190
- when /^\.([^.]*)$/
191
- # Unknown(maybe String)
192
- receiver = ""
193
- message = Regexp.quote($1)
194
- candidates = String.instance_methods(true).collect(&:to_s)
195
- select_message(path, receiver, message, candidates)
196
- else
197
- candidates = eval(
198
- "methods | private_methods | local_variables | " \
199
- "self.class.constants | instance_variables",
200
- bind
201
- ).collect(&:to_s)
202
-
203
- if eval("respond_to?(:class_variables)", bind)
204
- candidates += eval("class_variables", bind).collect(&:to_s)
205
- end
206
- candidates = (candidates|ReservedWords|custom_completions).grep(/^#{Regexp.quote(input)}/)
207
- candidates.collect(&path)
208
- end
209
- rescue Pry::RescuableException
210
- []
211
- end
212
- end
213
-
214
- def select_message(path, receiver, message, candidates)
215
- candidates.grep(/^#{message}/).collect { |e|
216
- case e
217
- when /^[a-zA-Z_]/
218
- path.call(receiver + "." << e)
219
- when /^[0-9]/
220
- when *Operators
221
- #receiver + " " << e
222
- end
223
- }.compact
224
- end
225
-
226
- # build_path seperates the input into two parts: path and input.
227
- # input is the partial string that should be completed
228
- # path is a proc that takes an input and builds a full path.
229
- def build_path(input)
230
- # check to see if the input is a regex
231
- return proc {|i| i.to_s }, input if input[/\/\./]
232
- trailing_slash = input.end_with?('/')
233
- contexts = input.chomp('/').split(/\//)
234
- input = contexts[-1]
235
- path = proc do |i|
236
- p = contexts[0..-2].push(i).join('/')
237
- p += '/' if trailing_slash && !i.nil?
238
- p
239
- end
240
- return path, input
241
- end
242
- end