Module: Rouge::REPL::Completer

Extended by:
Completer
Included in:
Completer
Defined in:
lib/rouge/repl.rb

Instance Method Summary collapse

Instance Method Details

#locate_module(query, root = Object) ⇒ Class, ...

Recursively searches for a Ruby module (includes classes) given by the string query. The string should contain a Rouge style namespace name for the module.

Optionally, a root module can be supplied as the context for the query. By default this is Object. If no module is found, the method returns nil or the root.

Be aware this method only returns modules and classes.

Examples:

locate_module("Bil.Bo") #=> Bil::Bo
locate_module("Ji.Tsu", Nin) #=> Nin::Ji::Tsu

Parameters:

  • query (String)

    the module (or class) to find

  • root (Module) (defaults to: Object)

    the optional search context

Returns:

  • (Class, Module, nil)

    the search result



221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/rouge/repl.rb', line 221

def locate_module(query, root = Object)
  head, tail = query.split('.', 2)

  return root unless rg_ruby_module?(head)

  lookup = head.to_sym

  if root.is_a?(Module) && root.constants.include?(lookup)
    result = root.const_get(lookup)

    return root unless result.is_a?(Module)

    # `query` may have ended with '.'.
    if tail.nil? || tail.empty?
      result
    else
      locate_module(tail, result)
    end
  else
    root
  end
end

#new(current_namespace) ⇒ Proc

Returns a proc intended to be used with Readline.

Parameters:

Returns:

  • (Proc)

    the completion proc to be used with Readline. The returned proc accepts a string and returns an array.



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/rouge/repl.rb', line 91

def new(current_namespace)
  return lambda do |query|
    if query.nil? || query.empty?
      return []
    end

    list = namespace_items(current_namespace)
    list << search(query)

    matches = search_list(list.flatten, query)

    # If there's only one match we check if it's a namespace or a Ruby
    # constant which contains other constants or singleton methods.
    if matches.length == 1
      match = matches[0]
      if Rouge::Namespace.exists?(match)
        if current_namespace.table.include?(match)
          matches << "#{match}/"
        else
          Readline.completion_append_character = "/"
        end
      else
        if locate_module(match.to_s)
          Readline.completion_append_character = ""
        end
      end
    else
      Readline.completion_append_character = ""
    end

    matches
  end
end

#rg_namespace?(x) ⇒ Boolean

Returns true if the provided namespace is included in ‘rg_namespaces`.

Parameters:

Returns:

  • (Boolean)

See Also:

  • rg_namespaces


268
269
270
# File 'lib/rouge/repl.rb', line 268

def rg_namespace?(x)
  x.is_a?(Rouge::Namespace) && rg_namespaces.keys.include?(x.name)
end

#rg_namespacesHash

Rouge namespaces. Note we do not include the rouge.builtin and ruby namespaces since we would like built in vars, such as def or let, and top level Ruby constants to be easily accessible with command line completion.

Returns:

  • (Hash)

    the filtered namespaces



252
253
254
255
256
# File 'lib/rouge/repl.rb', line 252

def rg_namespaces
  Rouge::Namespace.all.reject do |key, _|
    [:"rouge.builtin", :ruby].include?(key)
  end
end

#search(query) ⇒ Array<Symbol,String>

Returns a list of constants and singleton method names based on the string query.

Parameters:

  • query (String)

    the search string to use

Returns:

  • (Array<Symbol,String>)

    the search results



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/rouge/repl.rb', line 134

def search(query)
  namespace, lookup = query.split('/', 2)
  result =
    case namespace
    # The ruby namespace requires special handling.
    when /^[A-Z]/
      search_ruby(query)
    when /^ruby/
      if lookup && lookup.empty?
        Rouge[:ruby].table.map {|x| "ruby/#{x}" }
      else
        search_ruby(lookup).map {|x| "ruby/#{x}" }
      end
    else
      ns = rg_namespaces[namespace.to_sym]

      if ns
        ns.table.map { |var, _| "#{namespace}/#{var}" }
      else
        # Add the current namepace, rouge.builtin, and ruby tables along with
        # the names of available namespaces in the completion list.
        list = []
        list << Rouge[:"rouge.builtin"].table.keys
        list << :ruby
        list << Rouge[:ruby].table
        list << rg_namespaces.keys
      end
    end

  search_list(result.flatten, query)
end

#search_ruby(query) ⇒ Array<Symbol,String>

Applies ‘locate_module` to the string query and returns a list constants and singleton methods. These results are intended to be filtered in the `search` method.

Examples:

search_ruby("Rouge") #=> ["Rouge/[]", "Rouge/boot!", ...]
search_ruby("Rouge.") #=> ["Rouge/[]", "Rouge/boot!", ...]

Parameters:

  • query (String)

    the search string to use

Returns:

  • (Array<Symbol,String>)

    the search result

See Also:

  • Completer.search


182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/rouge/repl.rb', line 182

def search_ruby(query)
  namespace = query.split('/', 2).first

  mod = locate_module(namespace)

  if mod == Object
    mod.constants
  else
    ns = mod.name.gsub('::','.')
    result = []
    mod.singleton_methods.each { |sm| result << "#{ns}/#{sm}" }
    mod.constants.each { |c| result << "#{ns}.#{c}" }
    result.flatten
  end
end