--- 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