Code.require_file "utils.exs", __DIR__
|
|
Code.require_file "completer.exs", __DIR__
|
|
Code.require_file "informant.exs", __DIR__
|
|
Code.require_file "source.exs", __DIR__
|
|
Code.require_file "case.exs", __DIR__
|
|
|
|
defmodule Alchemist.Server do
|
|
|
|
alias Alchemist.Case
|
|
|
|
def start([env]) do
|
|
# Preload Enum so we load basic Elixir/Erlang code
|
|
IEx.Autocomplete.expand('.munE')
|
|
:ets.new(:alchemist, [:named_table])
|
|
loop(all_loaded(), env)
|
|
end
|
|
|
|
def loop(loaded, env) do
|
|
line = IO.gets("") |> String.rstrip()
|
|
paths = load_paths(env)
|
|
apps = load_apps(env)
|
|
|
|
read_input(line)
|
|
|
|
purge_modules(loaded)
|
|
purge_paths(paths)
|
|
purge_apps(apps)
|
|
|
|
:ets.delete_all_objects(:alchemist)
|
|
|
|
loop(loaded, env)
|
|
end
|
|
|
|
def read_input(line) do
|
|
case line |> String.split(" ", parts: 2) do
|
|
["COMPLETE"] ->
|
|
Case.Complete.process!
|
|
["COMPLETE", hint] ->
|
|
Case.Complete.process!(hint)
|
|
["COMPLETE-WITH-CONTEXT", hint] ->
|
|
Case.Complete.process_with_context!(hint)
|
|
["DOC", exp] ->
|
|
Case.Doc.process!(exp)
|
|
["MODULES"] ->
|
|
Case.Modules.process!
|
|
["EVAL", exp] ->
|
|
Case.Eval.process!(exp)
|
|
["QUOTE", file] ->
|
|
Case.Quote.process!(file)
|
|
["SOURCE", exp] ->
|
|
Case.Find.process!(exp)
|
|
_ ->
|
|
nil
|
|
end
|
|
end
|
|
|
|
defp all_loaded() do
|
|
for {m,_} <- :code.all_loaded, do: m
|
|
end
|
|
|
|
defp load_paths(env) do
|
|
for path <- Path.wildcard("_build/#{env}/lib/*/ebin") do
|
|
Code.prepend_path(path)
|
|
path
|
|
end
|
|
end
|
|
|
|
defp load_apps(env) do
|
|
for path <- Path.wildcard("_build/#{env}/lib/*/ebin/*.app") do
|
|
app = path |> Path.basename() |> Path.rootname() |> String.to_atom
|
|
Application.load(app)
|
|
app
|
|
end
|
|
end
|
|
|
|
defp purge_modules(loaded) do
|
|
for m <- (all_loaded() -- loaded) do
|
|
:code.delete(m)
|
|
:code.purge(m)
|
|
end
|
|
end
|
|
|
|
defp purge_paths(paths) do
|
|
for p <- paths, do: Code.delete_path(p)
|
|
end
|
|
|
|
defp purge_apps(apps) do
|
|
for a <- apps, do: Application.unload(a)
|
|
end
|
|
end
|
|
|
|
Alchemist.Server.start([System.argv])
|