Skip to content

Commit

Permalink
Add dot_iex IEx.Config for .iex lookup (#13647)
Browse files Browse the repository at this point in the history
  • Loading branch information
camilleryr committed Jun 9, 2024
1 parent ab7de3a commit 26c6b1b
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 11 deletions.
19 changes: 13 additions & 6 deletions lib/iex/lib/iex.ex
Original file line number Diff line number Diff line change
Expand Up @@ -321,10 +321,10 @@ defmodule IEx do
## The .iex.exs file
When starting, IEx looks for a local `.iex.exs` file (located in the current
working directory), then for a global `.iex.exs` file located inside the
directory pointed by the `IEX_HOME` environment variable (which defaults
to `~`) and loads the first one it finds (if any).
When starting, IEx looks for a configured path, then for a local `.iex.exs` file
(located in the current working directory), then for a global `.iex.exs` file
located inside the directory pointed by the `IEX_HOME` environment variable
(which defaults to `~`) and loads the first one it finds (if any).
The code in the chosen `.iex.exs` file is evaluated line by line in the shell's
context, as if each line were being typed in the shell. For instance, any modules
Expand Down Expand Up @@ -356,8 +356,9 @@ defmodule IEx do
iex(1)> value
13
It is possible to load another file by supplying the `--dot-iex` option
to IEx. See `iex --help`.
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")`)
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
relative to the user that started the application, not to the user that
Expand Down Expand Up @@ -399,6 +400,7 @@ defmodule IEx do
* `:alive_prompt`
* `:alive_continuation_prompt`
* `:parser`
* `:dot_iex`
They are discussed individually in the sections below.
Expand Down Expand Up @@ -504,6 +506,11 @@ defmodule IEx do
or `{:incomplete, buffer}`.
If the parser raises, the buffer is reset to an empty string.
## dot_iex
Configure the file loaded into your IEx session when it starts.
See more information [in the `.iex.exs` documentation](`m:IEx#module-the-iex-exs-file`).
"""
@spec configure(keyword()) :: :ok
def configure(options) do
Expand Down
8 changes: 7 additions & 1 deletion lib/iex/lib/iex/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ defmodule IEx.Config do
:alive_prompt,
:alive_continuation_prompt,
:width,
:parser
:parser,
:dot_iex
]

# Read API
Expand Down Expand Up @@ -88,6 +89,10 @@ defmodule IEx.Config do
end
end

def dot_iex() do
Application.get_env(:iex, :dot_iex)
end

# Used by default on evaluation cycle
defp default_color(:eval_interrupt), do: [:yellow]
defp default_color(:eval_result), do: [:yellow]
Expand Down Expand Up @@ -193,6 +198,7 @@ defmodule IEx.Config do
defp validate_option({:alive_continuation_prompt, new}) when is_binary(new), do: :ok
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(option) do
raise ArgumentError, "invalid configuration #{inspect(option)}"
Expand Down
6 changes: 5 additions & 1 deletion lib/iex/lib/iex/evaluator.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
defmodule IEx.Evaluator do
@moduledoc false

alias IEx.Config

@doc """
Eval loop for an IEx session. Its responsibilities include:
Expand Down Expand Up @@ -242,7 +244,9 @@ defmodule IEx.Evaluator do
ref: ref
}

case opts[:dot_iex_path] do
dot_iex_path = opts[:dot_iex_path] || Config.dot_iex()

case dot_iex_path do
"" -> state
path -> load_dot_iex(state, path)
end
Expand Down
15 changes: 15 additions & 0 deletions lib/iex/test/iex/interaction_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,21 @@ defmodule IEx.InteractionTest do
input = "nested_var\nmy_variable\nmy_fun_nested()"
assert capture_iex(input, [], dot_iex_path: path) == "42\n13\n:nested"
end

@tag :tmp_dir
test "configured .iex", %{tmp_dir: tmp_dir} do
path =
write_dot_iex!(tmp_dir, "configured-dot-iex", """
defmodule ConfiguredDotIEx do
def my_fun_single, do: :single
end
import ConfiguredDotIEx
my_variable = 42
""")

assert capture_iex("{my_fun_single(), my_variable}", [dot_iex: path], dot_iex_path: nil) ==
"{:single, 42}"
end
end

defp write_dot_iex!(tmp_dir, name, contents) do
Expand Down
6 changes: 3 additions & 3 deletions lib/iex/test/test_helper.exs
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ defmodule IEx.Case do
end
end

keys = [:default_prompt, :alive_prompt, :inspect, :colors, :history_size]
@iex_env Application.get_all_env(:iex) |> Keyword.take(keys)
@keys [:default_prompt, :alive_prompt, :inspect, :colors, :history_size, :dot_iex]
@iex_env Application.get_all_env(:iex) |> Keyword.take(@keys)

setup do
on_exit(fn ->
env = @iex_env
Enum.each(env, fn {k, _} -> Application.delete_env(:iex, k) end)
Enum.each(@keys, &Application.delete_env(:iex, &1))
IEx.configure(env)
end)

Expand Down

0 comments on commit 26c6b1b

Please sign in to comment.