Imported File#ftype spec from rubyspecs.
[rbx.git] / lib / irb / completion.rb
blobaebb6f0c5e159c09422169dd3663a9c29d5ea7fa
2 #   irb/completor.rb - 
3 #       $Release Version: 0.9$
4 #       $Revision: 11708 $
5 #       $Date: 2007-02-12 15:01:19 -0800 (Mon, 12 Feb 2007) $
6 #       by Keiju ISHITSUKA(keiju@ishitsuka.com)
7 #       From Original Idea of shugo@ruby-lang.org
10 require "readline"
12 module IRB
13   module InputCompletor
15     @RCS_ID='-$Id: completion.rb 11708 2007-02-12 23:01:19Z shyouhei $-'
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}"
42       case input
43       when /^(\/[^\/]*\/)\.([^.]*)$/
44         # Regexp
45         receiver = $1
46         message = Regexp.quote($2)
48         candidates = Regexp.instance_methods(true)
49         select_message(receiver, message, candidates)
51       when /^([^\]]*\])\.([^.]*)$/
52         # Array
53         receiver = $1
54         message = Regexp.quote($2)
56         candidates = Array.instance_methods(true)
57         select_message(receiver, message, candidates)
59       when /^([^\}]*\})\.([^.]*)$/
60         # Proc or Hash
61         receiver = $1
62         message = Regexp.quote($2)
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
77       when /^::([A-Z][^:\.\(]*)$/
78         # Absolute Constant or class methods
79         receiver = $1
80         candidates = Object.constants
81         candidates.grep(/^#{receiver}/).collect{|e| "::" + e}
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}
94       when /^(:[^:.]+)\.([^.]*)$/
95         # Symbol
96         receiver = $1
97         message = Regexp.quote($2)
99         candidates = Symbol.instance_methods(true)
100         select_message(receiver, message, candidates)
102       when /^(-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)\.([^.]*)$/
103         # Numeric
104         receiver = $1
105         message = Regexp.quote($5)
107         begin
108           candidates = eval(receiver, bind).methods
109         rescue Exception
110           candidates = []
111         end
112         select_message(receiver, message, candidates)
114       when /^(-?0x[0-9a-fA-F_]+)\.([^.]*)$/
115         # Numeric(0xFFFF)
116         receiver = $1
117         message = Regexp.quote($2)
119         begin
120           candidates = eval(receiver, bind).methods
121         rescue Exception
122           candidates = []
123         end
124         select_message(receiver, message, candidates)
126       when /^(\$[^.]*)$/
127         candidates = global_variables.grep(Regexp.new(Regexp.quote($1)))
129 #      when /^(\$?(\.?[^.]+)+)\.([^.]*)$/
130       when /^((\.?[^.]+)+)\.([^.]*)$/
131         # variable
132         receiver = $1
133         message = Regexp.quote($3)
135         gv = eval("global_variables", bind)
136         lv = eval("local_variables", bind)
137         cv = eval("self.class.constants", bind)
138         
139         if (gv | lv | cv).include?(receiver)
140           # foo.func and foo is local var.
141           candidates = eval("#{receiver}.methods", bind)
142         elsif /^[A-Z]/ =~ receiver and /\./ !~ receiver
143           # Foo::Bar.func
144           begin
145             candidates = eval("#{receiver}.methods", bind)
146           rescue Exception
147             candidates = []
148           end
149         else
150           # func1.func2
151           candidates = []
152           ObjectSpace.each_object(Module){|m|
153             begin
154               name = m.name
155             rescue Exception
156               name = ""
157             end
158             next if name != "IRB::Context" and 
159               /^(IRB|SLex|RubyLex|RubyToken)/ =~ name
160             candidates.concat m.instance_methods(false)
161           }
162           candidates.sort!
163           candidates.uniq!
164         end
165         select_message(receiver, message, candidates)
167       when /^\.([^.]*)$/
168         # unknown(maybe String)
170         receiver = ""
171         message = Regexp.quote($1)
173         candidates = String.instance_methods(true)
174         select_message(receiver, message, candidates)
176       else
177         candidates = eval("methods | private_methods | local_variables | self.class.constants", bind)
178                           
179         (candidates|ReservedWords).grep(/^#{Regexp.quote(input)}/)
180       end
181     }
183     Operators = ["%", "&", "*", "**", "+",  "-",  "/",
184       "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>",
185       "[]", "[]=", "^",]
187     def self.select_message(receiver, message, candidates)
188       candidates.grep(/^#{message}/).collect do |e|
189         case e
190         when /^[a-zA-Z_]/
191           receiver + "." + e
192         when /^[0-9]/
193         when *Operators
194           #receiver + " " + e
195         end
196       end
197     end
198   end
201 if Readline.respond_to?("basic_word_break_characters=")
202   Readline.basic_word_break_characters= " \t\n\"\\'`><=;|&{("
204 Readline.completion_append_character = nil
205 Readline.completion_proc = IRB::InputCompletor::CompletionProc