rekkice

rekkice

IEx - Expose API to evaluate code inside IEx session for REPL Integrations

I’m building an editor integration to evaluate Elixir code in an IEx session. While Code.eval_string/3 allows tracking variable bindings, i think there’s currently no way to persist the environment (aliases, imports, etc.) between evaluations using this approach.

Use Case:

  • User is using an editor to send code to IEx (through a named pipe, e.g.), which is then read by a custom module defined in .iex.exs.
  • User defines alias MyApp.Module in one evaluation.
  • In subsequent evaluations, they expect Module.function() to work (as if it would in a regular IEx shell).

Proposal:
Expose a public API to evaluate code directly in the IEx instance, e.g.:

# it could be a helper function
result = IEx.Helpers.eval_string("IO.puts(123)")

# or maybe work by directly sending a message to IEx’s evaluator process (e.g., using eval_pid() if such a function were available)
send(eval_pid(), {:eval, "IO.puts(123)"})

I think this would make integrating IEx with external tools such as code editors a much easier task. Helix allows piping selected code directly to a Bash command, so i was using that to send code to a named pipe and read that in IEx. IEx is very useful, but i always experience some friction between it and my editor because i have to manually copy and paste code to it.

I found this post from a while ago that suggests something that i think would work for my case, but i tried it on Elixir 1.18.1 with OTP 26 and it didn’t work, maybe because it’s not a public API.

I’d love to hear if others have faced similar challenges or if there’s an existing approach i might have missed. I’d also be happy to contribute to this implementation if there’s interest, though I’m still learning Elixir and don’t have experience with Erlang.

Most Liked

v0idpwn

v0idpwn

Hi,

I think most of what you want is achievable with Code:

def iterative_eval(code, bindings \\ [], env \\ env_for_eval([])) do
  quoted = Code.string_to_quoted(code)
  Code.eval_quoted_with_env(quoted, bindings, env)
end

Which can be used as:

iex(5)> {result, bindings, env} = Repl.iterative_eval("a = 1"); :ok # Using this `:ok` to avoid printing env
:ok
iex(6)> {result, bindings, env} = Repl.iterative_eval("a + 2", bindings, env); :ok
:ok
iex(7)> result
{:ok, 3}
iex(8)> bindings
[a: 1]

It carries the env, hence it carries aliases, requires, etc. To use the env from iex, you can just use __ENV__:

iex(9)> alias Map, as: M
Map
iex(10)> {result, bindings, env} = Repl.iterative_eval("map = M.new()", [], __ENV__); :ok
:ok
iex(11)> result
{:ok, %{}}
iex(12)> bindings
[map: %{}]
iex(13)> 

I don’t know if there’s a way to load these bindings/env back in iex, though.

Where Next?

Popular in Proposals: Ideas Top

kip
Sumary of proposal DateTime.from_iso8601/3 adjusted to: set all numeric fields to the values as parsed (not shifted to UTC), preservi...
New
mudasobwa
I am not sure it deserves to be discussed in the mailing list, so I’d start here. assert/1 and/or refute/1 macros print the following er...
New
markevans
Hi! I’m excited about everything that’s going on re. gradual typing and am really pleased to see that Jose and the team seem to be think...
New
sodapopcan
So after complaining about this for the third or fourth time on this forum, I figured I should make a proposal. TL;DR with can be hard t...
New
ffloyd
The Problem Currently, if I define a struct in the following way: defmodule MyStruct do # Both x and y will have the FIXED values unti...
New
7rans
I implemented Access behavior for a struct today. Pseudo-code… defmodule MyStruct do defstruct data: %{} @behaviour Access # ... ...
New
winsalva
Hello all. First of all i’m running this using termux on an android phone. Running mix assets.setup shows this message 06:54:08.450 [de...
New
nhpip
So the other day I was rearranging the supervisor hierarchy of our product and I had a thought. In addition to creating a child spec with...
New
Oliver
One common problem we face in constructing lists is that there is (AFAIK) no support for conditionally inserting members into list declar...
New
pejrich
I propose adding compact_map/2 to the Enum module. What is it? Sometimes you want to map over a collection, but sometimes you want to ma...
New

Other popular topics Top

yurko
Here are few pieces of (common) Linux knowledge that we use for reasonably small one server apps. We use Ubuntu but this should work for ...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list....
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New

We're in Beta

About us Mission Statement