Closed olejorgenb closed 7 years ago
If I get this correctly, this implies that the same process-environment
is shared between all files/buffers contained in the same nix project, whereas currently nix-shell
is called for each buffer that is opened.
@olejorgenb, can you please point out in more detail the differences and implications between your suggested change and what is already implemented in nix-sandbox.el
. Thanks.
If I get this correctly, this implies that the same process-environment is shared between all files/buffers contained in the same nix project, whereas currently nix-shell is called for each buffer that is opened.
Yes, ideally I think nix-shell should be called once per project (could check timestamp of shell.nix ofc) and the environment be shared (mostly to save some memory I guess) between the project buffers. (1)
Project would have to be defined somehow of course.
Unless I'm missing something, the functions in nix-sandbox.el
help run stuff explicitly in a nix-shell environment. That doesn't help eg. anaconda-mode. anaconda-mode provide completion and documentation lookup for python and need to know where the dependencies are. Setting process-environment
dictates which python version should be used, the dependencies (through PYTHONPATH
) and possibly more. (2)
It might be naive to think that setting the environment per buffer actually emulate closely what happens when emacs is started from within nix-shell though. It all depends on how much environment-dependent setup is done only once and not per buffer. (?)
(1) The process-environment
would probably have to be buffer-local unless emacs have a project local variable concept, but I assume it's possible to share the actual value.
(2) anaconda-mode might have some other way of providing this information, but it's a lot less hassle to use the environment and other modes might not have such mechanisms.
Project would have to be defined somehow of course.
My current definition of project is all files below a directory containing a (shell|default).nix
file.
Unless I'm missing something, the functions in nix-sandbox.el help run stuff explicitly in a nix-shell environment. That doesn't help eg. anaconda-mode. anaconda-mode provide completion and documentation lookup for python and need to know where the dependencies are.
I wrote nix-sandbox.el
originally to allow flycheck-checkers to get access to the nix environment. I guess this would allow anaconda-mode in a similar fashion to provide completions and document lookup.
(setq flycheck-command-wrapper-function
(lambda (command) (apply 'nix-shell-command (nix-current-sandbox) command))
flycheck-executable-find
(lambda (cmd) (nix-executable-find (nix-current-sandbox) cmd)))
Furthermore, I just remembered nix-sandbox.el
already calls nix-shell
only once per project since the execution environment is cached in the hash maps nix-sandbox-rc-map
and nix-exec-path-map
. When you want to update your nix configuration, simply call nix-clear-caches
, which simply clears the hash maps and nix-shell
is called again to retrieve the environment of the new configuration.
Please let me know if you still have a problem with the existing code in nix-sandbox.el
.
Yes, that's a reasonable project definition.
I guess what I'm trying to ask is if this could be a home for something a bit more general (not having to set up manual wrappers), and if you have given any thoughts to that problem :)
I just noticed that temp buffers don't inherit buffer-local variables though (which makes sense I guess). That seems like a problem for the buffer-local process-environment
approach.
(No problem with the existing code :))
(I'll reopen or make a PR if I get any further in the future)
Please do. I'm always open for improvements and discussion. Thanks @olejorgenb.
A typical problem using nix and emacsclient/server is that the environment from nix-shell isn't inherited. This break lots of functionality - anaconda-mode for python, etc.
The easiest solution is to start a dedicated emacs per nix-shell, but that's annoying.
Since all(?) of the environment is contained in the environment variables it seems like just replacing
process-environment
with the environment set up bynix-shell
should work quite well?It's possible to make
process-environment
buffer local so the changes are contained to the relevant buffers.A quick and dirty function to this is provided below:
A possible complication is whether the various modes react to changes in the environment. Anaconda mode seems to pick up the changes.
Another problem is to automate it. With the correct hooks (that hopefully runs before mode hooks) and
nix-current-sandbox
it doesn't seem to hard though. Ideally we don't want to callnix-shell
each time a new buffer is opened, and it would be nice to share theprocess-enviroment
across buffers belonging to the same project. Which start to sound like a projectile feature/plugin.A related discussion: https://github.com/flycheck/flycheck/issues/610
I can try to clean things up and create a PR, but some early feedback is always a good idea.