Skip to content

Commit 5a99fbf

Browse files
committed
Add import_file/1 and /2 helpers
1 parent c634a5d commit 5a99fbf

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

lib/iex/lib/iex/helpers.ex

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ defmodule IEx.Helpers do
2525
* `t/1` — prints type information
2626
* `v/0` - prints all commands and values
2727
* `v/1` - retrieves nth value from console
28+
* `import_file/1`, `import_file/2` - evaluate the given file in the shell's context
2829
2930
Help for functions in this module can be consulted
3031
directly from the command line, as an example, try:
@@ -375,4 +376,44 @@ defmodule IEx.Helpers do
375376
representation
376377
end
377378
end
379+
380+
@doc """
381+
Evaluates the contents of file at `path` as if it were directly typed into
382+
the shell. When `relative_to` is provided, `path` is treated as being
383+
relative to that (unless it is already an absolute path). See `Path.expand`
384+
for more details.
385+
386+
Both `path` and `relative_to` (if present) have to be literal binaries.
387+
388+
Leading `~` in `path` and `relative_to` is automatically expanded.
389+
390+
## Examples
391+
392+
# ~/file.exs
393+
value = 13
394+
395+
# in the shell
396+
iex(1)> import_file "~/file.exs"
397+
13
398+
iex(2)> value
399+
13
400+
"""
401+
defmacro import_file(path, relative_to // nil)
402+
403+
defmacro import_file(path, relative_to)
404+
when is_binary(path) and (nil?(relative_to) or is_binary(relative_to)) do
405+
if relative_to do
406+
inject_file Path.expand(path, relative_to)
407+
else
408+
inject_file Path.expand(path)
409+
end
410+
end
411+
412+
defmacro import_file(_, _) do
413+
raise "import_file expects literal binaries as its arguments"
414+
end
415+
416+
defp inject_file(path) do
417+
Code.string_to_ast! File.read!(path), file: path
418+
end
378419
end

lib/iex/lib/iex/server.ex

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,16 @@ defmodule IEx.Server do
9898
else
9999
try do
100100
code = File.read!(path)
101+
scope = :elixir.scope_for_eval(config.scope, file: path)
101102

102103
# Evaluate the contents in the same environment do_loop will run in
103104
{ _result, binding, scope } =
104105
:elixir.eval(:unicode.characters_to_list(code),
105106
config.binding,
106107
0,
107-
config.scope)
108+
scope)
109+
110+
scope = :elixir.scope_for_eval(scope, file: "iex")
108111
config.binding(binding).scope(scope)
109112
rescue
110113
exception ->

0 commit comments

Comments
 (0)