Module: IRB::InputCompletor

Defined in:
lib/coderunner/interactive_methods.rb

Overview

ep ‘COMMANDS’, COMMANDS

Constant Summary collapse

CodeRunnerCompletionProc =
proc do |input|
  bind = IRB.conf[:MAIN_CONTEXT].workspace.binding
  Readline.completion_append_character = nil
  #     eputs "\n\ninput: #{input}"


  case input
  when Regexp.new("^(#{/\w+\b.*(?:\s|,)(?::p\s+\=\>|p:)\s+\[?\s*/}(?:#{Regexp.quoted_string}\\s*,\\s*)*#{/'\{(?:[^}]*\s)?:?/})(\\w+)$")
    # matches CodeRunner parameter list.... command [stuff] p: '{var: value, var
                                                                                                         receiver = $1
    message = $2
    #         ep 'mess', message
    if CodeRunner.runner and CodeRunner.runner.run_class
      candidates = CodeRunner.runner.run_class.rcp.variables.map{|var| var.to_s}.find_all{|var| var[0...message.size] == message}.map{|var| receiver + var}
    else
      candidates = []
    end
  when /^('(?:(?:\\ |[^'\s])*\s+)*)((?:\\ |[^'\s])*)$/, Regexp.new("^((?:[^']|#{Regexp.quoted_string})*')([^']*)$")
    #filename in a single quoted string
    receiver = "#$1" # "`" #$~[1]
    message = "#$2" #Regexp.quote($~[2]) # $2 #Regexp.quote($2)
    #       ep 'mess', message
    complete_files(receiver, message)



  when /^(\`\w+\s+(?:\S+\s+)*)([^`\s]*)$/, /^([^`]*`\w+\s+)([^`]*)$/
    #shell command with an executable
    receiver = $1 # "`" #$~[1]
    message = $2 #Regexp.quote($~[2]) # $2 #Regexp.quote($2)
    complete_files(receiver, message)
    #       files = Dir.entries(File.dirname(message))
    #       candidates = message.size > 0 ? files.find_all{|com| com[0...message.size] == message} : files
    #       candidates.map{|com| receiver + com}

  when /^(\`)([^`]*)$/, /^([^`]*`)([^`]*)$/
    #shell command without an excutable

    #         p $~
    receiver = $1 # "`" #$~[1]
    message = $2 #Regexp.quote($~[2]) # $2 #Regexp.quote($2)
    #   ep "message is", message
    #   ep COMMANDS.grep(//)
    candidates = message.size > 0 ? COMMANDS.find_all{|com| com[0...message.size] == message} : COMMANDS
    candidates.map{|com| receiver + com}
    #.grep(Regexp.new("^#{message}")) #("^#{Regexp.escape(message)}")) #.map{|com| "#{com}"} #.map{|com| receiver + com}
    #   ep candidates
    #   select_message(receiver, message, COMMANDS)

  when /^([^\/]*\/[^\/]*\/)\.([^.]*)$/
    # Regexp
    receiver = $1
    message = Regexp.quote($2)

    candidates = Regexp.instance_methods.collect{|m| m.to_s}
    select_message(receiver, message, candidates)

  when /^([^\]]*\])\.([^.]*)$/
    # Array
    receiver = $1
    message = Regexp.quote($2)

    candidates = Array.instance_methods.collect{|m| m.to_s}
    select_message(receiver, message, candidates)

  when /([^\}]*\})\.([^.]*)$/
    # Proc or Hash
    receiver = $1
    message = Regexp.quote($2)

    candidates = Proc.instance_methods.collect{|m| m.to_s}
    candidates |= Hash.instance_methods.collect{|m| m.to_s}
    select_message(receiver, message, candidates)


  when /^((?:(::)?[A-Z][^:.(]*)+)\.help :(\w*)$/
    # CodeRunner help method
    receiver = $1
    message = Regexp.quote($3)
    begin
      candidates = eval("(#{receiver}.constants - Object.constants).collect{|m| m.to_s}", bind)
      candidates |= eval("(#{receiver}.methods - Object.methods).collect{|m| m.to_s}", bind)
      begin
        candidates |= eval("(#{receiver}.instance_methods - Object.instance_methods).collect{|m| m.to_s}", bind)
      rescue
      end
    rescue Exception
      candidates = []
    end
    candidates.grep(/^#{message}/).collect{|e| receiver + '.help :' + e}

  when /^((?:.*[^:])?:[^:.]*)$/
    #         eputs 'found symbol'
    # Symbol
    if Symbol.respond_to?(:all_symbols)
      sym = $1
      candidates = Symbol.all_symbols.collect{|s| ":" + s.id2name}
      candidates.grep(/^#{sym}/)
    else
      []
    end

  when /^(.*\s)?(((::)?[A-Z][^:.(]*)+)(::|\.)([^:.]*)$/
    # Constant or class methods
    #         p "CCC"
    start = $1
    receiver = $2
    message = Regexp.quote($6)
    joiner = "#$5"
    begin
      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| (start or "") + receiver + (joiner or "::") + e}


  when /^(.*)(\b[A-Z][^:\.\(]*)$/
    # Absolute Constant or class methods
    receiver = $1
    message = $2
    candidates = Object.constants.collect{|m| m.to_s}
    candidates.grep(/^#{message}/).collect{|e| receiver + e}



  when /^(.*-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)\.([^.]*)$/
    # Numeric
    receiver = $1
    message = Regexp.quote($5)

    begin
      candidates = eval(receiver, bind).methods.collect{|m| m.to_s}
    rescue Exception
      candidates = []
    end
    select_message(receiver, message, candidates)

  when /^(.*-?0x[0-9a-fA-F_]+)\.([^.]*)$/
    # Numeric(0xFFFF)
    receiver = $1
    message = Regexp.quote($2)

    begin
      candidates = eval(receiver, bind).methods.collect{|m| m.to_s}
    rescue Exception
      candidates = []
    end
    select_message(receiver, message, candidates)

  when /^(.*[\s\{\[])?(\$[^.]*)$/
    regmessage = Regexp.new(Regexp.quote($1))
    candidates = global_variables.collect{|m| m.to_s}.grep(regmessage)

    #      when /^(\$?(\.?[^.]+)+)\.([^.]*)$/
  when /^((\.?[^.]+)+)\.([^.]*)$/
    # variable
    receiver = $1
    message = Regexp.quote($3)

    gv = eval("global_variables", bind).collect{|m| m.to_s}
    lv = eval("local_variables", bind).collect{|m| m.to_s}
    cv = eval("self.class.constants", bind).collect{|m| m.to_s}

    if (gv | lv | cv).include?(receiver)
      # foo.func and foo is local var.
      candidates = eval("#{receiver}.methods", bind).collect{|m| m.to_s}
    elsif /^[A-Z]/ =~ receiver and /\./ !~ receiver
      # Foo::Bar.func
      begin
        candidates = eval("#{receiver}.methods", bind).collect{|m| m.to_s}
      rescue Exception
        candidates = []
      end
    else
      # func1.func2
      candidates = []
      ObjectSpace.each_object(Module){|m|
        begin
          name = m.name
        rescue Exception
          name = ""
        end
        next if name != "IRB::Context" and 
          /^(IRB|SLex|RubyLex|RubyToken)/ =~ name
        candidates.concat m.instance_methods(false).collect{|x| x.to_s}
      }
      candidates.sort!
      candidates.uniq!
    end
    select_message(receiver, message, candidates)

  when /^\.([^.]*)$/
    # unknown(maybe String)

    receiver = ""
    message = Regexp.quote($1)

    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", bind).collect{|m| m.to_s}

    (candidates|ReservedWords).grep(/^#{Regexp.quote(input)}/)

  end
end

Class Method Summary collapse

Class Method Details

.complete_files(receiver, message) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/coderunner/interactive_methods.rb', line 95

def self.complete_files(receiver, message)
  #       files = message.split(/\s+/)
  #       message = files.pop
  dir = message.sub(/[^\/]*$/, '')
  message = message.sub(Regexp.new("#{Regexp.escape(dir)}"), '')
  dir.sub!(/^~/, ENV['HOME'])
  short_dir = dir
  dir = Dir.pwd + '/' + dir unless dir =~ /^\//
  #$stderr.puts "Dir to scan: #{dir}"

  files = Dir.entries(dir)

  #$stderr.puts "entries", files
  Dir.chdir(dir){files= files.map{|file| FileTest.directory?(file) ? file + "/" : file}}
  #$stderr.puts "entries - directories", files

  candidates = message.size > 0 ? files.find_all{|com| com[0...message.size] == message} : files
  return candidates.map{|com| receiver + short_dir + com}
rescue 
  return []
end