Sounds great to me - and my concern that you couldn't emulate the correct
loading a file provided via the command line has be assuaged by realizing
you can find the `--dot-iex` arg in `:init.get_plain_arguments` - I'll open
up a pr to continue the discussion around implementation there

On Thu, Jun 6, 2024 at 2:44 PM José Valim <jose.va...@dashbit.co> wrote:

> Let's try starting with a IEx.configure(dot_iex: ...) for now. We could
> always support making it a list in the future for multiple paths.
>
> On Thu, Jun 6, 2024 at 9:42 PM Chris Miller <camiller...@gmail.com> wrote:
>
>> > That's tricky, because nowhere in IEx ends-up loading multiple dot_iex
>> files, so it would be a departure.
>> Very true - while it is technically trivial to load multiple files it is
>> a departure workflow wise and you _could_ end up with some conflicts
>> between the files - that being said, that why I had originally though a
>> different key name would provide a different context for the two things -
>> there could be the existing dot-iex concept that would work the same way as
>> it currently does with the addition of an IEx.Config.configuration_file(s?)
>> that would be an additional file(s) that are loaded either before or after
>> the dot-iex file
>>
>> > But you can always emulate multiple files with import_if_available.
>> This is also very true! I think the only potential downside I could think
>> of for this is that it would be slightly more restrictive than the multiple
>> file approach.  If you had a `dot-iex` file configured in your project and
>> then ran `iex --dot-iex other_file.exs -S mix` you may be confused by the
>> fact that your file didn't get loaded as expected
>>
>> That being said - I defer to your judgement on the best approach here and
>> if this is valuable!
>> As always, really appreciate your time and all of your work!
>>
>> On Thu, Jun 6, 2024 at 2:29 PM José Valim <jose.va...@dashbit.co> wrote:
>>
>>> That's tricky, because nowhere in IEx ends-up loading multiple dot_iex
>>> files, so it would be a departure. But you can always emulate multiple
>>> files with import_if_available.
>>>
>>> On Thu, Jun 6, 2024 at 9:26 PM Chris Miller <camiller...@gmail.com>
>>> wrote:
>>>
>>>> I think that would get us pretty close to the behavior I was hoping for
>>>> - but I was generally hoping that instead of taking precedence over an
>>>> existing dot-iex configured file it could be used in addition to the
>>>> existing dot-iex file.  This might be hyper specific to my individual
>>>> workflow, but I was hoping that we could add a feature to allow for
>>>> application level configuration while also still using the existing dot-iex
>>>> files to provide local configuration
>>>>
>>>> An example would be that we would use the new application level
>>>> configuration to import some helper function and cat out some introduction
>>>> / instruction to the prompt, while the local would be some functions or
>>>> data that I as a developer have around for development / debugging but are
>>>> very specific to my development.
>>>>
>>>> What are your thoughts on this multi-file configuration?
>>>>
>>>> On Thu, Jun 6, 2024 at 2:19 PM José Valim <jose.va...@dashbit.co>
>>>> wrote:
>>>>
>>>>> Yeah, we can add a IEx.configure(dot_iex: "..."), which takes
>>>>> precedence over the other ones if set. And we should read it in the same
>>>>> place we read everything else.
>>>>>
>>>>> On Thu, Jun 6, 2024 at 9:08 PM Chris Miller <camiller...@gmail.com>
>>>>> wrote:
>>>>>
>>>>>> I hadn't considered the config, but thats an interesting thought -
>>>>>> not entirely sure if I totally get your though on the matter, but I was
>>>>>> able to extend the IEx.Config to track a new key (:configuration_files) 
>>>>>> and
>>>>>> then extended the IEx.Evaluator to pull that value from the config and 
>>>>>> load
>>>>>> the configured files plus the `.iex.exs` file.  This allows the feature 
>>>>>> to
>>>>>> be used either through a call to `IEx.configure/1` before the evaluator
>>>>>> starts, or the config can be added into any config file, which would 
>>>>>> allow
>>>>>> you to easily swap config files per env if desired
>>>>>>
>>>>>> On Thursday, June 6, 2024 at 1:50:44 PM UTC-5 José Valim wrote:
>>>>>>
>>>>>>> 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 <camil...@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-co...@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/a01b0032-13ee-45a1-b59b-5320a70e3322n%40googlegroups.com
>>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/a01b0032-13ee-45a1-b59b-5320a70e3322n%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>>> .
>>>>>>
>>>>> --
>>>>> You received this message because you are subscribed to a topic in the
>>>>> Google Groups "elixir-lang-core" group.
>>>>> To unsubscribe from this topic, visit
>>>>> https://groups.google.com/d/topic/elixir-lang-core/qphuwdQxcsc/unsubscribe
>>>>> .
>>>>> To unsubscribe from this group and all its topics, 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/CAGnRm4JX6KYe1En8WsCQeLhHF8SXnMB7jqps-qcwYKQwNWRimw%40mail.gmail.com
>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4JX6KYe1En8WsCQeLhHF8SXnMB7jqps-qcwYKQwNWRimw%40mail.gmail.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/CAOZBLdORTXogFXez02uX1NCU1dskL2opqFB9HQRpdGAFNEM8NA%40mail.gmail.com
>>>> <https://groups.google.com/d/msgid/elixir-lang-core/CAOZBLdORTXogFXez02uX1NCU1dskL2opqFB9HQRpdGAFNEM8NA%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>> .
>>>>
>>> --
>>> You received this message because you are subscribed to a topic in the
>>> Google Groups "elixir-lang-core" group.
>>> To unsubscribe from this topic, visit
>>> https://groups.google.com/d/topic/elixir-lang-core/qphuwdQxcsc/unsubscribe
>>> .
>>> To unsubscribe from this group and all its topics, 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/CAGnRm4Kd6NeDoZQ%2Bx6i%3DwNj4yHK0pmoby5ay_CGkQqDcMCiCRg%40mail.gmail.com
>>> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4Kd6NeDoZQ%2Bx6i%3DwNj4yHK0pmoby5ay_CGkQqDcMCiCRg%40mail.gmail.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/CAOZBLdOBYmuwaURE0uXNfJa-%2B4hyjbiDjYnkMs5XowXGasNp5g%40mail.gmail.com
>> <https://groups.google.com/d/msgid/elixir-lang-core/CAOZBLdOBYmuwaURE0uXNfJa-%2B4hyjbiDjYnkMs5XowXGasNp5g%40mail.gmail.com?utm_medium=email&utm_source=footer>
>> .
>>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "elixir-lang-core" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/elixir-lang-core/qphuwdQxcsc/unsubscribe
> .
> To unsubscribe from this group and all its topics, 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/CAGnRm4%2B3mtzv73tnqWo9cg%2BwEVoDgd%2ByC%3DA8RmhN%3Dj%3DVENmk4w%40mail.gmail.com
> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4%2B3mtzv73tnqWo9cg%2BwEVoDgd%2ByC%3DA8RmhN%3Dj%3DVENmk4w%40mail.gmail.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/CAOZBLdOuEyTGzAue1q5tKz0D%2BzAkyDnSvFjgXeHt1ATqGrBsQg%40mail.gmail.com.

Reply via email to