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.

Reply via email to