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

azyzz228
The slow network is known to be an Achilles heel of LiveView’s architecture. Recently, I was working on creating a fast rendering map wi...
New
snofang
In a typical business development task, having a function in a context module which accepts attributes of map type and passes them to Ect...
New
GenericJam
I’ve been messing around with image generation models recently and thought this could be wrapped in a library or people could just use th...
New
mikesax
On a Rails/Turbo site, the first page is typically loaded using http GET and then sockets are used navigate and replace HTML content for ...
New
virinchi_cv
The Problem Phoenix 1.8 comes aggressively coupled with Daisy UI, a decision which many developers in the community have had mixed feelin...
New
cevado
IEx is a very powerfull shell and it would be awesome to have all this power integrated inside a code editor. Clojure enables something l...
New
sevensidedmarble
All the pieces are there to execute arbitrary JS commands from the server. You can put them on a data property and call them from the cli...
New
derekkraan
I have been using a multi-endpoint setup in my app, just because I think it makes the most sense for a multi-subdomain app. This worked w...
New
davydog187
I’ve been enjoying the new Streams API, but I keep needing to work around the lack of access to the underlying items. One issue that cons...
New
superchris
Currently there is no out of the box way to support DOM Custom Events in phoenix. I’ve created a separate library to do this, but I’d lov...
New

Other popular topics Top

WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 43657 311
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

We're in Beta

About us Mission Statement