diff --git a/lib/iex/lib/iex.ex b/lib/iex/lib/iex.ex index 7215b5ef3cc..68a3dd31e72 100644 --- a/lib/iex/lib/iex.ex +++ b/lib/iex/lib/iex.ex @@ -357,7 +357,7 @@ defmodule IEx do 13 It is possible to load another file by configuring the `iex` application's `dot_iex` - value (`config :iex, dot_iex: "PATH"` or `IEx.Config.configure(dot_iex: "PATH")`) + value (`config :iex, dot_iex: "PATH"` or `IEx.configure(dot_iex: "PATH")`) or supplying the `--dot-iex` option to IEx. See `iex --help`. In case of remote nodes, the location of the `.iex.exs` files are taken @@ -488,6 +488,9 @@ defmodule IEx do * `:alive_continuation_prompt` - used when `Node.alive?/0` returns `true` and more input is expected + * `:auto_reload` - when set to `true`, automatically purges in-memory + modules when they get invalidated by a concurrent compilation + The following values in the prompt string will be replaced appropriately: * `%counter` - the index of the history diff --git a/lib/iex/lib/iex/config.ex b/lib/iex/lib/iex/config.ex index f94406e6f7c..863b30ecfa5 100644 --- a/lib/iex/lib/iex/config.ex +++ b/lib/iex/lib/iex/config.ex @@ -14,7 +14,8 @@ defmodule IEx.Config do :alive_continuation_prompt, :width, :parser, - :dot_iex + :dot_iex, + :auto_reload ] # Read API @@ -93,6 +94,10 @@ defmodule IEx.Config do Application.get_env(:iex, :dot_iex) end + def auto_reload?() do + Application.fetch_env!(:iex, :auto_reload) + end + # Used by default on evaluation cycle defp default_color(:eval_interrupt), do: [:yellow] defp default_color(:eval_result), do: [:yellow] @@ -199,6 +204,7 @@ defmodule IEx.Config do defp validate_option({:width, new}) when is_integer(new), do: :ok defp validate_option({:parser, tuple}) when tuple_size(tuple) == 3, do: :ok defp validate_option({:dot_iex, path}) when is_binary(path), do: :ok + defp validate_option({:auto_reload, enabled}) when is_boolean(enabled), do: :ok defp validate_option(option) do raise ArgumentError, "invalid configuration #{inspect(option)}" diff --git a/lib/iex/lib/iex/mix_listener.ex b/lib/iex/lib/iex/mix_listener.ex index c905a93c764..57f2e0f7f17 100644 --- a/lib/iex/lib/iex/mix_listener.ex +++ b/lib/iex/lib/iex/mix_listener.ex @@ -25,13 +25,8 @@ defmodule IEx.MixListener do @impl true def handle_call(:purge, _from, state) do - for module <- state.to_purge do - :code.purge(module) - :code.delete(module) - end - + purge_modules(state.to_purge) status = if Enum.empty?(state.to_purge), do: :noop, else: :ok - {:reply, status, %{state | to_purge: MapSet.new()}} end @@ -43,13 +38,27 @@ defmodule IEx.MixListener do {:noreply, state} else %{changed: changed, removed: removed} = info.modules_diff - state = update_in(state.to_purge, &Enum.into(changed, &1)) - state = update_in(state.to_purge, &Enum.into(removed, &1)) - {:noreply, state} + + if IEx.Config.auto_reload?() do + purge_modules(changed) + purge_modules(removed) + {:noreply, state} + else + state = update_in(state.to_purge, &Enum.into(changed, &1)) + state = update_in(state.to_purge, &Enum.into(removed, &1)) + {:noreply, state} + end end end def handle_info(_message, state) do {:noreply, state} end + + defp purge_modules(modules) do + for module <- modules do + :code.purge(module) + :code.delete(module) + end + end end diff --git a/lib/iex/mix.exs b/lib/iex/mix.exs index 30e7c537d58..0493b7f1644 100644 --- a/lib/iex/mix.exs +++ b/lib/iex/mix.exs @@ -18,7 +18,8 @@ defmodule IEx.MixProject do inspect: [pretty: true], history_size: 20, default_prompt: "%prefix(%counter)>", - alive_prompt: "%prefix(%node)%counter>" + alive_prompt: "%prefix(%node)%counter>", + auto_reload: false ] ] end