DebugClients/Ruby/Completer.rb

changeset 2438
61bfcff921d8
parent 2302
f29e9405c851
child 3160
209a07d7e401
equal deleted inserted replaced
2436:f75dbdd22959 2438:61bfcff921d8
11 # This code is mostly based on the completer found in irb of the Ruby package 11 # This code is mostly based on the completer found in irb of the Ruby package
12 # Original copyright 12 # Original copyright
13 # by Keiju ISHITSUKA(keiju@ishitsuka.com) 13 # by Keiju ISHITSUKA(keiju@ishitsuka.com)
14 # From Original Idea of shugo@ruby-lang.org 14 # From Original Idea of shugo@ruby-lang.org
15 # 15 #
16
17 if RUBY_VERSION < "1.9"
18 $KCODE = 'UTF8'
19 require 'jcode'
20 end
21 16
22 class Completer 17 class Completer
23 =begin edoc 18 =begin edoc
24 Class implementing a command completer. 19 Class implementing a command completer.
25 =end 20 =end
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

eric ide

mercurial