You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

78 lines
1.6 KiB

Code.require_file "../helpers/module_info.exs", __DIR__
defmodule Alchemist.API.Docl do
@moduledoc false
import IEx.Helpers, warn: false
alias Alchemist.Helpers.ModuleInfo
def request(args) do
Application.put_env(:iex, :colors, [enabled: true])
args
|> normalize
|> process
IO.puts "END-OF-DOCL"
end
def process([expr, modules, aliases]) do
search(expr, modules, aliases)
end
def search(nil), do: true
def search(expr) do
try do
Code.eval_string("h(#{expr})", [], __ENV__)
rescue
_e -> nil
end
end
def search(expr, modules, []) do
expr = to_string expr
unless function?(expr) do
search(expr)
else
search_with_context(modules, expr)
end
end
def search(expr, modules, aliases) do
unless function?(expr) do
String.split(expr, ".")
|> ModuleInfo.expand_alias(aliases)
|> search
else
search_with_context(modules, expr)
end
end
defp search_with_context(modules, expr) do
modules ++ [Kernel, Kernel.SpecialForms]
|> build_search(expr)
|> search
end
defp build_search(modules, search) do
function = Regex.replace(~r/\/[0-9]$/, search, "")
function = String.to_atom(function)
for module <- modules,
ModuleInfo.docs?(module, function) do
"#{module}.#{search}"
end |> List.first
end
defp function?(expr) do
Regex.match?(~r/^[a-z_]/, expr)
end
defp normalize(request) do
{{expr, [ context: _,
imports: imports,
aliases: aliases]}, _} = Code.eval_string(request)
[expr, imports, aliases]
end
end