defmodule Alchemist.Informant do
|
|
def get_functions(mod, hint) do
|
|
{mod, _} = Code.eval_string(mod)
|
|
falist = get_module_funs(mod)
|
|
|
|
list = Enum.reduce falist, [], fn({f, a}, acc) ->
|
|
case :lists.keyfind(f, 1, acc) do
|
|
{f, aa} -> :lists.keyreplace(f, 1, acc, {f, [a|aa]})
|
|
false -> [{f, [a]}|acc]
|
|
end
|
|
end
|
|
|
|
case hint do
|
|
"" ->
|
|
for {fun, arities} <- list,
|
|
name = Atom.to_string(fun) do
|
|
"#{name}/#{List.first(arities)}"
|
|
end |> :lists.sort()
|
|
_otherwise ->
|
|
for {fun, arities} <- list,
|
|
name = Atom.to_string(fun),
|
|
String.starts_with?(name, hint) do
|
|
"#{name}/#{List.first(arities)}"
|
|
end |> :lists.sort()
|
|
end
|
|
end
|
|
|
|
defp get_module_funs(mod) do
|
|
case Code.ensure_loaded(mod) do
|
|
{:module, _} ->
|
|
mod.module_info(:functions) ++ mod.__info__(:macros)
|
|
_otherwise ->
|
|
[]
|
|
end
|
|
end
|
|
|
|
def get_modules do
|
|
modules = Enum.map(:code.all_loaded, fn({m, _}) -> Atom.to_string(m) end)
|
|
|
|
if :code.get_mode() === :interactive do
|
|
modules ++ get_modules_from_applications()
|
|
else
|
|
modules
|
|
end
|
|
end
|
|
|
|
defp get_modules_from_applications do
|
|
for {app, _, _} <- :application.loaded_applications,
|
|
{_, modules} = :application.get_key(app, :modules),
|
|
module <- modules,
|
|
has_doc = Code.get_docs(module, :moduledoc), elem(has_doc, 1) do
|
|
Atom.to_string(module)
|
|
end
|
|
end
|
|
end
|