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



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/coderunner/interactive_methods.rb', line 152

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}
  
  
  old_dir = message.sub(/[^\/]*$/, '')
  dir = old_dir.chomp("/")
  message = message.sub(Regexp.new("#{Regexp.escape(dir)}\\/"), '')
  if dir.size > 0
#       eputs 'dir', dir
#         unless old_dir ~= /^\//
      dir = Dir.pwd + '/' + dir
#         end
#         eputs 'dir', dir, FileTest.directory?(dir)
    if FileTest.directory? dir
      files = Dir.entries(dir)
    else
      files = []
    end
  else
    dir = Dir.pwd
    files = Dir.entries(dir)
  end
#       ep files
#       ep 'mess', message
  Dir.chdir(dir){files= files.map{|file| FileTest.directory?(file) ? file + "/" : file}}
#       ep dir, files
  candidates = message.size > 0 ? files.find_all{|com| com[0...message.size] == message} : files
  candidates.map{|com| receiver + old_dir + com}
rescue 
  return []
end