lib/irb/completion.rb
DEFINITIONS
This source file includes following functions.
1 #
2 # irb/completor.rb -
3 # $Release Version: 0.9$
4 # $Revision: 1.3 $
5 # $Date: 2002/07/09 11:17:16 $
6 # by Keiju ISHITSUKA(keiju@ishitsuka.com)
7 # From Original Idea of shugo@ruby-lang.org
8 #
9
10 require "readline"
11
12 module IRB
13 module InputCompletor
14
15 @RCS_ID='-$Id: completion.rb,v 1.3 2002/07/09 11:17:16 keiju Exp $-'
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
37 CompletionProc = proc { |input|
38 bind = IRB.conf[:MAIN_CONTEXT].workspace.binding
39
40 # puts "input: #{input}"
41
42 case input
43 when /^(\/[^\/]*\/)\.([^.]*)$/
44 # Regexp
45 receiver = $1
46 message = Regexp.quote($2)
47
48 candidates = Regexp.instance_methods(true)
49 select_message(receiver, message, candidates)
50
51 when /^([^\]]*\])\.([^.]*)$/
52 # Array
53 receiver = $1
54 message = Regexp.quote($2)
55
56 candidates = Array.instance_methods(true)
57 select_message(receiver, message, candidates)
58
59 when /^([^\}]*\})\.([^.]*)$/
60 # Proc or Hash
61 receiver = $1
62 message = Regexp.quote($2)
63
64 candidates = Proc.instance_methods(true) | Hash.instance_methods(true)
65 select_message(receiver, message, candidates)
66
67 when /^(:[^:.]*)$/
68 # Symbol
69 if Symbol.respond_to?(:all_symbols)
70 sym = $1
71 candidates = Symbol.all_symbols.collect{|s| ":" + s.id2name}
72 candidates.grep(/^#{sym}/)
73 else
74 []
75 end
76
77 when /^::([A-Z][^:\.\(]*)$/
78 # Absolute Constant or class methods
79 receiver = $1
80 candidates = Object.constants
81 candidates.grep(/^#{receiver}/).collect{|e| "::" + e}
82
83 when /^(((::)?[A-Z][^:.\(]*)+)::?([^:.]*)$/
84 # Constant or class methods
85 receiver = $1
86 message = Regexp.quote($4)
87 begin
88 candidates = eval("#{receiver}.constants | #{receiver}.methods", bind)
89 rescue Exception
90 candidates = []
91 end
92 candidates.grep(/^#{message}/).collect{|e| receiver + "::" + e}
93
94 when /^(:[^:.]+)\.([^.]*)$/
95 # Symbol
96 receiver = $1
97 message = Regexp.quote($2)
98
99 candidates = Symbol.instance_methods(true)
100 select_message(receiver, message, candidates)
101
102 when /^([0-9_]+(\.[0-9_]+)?(e[0-9]+)?)\.([^.]*)$/
103 # Numeric
104 receiver = $1
105 message = Regexp.quote($4)
106
107 begin
108 candidates = eval(receiver, bind).methods
109 rescue Exception
110 candidates
111 end
112 select_message(receiver, message, candidates)
113
114 when /^(\$[^.]*)$/
115 candidates = global_variables.grep Regexp.new(Regexp.quote($1))
116
117 # when /^(\$?(\.?[^.]+)+)\.([^.]*)$/
118 when /^((\.?[^.]+)+)\.([^.]*)$/
119 # variable
120 receiver = $1
121 message = Regexp.quote($3)
122
123 gv = eval "global_variables", bind
124 lv = eval "local_variables", bind
125 cv = eval "type.constants", bind
126
127 if (gv | lv | cv).include?(receiver)
128 # foo.func and foo is local var.
129 candidates = eval("#{receiver}.methods", bind)
130 elsif /^[A-Z]/ =~ receiver and /\./ !~ receiver
131 # Foo::Bar.func
132 begin
133 candidates = eval("#{receiver}.methods", bind)
134 rescue Exception
135 candidates = []
136 end
137 else
138 # func1.func2
139 candidates = []
140 ObjectSpace.each_object(Module){|m|
141 next if m.name != "IRB::Context" and
142 /^(IRB|SLex|RubyLex|RubyToken)/ =~ m.name
143 candidates.concat m.instance_methods
144 }
145 candidates.sort!
146 candidates.uniq!
147 end
148 select_message(receiver, message, candidates)
149
150 when /^\.([^.]*)$/
151 # unknown(maybe String)
152
153 receiver = ""
154 message = Regexp.quote($1)
155
156 candidates = String.instance_methods(true)
157 select_message(receiver, message, candidates)
158
159 else
160 candidates = eval("methods | private_methods | local_variables | type.constants", bind)
161
162 (candidates|ReservedWords).grep(/^#{Regexp.quote(input)}/)
163 end
164 }
165
166 Operators = ["%", "&", "*", "**", "+", "-", "/",
167 "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>",
168 "[]", "[]=", "^",]
169
170 def self.select_message(receiver, message, candidates)
171 candidates.grep(/^#{message}/).collect do |e|
172 case e
173 when /^[a-zA-Z_]/
174 receiver + "." + e
175 when /^[0-9]/
176 when *Operators
177 #receiver + " " + e
178 end
179 end
180 end
181 end
182 end
183
184 if Readline.respond_to?("basic_word_break_characters=")
185 Readline.basic_word_break_characters= "\t\n\"\\'`><=;|&{("
186 end
187 Readline.completion_append_character = nil
188 Readline.completion_proc = IRB::InputCompletor::CompletionProc