# {{{ ruby completion
# This was adapted from vim-ruby's omnicompletion script


def get_completions(input)
  
  input.sub!(%r'.*[ \t\n\"\\\'`><=;|&{(]', '') # Readline.basic_word_break_characters
  input.sub!(%r'self\.', '')
  input.sub!(%r'.*((\.\.[\[(]?)|([\[(]))', '')

  asn = %r'^.*(\+|\-|\*|=|\(|\[)=?(\s*[A-Za-z0-9_:@.-]*)(\s*(\{|\+|\-|\*|\%|\/)?\s*).*'

  if asn.match(input)
    input = $2
  end
  
  input.strip!
  message = nil
  receiver = nil
  candidates = []
  case input
  when %r'^(/[^/]*/)\.([^.]*)$' # Regexp
    receiver = $1
    message = $2
    candidates = Regexp.instance_methods(true)
    
  when %r'^([^\]]*\])\.([^.]*)$' # Array
    receiver = $1
    message = $2
    candidates = Array.instance_methods(true)
    
  when %r'^([^\}]*\})\.([^.]*)$' # Proc or Hash
    receiver = $1
    message = $2
    candidates = Proc.instance_methods(true) | Hash.instance_methods(true)
    
  when %r'^(:[^:.]*)$' # Symbol
    if Symbol.respond_to?(:all_symbols)
      receiver = $1
      candidates = Symbol.all_symbols.collect{|s| s.id2name}
      candidates.delete_if { |c| c.match( %r"'" ) }
    end
    
  when %r'^::([A-Z][^:\.\(]*)$' # Absolute Constant or class methods
    receiver = $1
    candidates = Object.constants
    
  when %r'^(((::)?[A-Z][^:.\(]*)+)::?([^:.]*)$' # Constant or class methods
    receiver = $1
    message = $4
    begin
      receiver = Kernel.const_get(receiver)
      candidates = receiver.constants | receiver.methods
    rescue Exception
      candidates = []
    end
    
  when %r'^(([A-Z][^:.\(]*)+).([^:.]*)$' # Class methods
    receiver = $1
    message = $3
    begin
      candidates = Kernel.const_get(receiver).methods
    rescue Exception
      candidates = []
    end

  when %r'^(:[^:.]+)\.([^.]*)$' # Symbol
    receiver = $1
    message = $2
    candidates = Symbol.instance_methods(true)
    
  when %r'^([0-9_]+(\.[0-9_]+)?(e[0-9]+)?)\.([^.]*)$' # Numeric
    receiver = $1
    message = $4
    begin
      candidates = Kernel.const_get(receiver).methods
    rescue Exception
      candidates = []
    end
    
  when %r'^(\$[^.]*)$' #global
    candidates = global_variables.grep(Regexp.new(Regexp.quote($1)))
    
  when %r'^\(?\s*[A-Za-z0-9:^@.%\/+*\(\)]+\.\.\.?[A-Za-z0-9:^@.%\/+*\(\)]+\s*\)?\.([^.]*)'
    message = $1
    candidates = Range.instance_methods(true)
    
  when %r'^\[(\s*[A-Za-z0-9:^@.%\/+*\(\)\[\]\{\}.\'\"],?)*\].([^.]*)'
    message = $2
    candidates = Array.instance_methods(true)
    
  when /^\.([^.]*)$/ # unknown(maybe String)
    message = $1
    candidates = String.instance_methods(true)
    
  else
    return nil
  end
  candidates.delete_if { |x| x == nil }
  candidates = candidates.grep(%r'^#{Regexp.quote(message)}') if message
  candidates.uniq!
  candidates.sort!
  
  valid = (candidates - Object.instance_methods)
  return nil unless valid.length > 0

  SLang.message(valid.join(' '))
  maximum = valid.max.to_s
  
  completion = '';
  i=0
  if RUBY_VERSION < '1.9.0'
    valid.min.to_s.each_byte do |c|
      break unless maximum[i] == c
      completion << c
      i += 1
    end
  else
    valid.min.to_s.each_char do |c|
      break unless maximum[i] == c
      completion << c
      i += 1
    end
  end
  if message
    return completion[message.length..completion.length]
  else
    return completion.to_s
  end
  
end

# }}} ruby completion
