def complete(key, icase = false, pat = nil)
pat ||= Regexp.new('\A' + Regexp.quote(key).gsub(/\w+\b/, '\&\w*'),
icase)
canon, sw, k, v, cn = nil
candidates = []
each do |k, *v|
(if Regexp === k
kn = nil
k === key
else
kn = defined?(k.id2name) ? k.id2name : k
pat === kn
end) or next
v << k if v.empty?
candidates << [k, v, kn]
end
candidates = candidates.sort_by {|k, v, kn| kn.size}
if candidates.size == 1
canon, sw, * = candidates[0]
elsif candidates.size > 1
canon, sw, cn = candidates.shift
candidates.each do |k, v, kn|
next if sw == v
if String === cn and String === kn
if cn.rindex(kn, 0)
canon, sw, cn = k, v, kn
next
elsif kn.rindex(cn, 0)
next
end
end
throw :ambiguous, key
end
end
if canon
block_given? or return key, *sw
yield(key, *sw)
end
end