class FastRI::RiService

Constants

DEFAULT_DISPLAY_OPTIONS
DEFAULT_INFO_OPTIONS
DEFAULT_OBTAIN_ENTRIES_OPTIONS
Options

Public Class Methods

new(ri_reader) click to toggle source
# File lib/fastri/ri_service.rb, line 112
def initialize(ri_reader)
  @ri_reader = ri_reader
end

Public Instance Methods

all_classes() click to toggle source

Return array of strings with the names of all known classes.

# File lib/fastri/ri_service.rb, line 276
def all_classes
  @ri_reader.full_class_names
end
all_methods() click to toggle source

Return array of strings with the names of all known methods.

# File lib/fastri/ri_service.rb, line 271
def all_methods
  @ri_reader.full_method_names
end
args(keyword, options = {}) click to toggle source
# File lib/fastri/ri_service.rb, line 237
def args(keyword, options = {})
  options = DEFAULT_INFO_OPTIONS.merge(options)
  return nil if keyword.strip.empty?
  descriptor = NameDescriptor.new(keyword)
  entries = obtain_entries(descriptor, options)
  return nil if entries.empty? || RiIndex::ClassEntry === entries[0]

  params_text = ""
  entries.each do |entry|
    desc = @ri_reader.get_method(entry)
    params_text << capture_stdout(display(options)) do |display|
      display.full_params(desc)
    end
  end
  params_text
rescue RiError
  return nil
end
class_list(keyword) click to toggle source

Returns a list with the names of the modules/classes that define the given method, or nil.

# File lib/fastri/ri_service.rb, line 258
def class_list(keyword)
  _class_list(keyword, '\1')
end
class_list_with_flag(keyword) click to toggle source

Returns a list with the names of the modules/classes that define the given method, followed by a flag (#|::), or nil. e.g. [“Array#”, “IO#”, “IO::”, … ]

# File lib/fastri/ri_service.rb, line 265
def class_list_with_flag(keyword)
  r = _class_list(keyword, '\1\2')
  r ? r.map{|x| x.gsub(/\./, "::")} : nil
end
completion_list(keyw) click to toggle source
# File lib/fastri/ri_service.rb, line 141
def completion_list(keyw)
  return @ri_reader.full_class_names if keyw == ""

  descriptor = NameDescriptor.new(keyw)

  if descriptor.class_names.empty?
    # try partial matches
    meths = @ri_reader.methods_under_matching("", /(#|\.)#{descriptor.method_name}/, true)
    ret = meths.map{|x| x.name}.uniq.sort
    return ret.empty? ? nil : ret
  end

  # if we're here, some namespace was given
  full_ns_name = descriptor.class_names.join("::")
  if descriptor.method_name == nil && ! [?#, ?:, ?.].include?(keyw[-1])
    # partial match
    namespaces = @ri_reader.namespaces_under_matching("", /^#{full_ns_name}/, false)
    ret = namespaces.map{|x| x.full_name}.uniq.sort
    return ret.empty? ? nil : ret
  else
    if [?#, ?:, ?.].include?(keyw[-1])
      seps = case keyw[-1]
        when ?#; %w[#]
        when ?:; %w[.]
        when ?.; %w[. #]
      end
    else  # both namespace and method
      seps = separators(descriptor.is_class_method)
    end
    sep_re = "(" + seps.map{|x| Regexp.escape(x)}.join("|") + ")"
    # partial
    methods = @ri_reader.methods_under_matching(full_ns_name, /#{sep_re}#{descriptor.method_name}/, false)
    ret = methods.map{|x| x.full_name}.uniq.sort
    return ret.empty? ? nil : ret
  end
rescue RiError
  return nil
end
info(keyw, options = {}) click to toggle source
# File lib/fastri/ri_service.rb, line 197
def info(keyw, options = {})
  options = DEFAULT_INFO_OPTIONS.merge(options)
  return nil if keyw.strip.empty?
  descriptor = NameDescriptor.new(keyw)
  entries = obtain_entries(descriptor, options)

  case entries.size
  when 0; nil
  when 1
    case entries[0].type
    when :namespace
      capture_stdout(display(options)) do |display|
        display.display_class_info(@ri_reader.get_class(entries[0]), @ri_reader)
        if options[:extended]
          methods = @ri_reader.methods_under(entries[0], true)
          methods.each do |meth_entry|
            display.display_method_info(@ri_reader.get_method(meth_entry))
          end
        end
      end
    when :method
      capture_stdout(display(options)) do |display|
        display.display_method_info(@ri_reader.get_method(entries[0]))
      end
    end
  else
    capture_stdout(display(options)) do |display|
      formatter = display.formatter
      formatter.draw_line("Multiple choices:")
      formatter.blankline
      formatter.wrap(entries.map{|x| x.full_name}.join(", "))
      entries.each do |entry|
        display.display_method_info(@ri_reader.get_method(entry)) if entry.type == :method
      end if options[:expand_choices]
    end
  end
rescue RiError
  return nil
end
matches(keyword, options = {}) click to toggle source
# File lib/fastri/ri_service.rb, line 187
def matches(keyword, options = {})
  options = DEFAULT_INFO_OPTIONS.merge(options)
  return nil if keyword.strip.empty?
  descriptor = NameDescriptor.new(keyword)
  ret = obtain_entries(descriptor, options).map{|x| x.full_name}
  ret ? ret : nil
rescue RiError
  return nil
end
obtain_entries(descriptor, options = {}) click to toggle source
# File lib/fastri/ri_service.rb, line 122
def obtain_entries(descriptor, options = {})
  options = DEFAULT_OBTAIN_ENTRIES_OPTIONS.merge(options)
  if descriptor.class_names.empty?
    seps = separators(descriptor.is_class_method)
    return obtain_unqualified_method_entries(descriptor.method_name, seps,
                                             options[:lookup_order])
  end

  # if we're here, some namespace was given
  full_ns_name = descriptor.class_names.join("::")
  if descriptor.method_name == nil
    return obtain_namespace_entries(full_ns_name, options[:lookup_order])
  else  # both namespace and method
    seps = separators(descriptor.is_class_method)
    return obtain_qualified_method_entries(full_ns_name, descriptor.method_name, 
                                           seps, options[:lookup_order])
  end
end

Private Instance Methods

_class_list(keyword, rep) click to toggle source
# File lib/fastri/ri_service.rb, line 384
def _class_list(keyword, rep)
  return nil if keyword.strip.empty?
  entries = @ri_reader.methods_under_matching("", /#{keyword}$/, true)
  return nil if entries.empty?

  entries.map{|entry| entry.full_name.sub(/(.*)(#|\.).*/, rep) }.uniq
rescue RiError
  return nil
end
capture_stdout(display) { |display| ... } click to toggle source
# File lib/fastri/ri_service.rb, line 421
def capture_stdout(display)
  yield display
  display.stringio.string
end
display(opt = {}) click to toggle source
# File lib/fastri/ri_service.rb, line 407
def display(opt = {})
  opt = DEFAULT_DISPLAY_OPTIONS.merge(opt)
  options = Options.new
  options.use_stdout = true
  case opt[:formatter].to_sym
  when :ansi
    options.formatter = RedirectedAnsiFormatter
  else
    options.formatter = RedirectedTextFormatter
  end
  options.width = opt[:width]
  StringRedirectedDisplay.new(options)
end
obtain_namespace_entries(name, order) click to toggle source
# File lib/fastri/ri_service.rb, line 355
def obtain_namespace_entries(name, order)
  name = Regexp.escape(name)
  matcher = MatchFinder.new do |m|
    m.add_matcher(:exact){ m.yield @ri_reader.get_class_entry(name) }
    m.add_matcher(:exact_ci) do 
      m.yield @ri_reader.namespaces_under_matching("", /^#{name}$/i, true)
    end
    m.add_matcher(:nested) do 
      m.yield @ri_reader.namespaces_under_matching("", /::#{name}$/, true)
    end
    m.add_matcher(:nested_ci) do 
      m.yield @ri_reader.namespaces_under_matching("", /::#{name}$/i, true)
    end
    m.add_matcher(:partial) do
      m.yield @ri_reader.namespaces_under_matching("", /^#{name}/, true)
    end
    m.add_matcher(:partial_ci) do
      m.yield @ri_reader.namespaces_under_matching("", /^#{name}/i, true)
    end
    m.add_matcher(:nested_partial) do
      m.yield @ri_reader.namespaces_under_matching("", /::#{name}[^:]*$/, true)
    end
    m.add_matcher(:nested_partial_ci) do
      m.yield @ri_reader.namespaces_under_matching("", /::#{name}[^:]*$/i, true)
    end
  end
  matcher.get_matches(order)
end
obtain_qualified_method_entries(namespace, method, separators, order) click to toggle source
# File lib/fastri/ri_service.rb, line 308
def obtain_qualified_method_entries(namespace, method, separators, order)
  namespace, unescaped_namespace = Regexp.escape(namespace), namespace
  method = Regexp.escape(method)
  matcher = MatchFinder.new do |m|
    m.add_matcher(:exact) do
      separators.each do |sep|
        m.yield @ri_reader.get_method_entry("#{namespace}#{sep}#{method}")
      end
    end
    sep_re = "(" + separators.map{|x| Regexp.escape(x)}.join("|") + ")"
    m.add_matcher(:exact_ci) do
      m.yield @ri_reader.methods_under_matching("", /^#{namespace}#{sep_re}#{method}$/i, true)
    end
    m.add_matcher(:nested) do
      m.yield @ri_reader.methods_under_matching("", /::#{namespace}#{sep_re}#{method}$/, true)
    end
    m.add_matcher(:nested_ci) do
      m.yield @ri_reader.methods_under_matching("", /::#{namespace}#{sep_re}#{method}$/i, true)
    end
    m.add_matcher(:partial) do
      m.yield @ri_reader.methods_under_matching(unescaped_namespace, /#{sep_re}#{method}/, false)
    end
    m.add_matcher(:partial_ci) do
      m.yield @ri_reader.methods_under_matching("", /^#{namespace}#{sep_re}#{method}/i, true)
    end
    m.add_matcher(:nested_partial) do
      m.yield @ri_reader.methods_under_matching("", /::#{namespace}#{sep_re}#{method}/, true)
    end
    m.add_matcher(:nested_partial_ci) do
      m.yield @ri_reader.methods_under_matching("", /::#{namespace}#{sep_re}#{method}/i, true)
    end
    m.add_matcher(:namespace_partial) do
      m.yield @ri_reader.methods_under_matching("", /^#{namespace}[^:]*#{sep_re}#{method}$/, true)
    end
    m.add_matcher(:namespace_partial_ci) do
      m.yield @ri_reader.methods_under_matching("", /^#{namespace}[^:]*#{sep_re}#{method}$/i, true)
    end
    m.add_matcher(:full_partial) do
      m.yield @ri_reader.methods_under_matching("", /^#{namespace}[^:]*#{sep_re}#{method}/, true)
    end
    m.add_matcher(:full_partial_ci) do
      m.yield @ri_reader.methods_under_matching("", /^#{namespace}[^:]*#{sep_re}#{method}/i, true)
    end
  end
  matcher.get_matches(order)
end
obtain_unqualified_method_entries(name, separators, order) click to toggle source
# File lib/fastri/ri_service.rb, line 282
def obtain_unqualified_method_entries(name, separators, order)
  name = Regexp.escape(name)
  sep_re = "(" + separators.map{|x| Regexp.escape(x)}.join("|") + ")"
  matcher = MatchFinder.new do |m|
    m.add_matcher(:exact) do
      m.yield @ri_reader.methods_under_matching("", /#{sep_re}#{name}$/, true)
    end
    m.add_matcher(:exact_ci) do
      m.yield @ri_reader.methods_under_matching("", /#{sep_re}#{name}$/i, true)
    end
    m.add_matcher(:partial) do
      m.yield @ri_reader.methods_under_matching("", /#{sep_re}#{name}/, true)
    end
    m.add_matcher(:partial_ci) do
      m.yield @ri_reader.methods_under_matching("", /#{sep_re}#{name}/i, true)
    end
    m.add_matcher(:anywhere) do
      m.yield @ri_reader.methods_under_matching("", /#{sep_re}.*#{name}/, true)
    end
    m.add_matcher(:anywhere_ci) do
      m.yield @ri_reader.methods_under_matching("", /#{sep_re}.*#{name}/i, true)
    end
  end
  matcher.get_matches(order)
end
separators(is_class_method) click to toggle source
# File lib/fastri/ri_service.rb, line 395
def separators(is_class_method)
  case is_class_method
  when true;  ["."]
  when false; ["#"]
  when nil;   [".","#"]
  end
end