DebugClients/Ruby/Completer.rb

changeset 2438
61bfcff921d8
parent 2302
f29e9405c851
child 3160
209a07d7e401
--- a/DebugClients/Ruby/Completer.rb	Thu Feb 28 16:57:45 2013 +0100
+++ b/DebugClients/Ruby/Completer.rb	Sat Mar 02 15:05:29 2013 +0100
@@ -14,11 +14,6 @@
 #       From Original Idea of shugo@ruby-lang.org
 #
 
-if RUBY_VERSION < "1.9"
-    $KCODE = 'UTF8'
-    require 'jcode'
-end
-
 class Completer
 =begin edoc
 Class implementing a command completer.
@@ -60,12 +55,20 @@
 @return list of possible completions (Array)
 =end
         case input
+        when /^((["'`]).*\2)\.([^.]*)$/
+        # String
+            receiver = $1
+            message = $3
+            
+            candidates = String.instance_methods.collect{|m| m.to_s}
+            select_message(receiver, message, candidates)
+
         when /^(\/[^\/]*\/)\.([^.]*)$/
         # Regexp
             receiver = $1
             message = Regexp.quote($2)
 
-            candidates = Regexp.instance_methods(true)
+            candidates = Regexp.instance_methods.collect{|m| m.to_s}
             select_message(receiver, message, candidates)
 
         when /^([^\]]*\])\.([^.]*)$/
@@ -73,7 +76,7 @@
             receiver = $1
             message = Regexp.quote($2)
 
-            candidates = Array.instance_methods(true)
+            candidates = Array.instance_methods.collect{|m| m.to_s}
             select_message(receiver, message, candidates)
 
         when /^([^\}]*\})\.([^.]*)$/
@@ -81,7 +84,8 @@
             receiver = $1
             message = Regexp.quote($2)
 
-            candidates = Proc.instance_methods(true) | Hash.instance_methods(true)
+            candidates = Proc.instance_methods.collect{|m| m.to_s}
+            candidates |= Hash.instance_methods.collect{|m| m.to_s}
             select_message(receiver, message, candidates)
     
         when /^(:[^:.]*)$/
@@ -97,61 +101,83 @@
         when /^::([A-Z][^:\.\(]*)$/
         # Absolute Constant or class methods
             receiver = $1
-            candidates = Object.constants
+            candidates = Object.constants.collect{|m| m.to_s}
             candidates.grep(/^#{receiver}/).collect{|e| "::" + e}
 
-        when /^(((::)?[A-Z][^:.\(]*)+)::?([^:.]*)$/
+        when /^([A-Z].*)::([^:.]*)$/
         # Constant or class methods
             receiver = $1
             message = Regexp.quote($4)
             begin
-                candidates = eval("#{receiver}.constants | #{receiver}.methods", @binding)
+                candidates = eval("#{receiver}.constants.collect{|m| m.to_s}", bind)
+                candidates |= eval("#{receiver}.methods.collect{|m| m.to_s}", bind)
             rescue Exception
                 candidates = []
             end
-            candidates.grep(/^#{message}/).collect{|e| receiver + "::" + e}
+            select_message(receiver, message, candidates, "::")
 
-        when /^(:[^:.]+)\.([^.]*)$/
+        when /^(:[^:.]+)(\.|::)([^.]*)$/
         # Symbol
             receiver = $1
-            message = Regexp.quote($2)
+            sep = $2
+            message = Regexp.quote($3)
 
-            candidates = Symbol.instance_methods(true)
-            select_message(receiver, message, candidates)
+            candidates = Symbol.instance_methods.collect{|m| m.to_s}
+            select_message(receiver, message, candidates, sep)
 
-        when /^([0-9_]+(\.[0-9_]+)?(e[0-9]+)?)\.([^.]*)$/
+        when /^(-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)(\.|::)([^.]*)$/
         # Numeric
             receiver = $1
-            message = Regexp.quote($4)
+            sep = $5
+            message = Regexp.quote($6)
 
             begin
-                candidates = eval(receiver, @binding).methods
+                candidates = eval(receiver, @binding).methods.collect{|m| m.to_s}
             rescue Exception
                 candidates
             end
-            select_message(receiver, message, candidates)
+            select_message(receiver, message, candidates, sep)
+
+        when /^(-?0x[0-9a-fA-F_]+)(\.|::)([^.]*)$/
+        # Numeric(0xFFFF)
+            receiver = $1
+            sep = $2
+            message = Regexp.quote($3)
+            
+            begin
+                candidates = eval(receiver, bind).methods.collect{|m| m.to_s}
+            rescue Exception
+                candidates = []
+            end
+            select_message(receiver, message, candidates, sep)
 
         when /^(\$[^.]*)$/
         # Global variable
             candidates = global_variables.grep(Regexp.new(Regexp.quote($1)))
 
-##        when /^(\$?(\.?[^.]+)+)\.([^.]*)$/
-        when /^((\.?[^.]+)+)\.([^.]*)$/
-        # variable
+        when /^([^."].*)(\.|::)([^.]*)$/
+        # variable.func or func.func
             receiver = $1
+            sep = $2
             message = Regexp.quote($3)
 
-            gv = eval("global_variables", @binding)
-            lv = eval("local_variables", @binding)
-            cv = eval("self.class.constants", @binding)
+            gv = eval("global_variables", @binding).collect{|m| m.to_s}
+            lv = eval("local_variables", @binding).collect{|m| m.to_s}
+            cv = eval("self.class.constants", @binding).collect{|m| m.to_s}
     
-            if (gv | lv | cv).include?(receiver)
-                # foo.func and foo is local var.
-                candidates = eval("#{receiver}.methods", @binding)
-            elsif /^[A-Z]/ =~ receiver and /\./ !~ receiver
+            if (gv | lv | cv).include?(receiver) or \
+                /^[A-Z]/ =~ receiver && /\./ !~ receiver
+                # foo.func and foo is var. OR
+                # foo::func and foo is var. OR
+                # foo::Const and foo is var. OR
                 # Foo::Bar.func
                 begin
-                    candidates = eval("#{receiver}.methods", @binding)
+                    candidates = []
+                    rec = eval(receiver, bind)
+                    if sep == "::" and rec.kind_of?(Module)
+                        candidates = rec.constants.collect{|m| m.to_s}
+                    end
+                    candidates |= rec.methods.collect{|m| m.to_s}
                 rescue Exception
                     candidates = []
                 end
@@ -159,14 +185,23 @@
                 # func1.func2
                 candidates = []
                 ObjectSpace.each_object(Module){|m|
-                    next if m.name != "IRB::Context" and 
-                    /^(IRB|SLex|RubyLex|RubyToken)/ =~ m.name
-                    candidates.concat m.instance_methods(false)
+                    begin
+                        name = m.name
+                    rescue Exception
+                        name = ""
+                    end
+                    begin
+                        next if m.name != "IRB::Context" and 
+                            /^(IRB|SLex|RubyLex|RubyToken)/ =~ m.name
+                    rescue Exception
+                        next
+                    end
+                    candidates.concat m.instance_methods(false).collect{|x| x.to_s}
                 }
                 candidates.sort!
                 candidates.uniq!
             end
-            select_message(receiver, message, candidates)
+            select_message(receiver, message, candidates, sep)
 
         when /^\.([^.]*)$/
         # unknown(maybe String)
@@ -174,11 +209,13 @@
             receiver = ""
             message = Regexp.quote($1)
 
-            candidates = String.instance_methods(true)
+            candidates = String.instance_methods(true).collect{|m| m.to_s}
             select_message(receiver, message, candidates)
 
         else
-            candidates = eval("methods | private_methods | local_variables | self.class.constants", @binding)
+            candidates = eval(
+                "methods | private_methods | local_variables | self.class.constants",
+                @binding).collect{|m| m.to_s}
             
             (candidates|ReservedWords).grep(/^#{Regexp.quote(input)}/)
         end
@@ -186,21 +223,22 @@
 
     Operators = ["%", "&", "*", "**", "+",  "-",  "/",
       "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>",
-      "[]", "[]=", "^",]
+      "[]", "[]=", "^", "!", "!=", "!~"]
 
-    def select_message(receiver, message, candidates)
+    def select_message(receiver, message, candidates, sep = ".")
 =begin edoc
 Method used to pick completion candidates.
 
 @param receiver object receiving the message
 @param message message to be sent to object
 @param candidates possible completion candidates
+@param sep separater string
 @return filtered list of candidates
 =end
         candidates.grep(/^#{message}/).collect do |e|
             case e
             when /^[a-zA-Z_]/
-                receiver + "." + e
+                receiver + sep + e
             when /^[0-9]/
             when *Operators
                 #receiver + " " + e

eric ide

mercurial