DebugClients/Ruby/Completer.rb

changeset 0
de9c2efb9d02
child 13
1af94a91f439
equal deleted inserted replaced
-1:000000000000 0:de9c2efb9d02
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2005 - 2009 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 =begin edoc
7 File implementing a command line completer class.
8 =end
9
10 #
11 # This code is mostly based on the completer found in irb of the Ruby package
12 # Original copyright
13 # by Keiju ISHITSUKA(keiju@ishitsuka.com)
14 # From Original Idea of shugo@ruby-lang.org
15 #
16
17 if RUBY_VERSION < "1.9"
18 $KCODE = 'UTF8'
19 require 'jcode'
20 end
21
22 class Completer
23 =begin edoc
24 Class implementing a command completer.
25 =end
26 ReservedWords = [
27 "BEGIN", "END",
28 "alias", "and",
29 "begin", "break",
30 "case", "class",
31 "def", "defined", "do",
32 "else", "elsif", "end", "ensure",
33 "false", "for",
34 "if", "in",
35 "module",
36 "next", "nil", "not",
37 "or",
38 "redo", "rescue", "retry", "return",
39 "self", "super",
40 "then", "true",
41 "undef", "unless", "until",
42 "when", "while",
43 "yield",
44 ]
45
46 def initialize(binding)
47 =begin edoc
48 constructor
49
50 @param binding binding object used to determine the possible completions
51 =end
52 @binding = binding
53 end
54
55 def complete(input)
56 =begin edoc
57 Public method to select the possible completions
58
59 @param input text to be completed (String)
60 @return list of possible completions (Array)
61 =end
62 case input
63 when /^(\/[^\/]*\/)\.([^.]*)$/
64 # Regexp
65 receiver = $1
66 message = Regexp.quote($2)
67
68 candidates = Regexp.instance_methods(true)
69 select_message(receiver, message, candidates)
70
71 when /^([^\]]*\])\.([^.]*)$/
72 # Array
73 receiver = $1
74 message = Regexp.quote($2)
75
76 candidates = Array.instance_methods(true)
77 select_message(receiver, message, candidates)
78
79 when /^([^\}]*\})\.([^.]*)$/
80 # Proc or Hash
81 receiver = $1
82 message = Regexp.quote($2)
83
84 candidates = Proc.instance_methods(true) | Hash.instance_methods(true)
85 select_message(receiver, message, candidates)
86
87 when /^(:[^:.]*)$/
88 # Symbol
89 if Symbol.respond_to?(:all_symbols)
90 sym = $1
91 candidates = Symbol.all_symbols.collect{|s| ":" + s.id2name}
92 candidates.grep(/^#{sym}/)
93 else
94 []
95 end
96
97 when /^::([A-Z][^:\.\(]*)$/
98 # Absolute Constant or class methods
99 receiver = $1
100 candidates = Object.constants
101 candidates.grep(/^#{receiver}/).collect{|e| "::" + e}
102
103 when /^(((::)?[A-Z][^:.\(]*)+)::?([^:.]*)$/
104 # Constant or class methods
105 receiver = $1
106 message = Regexp.quote($4)
107 begin
108 candidates = eval("#{receiver}.constants | #{receiver}.methods", @binding)
109 rescue Exception
110 candidates = []
111 end
112 candidates.grep(/^#{message}/).collect{|e| receiver + "::" + e}
113
114 when /^(:[^:.]+)\.([^.]*)$/
115 # Symbol
116 receiver = $1
117 message = Regexp.quote($2)
118
119 candidates = Symbol.instance_methods(true)
120 select_message(receiver, message, candidates)
121
122 when /^([0-9_]+(\.[0-9_]+)?(e[0-9]+)?)\.([^.]*)$/
123 # Numeric
124 receiver = $1
125 message = Regexp.quote($4)
126
127 begin
128 candidates = eval(receiver, @binding).methods
129 rescue Exception
130 candidates
131 end
132 select_message(receiver, message, candidates)
133
134 when /^(\$[^.]*)$/
135 # Global variable
136 candidates = global_variables.grep(Regexp.new(Regexp.quote($1)))
137
138 # when /^(\$?(\.?[^.]+)+)\.([^.]*)$/
139 when /^((\.?[^.]+)+)\.([^.]*)$/
140 # variable
141 receiver = $1
142 message = Regexp.quote($3)
143
144 gv = eval("global_variables", @binding)
145 lv = eval("local_variables", @binding)
146 cv = eval("self.class.constants", @binding)
147
148 if (gv | lv | cv).include?(receiver)
149 # foo.func and foo is local var.
150 candidates = eval("#{receiver}.methods", @binding)
151 elsif /^[A-Z]/ =~ receiver and /\./ !~ receiver
152 # Foo::Bar.func
153 begin
154 candidates = eval("#{receiver}.methods", @binding)
155 rescue Exception
156 candidates = []
157 end
158 else
159 # func1.func2
160 candidates = []
161 ObjectSpace.each_object(Module){|m|
162 next if m.name != "IRB::Context" and
163 /^(IRB|SLex|RubyLex|RubyToken)/ =~ m.name
164 candidates.concat m.instance_methods(false)
165 }
166 candidates.sort!
167 candidates.uniq!
168 end
169 select_message(receiver, message, candidates)
170
171 when /^\.([^.]*)$/
172 # unknown(maybe String)
173
174 receiver = ""
175 message = Regexp.quote($1)
176
177 candidates = String.instance_methods(true)
178 select_message(receiver, message, candidates)
179
180 else
181 candidates = eval("methods | private_methods | local_variables | self.class.constants", @binding)
182
183 (candidates|ReservedWords).grep(/^#{Regexp.quote(input)}/)
184 end
185 end
186
187 Operators = ["%", "&", "*", "**", "+", "-", "/",
188 "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>",
189 "[]", "[]=", "^",]
190
191 def select_message(receiver, message, candidates)
192 =begin edoc
193 Method used to pick completion candidates.
194
195 @param receiver object receiving the message
196 @param message message to be sent to object
197 @param candidates possible completion candidates
198 @return filtered list of candidates
199 =end
200 candidates.grep(/^#{message}/).collect do |e|
201 case e
202 when /^[a-zA-Z_]/
203 receiver + "." + e
204 when /^[0-9]/
205 when *Operators
206 #receiver + " " + e
207 end
208 end
209 end
210 end

eric ide

mercurial