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
@@ -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