I wonder if you could call something like "IEx.configure(...)" from the top of your mix.exs and that would be enough to configure its location. Or maybe it would only require a small tweak to make it work.
On Thu, Jun 6, 2024 at 8:22 PM Chris Miller <camiller...@gmail.com> wrote: > Actually - I am a little confused by the startup dependencies between mix > and iex as it seems like the Evaluator is starting after mix (or at least > that how it appears in my tests), this patch to the IEx.Evaluator seems to > accomplish what I was hoping to achieve (but it does make IEx depend on Mix > which may have been something you wanted to avoid, but perhaps there is > some more abstract way of getting this information from the mix project to > the evaluator) > > ```elixir > defp load_dot_iex(state, path) do > candidates = > if path do > [path] > else > # Do not assume there is a $HOME > for dir <- [".", System.get_env("IEX_HOME") || System.user_home()], > dir != nil, > do: dir |> Path.join(".iex.exs") |> Path.expand() > end > > mix_config_file = > List.wrap(Mix.Project.get().cli()[:iex_configuration_file]) > > candidates > |> Enum.filter(&File.regular?/1) > |> Enum.take(1) > |> Enum.concat(mix_config_file) > |> Enum.reduce(state, fn path, state -> > eval_dot_iex(state, path) > end) > end > ``` > Once again - sorry for the noise if this in not a feature you are > interested in introducing! > > On Thursday, June 6, 2024 at 12:43:09 PM UTC-5 Chris Miller wrote: > >> Thanks for the reply Jose! The dependency order makes sense as an issue >> with my initial thought - one other approach is that a project could define >> its own method of configuring IEx if there were a hook to allow that - >> looking at the IEx.Evaluator I was able to make a pretty small patch to >> allow for this type of configuration by adding a new public function and >> extending the `loop` function >> >> ```elixir >> @spec load_dot_iex(pid, pid, String.t()) :: :ok | :error >> def load_dot_iex(evaluator, server, path) do >> ref = make_ref() >> send(evaluator, {:load_dot_iex, server, ref, self(), path}) >> >> receive do >> {^ref, result} -> result >> after >> 5000 -> :error >> end >> end >> >> ... >> >> defp loop(%{server: server, ref: ref} = state) do >> receive do >> {:eval, ^server, code, counter, parser_state} -> >> {status, parser_state, state} = parse_eval_inspect(code, counter, >> parser_state, state) >> send(server, {:evaled, self(), status, parser_state}) >> loop(state) >> >> {:fields_from_env, ^server, ref, receiver, fields} -> >> send(receiver, {ref, Map.take(state.env, fields)}) >> loop(state) >> >> {:value_from_binding, ^server, ref, receiver, var_name, >> map_key_path} -> >> value = traverse_binding(state.binding, var_name, map_key_path) >> send(receiver, {ref, value}) >> loop(state) >> >> {:variables_from_binding, ^server, ref, receiver, var_prefix} -> >> value = find_matched_variables(state.binding, var_prefix) >> send(receiver, {ref, value}) >> loop(state) >> >> # NEW RECEIVE CASE TO LOAD A DOT IEX FILE PROGRAMMATICALY >> {:load_dot_iex, ^server, ref, receiver, path} -> >> next_state = load_dot_iex(state, path) >> send(receiver, {ref, :ok}) >> loop(next_state) >> >> {:done, ^server, next?} -> >> {:ok, next?} >> >> {:done, ^ref, next?} -> >> {:ok, next?} >> end >> end >> ... >> >> I think that combining this overriding the default mix task would allow >> for the type of configuration that I was hoping to achieve - or if there is >> desire for this functionality a small change could be incorporated into mix >> to do this as a feature using `project.cli()[:iex_configuration_file]` or >> something of the sort. >> >> If you don't think any of this is necessary in Elixir proper I can move >> my work towards something at the project level, but wanted to see if there >> was any interest in upstreaming this concept >> On Thursday, June 6, 2024 at 11:40:51 AM UTC-5 José Valim wrote: >> >>> Hi Chris, thanks for writing. >>> >>> > • will be used when `iex` is run from that directory not in the >>> context of that mix project >>> >>> The reason this happens is exactly because IEx starts before Mix, so we >>> can't use Mix to configure IEx. And I think that will get in the way of >>> your proposal too. I hope this helps narrow down a bit the paths to explore. >>> >>> On Thu, Jun 6, 2024 at 4:23 PM Chris Miller <camil...@gmail.com> wrote: >>> >>>> Currently we use the `dot-iex` file to configure an iex shell. The >>>> `dot-iex` file that gets loaded is the first of these three things that is >>>> found >>>> • --dot-iex PATH command line argument supplied to the iex command >>>> • '.iex.exs' file in the directory that iex is run from >>>> • '.iex.exs' file in directory found in the env var "IEX_HOME" OR the >>>> users home directory >>>> >>>> The issue I am facing currently is that project level shell >>>> configuration is hard to manage in a way that achieves these goals >>>> • will apply configuration when running a shell in the context of a >>>> particular (mix) project >>>> • will allow for a developer to apply their own particular customization >>>> • does not require any additional scripts / arguments to start the >>>> project >>>> >>>> Existing partial solutions for a project level iex configuration >>>> >>>> • create and commit a `.iex.exs` file for the project >>>> -- PROS: >>>> • the file will be loaded when `iex -S mix` is run >>>> • configuration can be specific to the project as it is part of the >>>> source code written for the project and tracked through whatever svc is >>>> used >>>> -- CONS: >>>> • does not allow for an individual developer to include their own >>>> configuration as expected (you could add an >>>> `import_if_avaiable(".dev.iex.exs")` line to the project level `.iex.exs` >>>> file to allow for this extension, but it makes the file name arbitrary and >>>> could cause some confusion) >>>> • will be used when `iex` is run from that directory not in the >>>> context of that mix project >>>> >>>> • create a project specific configuration file and use the --dot-iex >>>> command line arg >>>> -- PROS: >>>> • does not interfere with running `iex` outside of the context of >>>> the mix project >>>> • can load additional configuration files by include >>>> `import_if_avaiable` statements >>>> -- CONS: >>>> • Requires including the --dot-iex arg when running the `iex -S >>>> mix` command, which is prone to being forgotten, this could be wrapped in a >>>> very simple start script, but you would still need to remember to run that >>>> (I work with a largish number of elixir services and having individual >>>> start scripts or args per project can be cumbersome to remember) >>>> >>>> I think an ideal solution would be a way to configure a mix project to >>>> load a particular configuration file that will be loaded when the >>>> IEx.Evaluator starts IN ADDITION to the existing `dot-iex` file options. I >>>> believe this would allow for maintainers of a project to normalize some >>>> shell configuration while still allowing developers the full ability to add >>>> their own configuration while also keeping the workflow of starting the >>>> shell more standardized across projects. >>>> >>>> A secondary goal might be that this could be incorporated into releases >>>> as well so that the `./bin/project remote` and similar commands could also >>>> load some particular configuration >>>> >>>> Thanks in advance for any thoughts you had, and if I missed any >>>> existing options for this type of configuration, let me know! >>>> >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "elixir-lang-core" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to elixir-lang-co...@googlegroups.com. >>>> To view this discussion on the web visit >>>> https://groups.google.com/d/msgid/elixir-lang-core/a956613f-7ef1-435c-8aaf-ab3af8058d5dn%40googlegroups.com >>>> <https://groups.google.com/d/msgid/elixir-lang-core/a956613f-7ef1-435c-8aaf-ab3af8058d5dn%40googlegroups.com?utm_medium=email&utm_source=footer> >>>> . >>>> >>> -- > You received this message because you are subscribed to the Google Groups > "elixir-lang-core" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to elixir-lang-core+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/elixir-lang-core/085f777f-3b9c-4ef1-8787-d1396c13fc88n%40googlegroups.com > <https://groups.google.com/d/msgid/elixir-lang-core/085f777f-3b9c-4ef1-8787-d1396c13fc88n%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "elixir-lang-core" group. To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4Jq7noduzak77F22F3W7o8FBU-NsrP_FMA9%3DhtV4Z4Hjw%40mail.gmail.com.