58 |
53 |
59 @param input text to be completed (String) |
54 @param input text to be completed (String) |
60 @return list of possible completions (Array) |
55 @return list of possible completions (Array) |
61 =end |
56 =end |
62 case input |
57 case input |
|
58 when /^((["'`]).*\2)\.([^.]*)$/ |
|
59 # String |
|
60 receiver = $1 |
|
61 message = $3 |
|
62 |
|
63 candidates = String.instance_methods.collect{|m| m.to_s} |
|
64 select_message(receiver, message, candidates) |
|
65 |
63 when /^(\/[^\/]*\/)\.([^.]*)$/ |
66 when /^(\/[^\/]*\/)\.([^.]*)$/ |
64 # Regexp |
67 # Regexp |
65 receiver = $1 |
68 receiver = $1 |
66 message = Regexp.quote($2) |
69 message = Regexp.quote($2) |
67 |
70 |
68 candidates = Regexp.instance_methods(true) |
71 candidates = Regexp.instance_methods.collect{|m| m.to_s} |
69 select_message(receiver, message, candidates) |
72 select_message(receiver, message, candidates) |
70 |
73 |
71 when /^([^\]]*\])\.([^.]*)$/ |
74 when /^([^\]]*\])\.([^.]*)$/ |
72 # Array |
75 # Array |
73 receiver = $1 |
76 receiver = $1 |
74 message = Regexp.quote($2) |
77 message = Regexp.quote($2) |
75 |
78 |
76 candidates = Array.instance_methods(true) |
79 candidates = Array.instance_methods.collect{|m| m.to_s} |
77 select_message(receiver, message, candidates) |
80 select_message(receiver, message, candidates) |
78 |
81 |
79 when /^([^\}]*\})\.([^.]*)$/ |
82 when /^([^\}]*\})\.([^.]*)$/ |
80 # Proc or Hash |
83 # Proc or Hash |
81 receiver = $1 |
84 receiver = $1 |
82 message = Regexp.quote($2) |
85 message = Regexp.quote($2) |
83 |
86 |
84 candidates = Proc.instance_methods(true) | Hash.instance_methods(true) |
87 candidates = Proc.instance_methods.collect{|m| m.to_s} |
|
88 candidates |= Hash.instance_methods.collect{|m| m.to_s} |
85 select_message(receiver, message, candidates) |
89 select_message(receiver, message, candidates) |
86 |
90 |
87 when /^(:[^:.]*)$/ |
91 when /^(:[^:.]*)$/ |
88 # Symbol |
92 # Symbol |
89 if Symbol.respond_to?(:all_symbols) |
93 if Symbol.respond_to?(:all_symbols) |
95 end |
99 end |
96 |
100 |
97 when /^::([A-Z][^:\.\(]*)$/ |
101 when /^::([A-Z][^:\.\(]*)$/ |
98 # Absolute Constant or class methods |
102 # Absolute Constant or class methods |
99 receiver = $1 |
103 receiver = $1 |
100 candidates = Object.constants |
104 candidates = Object.constants.collect{|m| m.to_s} |
101 candidates.grep(/^#{receiver}/).collect{|e| "::" + e} |
105 candidates.grep(/^#{receiver}/).collect{|e| "::" + e} |
102 |
106 |
103 when /^(((::)?[A-Z][^:.\(]*)+)::?([^:.]*)$/ |
107 when /^([A-Z].*)::([^:.]*)$/ |
104 # Constant or class methods |
108 # Constant or class methods |
105 receiver = $1 |
109 receiver = $1 |
106 message = Regexp.quote($4) |
110 message = Regexp.quote($4) |
107 begin |
111 begin |
108 candidates = eval("#{receiver}.constants | #{receiver}.methods", @binding) |
112 candidates = eval("#{receiver}.constants.collect{|m| m.to_s}", bind) |
|
113 candidates |= eval("#{receiver}.methods.collect{|m| m.to_s}", bind) |
109 rescue Exception |
114 rescue Exception |
110 candidates = [] |
115 candidates = [] |
111 end |
116 end |
112 candidates.grep(/^#{message}/).collect{|e| receiver + "::" + e} |
117 select_message(receiver, message, candidates, "::") |
113 |
118 |
114 when /^(:[^:.]+)\.([^.]*)$/ |
119 when /^(:[^:.]+)(\.|::)([^.]*)$/ |
115 # Symbol |
120 # Symbol |
116 receiver = $1 |
121 receiver = $1 |
117 message = Regexp.quote($2) |
122 sep = $2 |
118 |
123 message = Regexp.quote($3) |
119 candidates = Symbol.instance_methods(true) |
124 |
120 select_message(receiver, message, candidates) |
125 candidates = Symbol.instance_methods.collect{|m| m.to_s} |
121 |
126 select_message(receiver, message, candidates, sep) |
122 when /^([0-9_]+(\.[0-9_]+)?(e[0-9]+)?)\.([^.]*)$/ |
127 |
|
128 when /^(-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)(\.|::)([^.]*)$/ |
123 # Numeric |
129 # Numeric |
124 receiver = $1 |
130 receiver = $1 |
125 message = Regexp.quote($4) |
131 sep = $5 |
|
132 message = Regexp.quote($6) |
126 |
133 |
127 begin |
134 begin |
128 candidates = eval(receiver, @binding).methods |
135 candidates = eval(receiver, @binding).methods.collect{|m| m.to_s} |
129 rescue Exception |
136 rescue Exception |
130 candidates |
137 candidates |
131 end |
138 end |
132 select_message(receiver, message, candidates) |
139 select_message(receiver, message, candidates, sep) |
|
140 |
|
141 when /^(-?0x[0-9a-fA-F_]+)(\.|::)([^.]*)$/ |
|
142 # Numeric(0xFFFF) |
|
143 receiver = $1 |
|
144 sep = $2 |
|
145 message = Regexp.quote($3) |
|
146 |
|
147 begin |
|
148 candidates = eval(receiver, bind).methods.collect{|m| m.to_s} |
|
149 rescue Exception |
|
150 candidates = [] |
|
151 end |
|
152 select_message(receiver, message, candidates, sep) |
133 |
153 |
134 when /^(\$[^.]*)$/ |
154 when /^(\$[^.]*)$/ |
135 # Global variable |
155 # Global variable |
136 candidates = global_variables.grep(Regexp.new(Regexp.quote($1))) |
156 candidates = global_variables.grep(Regexp.new(Regexp.quote($1))) |
137 |
157 |
138 ## when /^(\$?(\.?[^.]+)+)\.([^.]*)$/ |
158 when /^([^."].*)(\.|::)([^.]*)$/ |
139 when /^((\.?[^.]+)+)\.([^.]*)$/ |
159 # variable.func or func.func |
140 # variable |
160 receiver = $1 |
141 receiver = $1 |
161 sep = $2 |
142 message = Regexp.quote($3) |
162 message = Regexp.quote($3) |
143 |
163 |
144 gv = eval("global_variables", @binding) |
164 gv = eval("global_variables", @binding).collect{|m| m.to_s} |
145 lv = eval("local_variables", @binding) |
165 lv = eval("local_variables", @binding).collect{|m| m.to_s} |
146 cv = eval("self.class.constants", @binding) |
166 cv = eval("self.class.constants", @binding).collect{|m| m.to_s} |
147 |
167 |
148 if (gv | lv | cv).include?(receiver) |
168 if (gv | lv | cv).include?(receiver) or \ |
149 # foo.func and foo is local var. |
169 /^[A-Z]/ =~ receiver && /\./ !~ receiver |
150 candidates = eval("#{receiver}.methods", @binding) |
170 # foo.func and foo is var. OR |
151 elsif /^[A-Z]/ =~ receiver and /\./ !~ receiver |
171 # foo::func and foo is var. OR |
|
172 # foo::Const and foo is var. OR |
152 # Foo::Bar.func |
173 # Foo::Bar.func |
153 begin |
174 begin |
154 candidates = eval("#{receiver}.methods", @binding) |
175 candidates = [] |
|
176 rec = eval(receiver, bind) |
|
177 if sep == "::" and rec.kind_of?(Module) |
|
178 candidates = rec.constants.collect{|m| m.to_s} |
|
179 end |
|
180 candidates |= rec.methods.collect{|m| m.to_s} |
155 rescue Exception |
181 rescue Exception |
156 candidates = [] |
182 candidates = [] |
157 end |
183 end |
158 else |
184 else |
159 # func1.func2 |
185 # func1.func2 |
160 candidates = [] |
186 candidates = [] |
161 ObjectSpace.each_object(Module){|m| |
187 ObjectSpace.each_object(Module){|m| |
162 next if m.name != "IRB::Context" and |
188 begin |
163 /^(IRB|SLex|RubyLex|RubyToken)/ =~ m.name |
189 name = m.name |
164 candidates.concat m.instance_methods(false) |
190 rescue Exception |
|
191 name = "" |
|
192 end |
|
193 begin |
|
194 next if m.name != "IRB::Context" and |
|
195 /^(IRB|SLex|RubyLex|RubyToken)/ =~ m.name |
|
196 rescue Exception |
|
197 next |
|
198 end |
|
199 candidates.concat m.instance_methods(false).collect{|x| x.to_s} |
165 } |
200 } |
166 candidates.sort! |
201 candidates.sort! |
167 candidates.uniq! |
202 candidates.uniq! |
168 end |
203 end |
169 select_message(receiver, message, candidates) |
204 select_message(receiver, message, candidates, sep) |
170 |
205 |
171 when /^\.([^.]*)$/ |
206 when /^\.([^.]*)$/ |
172 # unknown(maybe String) |
207 # unknown(maybe String) |
173 |
208 |
174 receiver = "" |
209 receiver = "" |
175 message = Regexp.quote($1) |
210 message = Regexp.quote($1) |
176 |
211 |
177 candidates = String.instance_methods(true) |
212 candidates = String.instance_methods(true).collect{|m| m.to_s} |
178 select_message(receiver, message, candidates) |
213 select_message(receiver, message, candidates) |
179 |
214 |
180 else |
215 else |
181 candidates = eval("methods | private_methods | local_variables | self.class.constants", @binding) |
216 candidates = eval( |
|
217 "methods | private_methods | local_variables | self.class.constants", |
|
218 @binding).collect{|m| m.to_s} |
182 |
219 |
183 (candidates|ReservedWords).grep(/^#{Regexp.quote(input)}/) |
220 (candidates|ReservedWords).grep(/^#{Regexp.quote(input)}/) |
184 end |
221 end |
185 end |
222 end |
186 |
223 |
187 Operators = ["%", "&", "*", "**", "+", "-", "/", |
224 Operators = ["%", "&", "*", "**", "+", "-", "/", |
188 "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>", |
225 "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>", |
189 "[]", "[]=", "^",] |
226 "[]", "[]=", "^", "!", "!=", "!~"] |
190 |
227 |
191 def select_message(receiver, message, candidates) |
228 def select_message(receiver, message, candidates, sep = ".") |
192 =begin edoc |
229 =begin edoc |
193 Method used to pick completion candidates. |
230 Method used to pick completion candidates. |
194 |
231 |
195 @param receiver object receiving the message |
232 @param receiver object receiving the message |
196 @param message message to be sent to object |
233 @param message message to be sent to object |
197 @param candidates possible completion candidates |
234 @param candidates possible completion candidates |
|
235 @param sep separater string |
198 @return filtered list of candidates |
236 @return filtered list of candidates |
199 =end |
237 =end |
200 candidates.grep(/^#{message}/).collect do |e| |
238 candidates.grep(/^#{message}/).collect do |e| |
201 case e |
239 case e |
202 when /^[a-zA-Z_]/ |
240 when /^[a-zA-Z_]/ |
203 receiver + "." + e |
241 receiver + sep + e |
204 when /^[0-9]/ |
242 when /^[0-9]/ |
205 when *Operators |
243 when *Operators |
206 #receiver + " " + e |
244 #receiver + " " + e |
207 end |
245 end |
208 end |
246 end |