Nix-Shell Questions from a New Emacs user
CMCDragonkai opened this issue · 8 comments
I'm new to spacemacs and have only been using it for a couple months, but I work in NixOS and make use of nix-shell alot.
One of the interesting consequences of this, is that many projects have dependencies which are now isolated within a nix-shell.
However various spacemacs layers work on the basis of running external commands, like the sqli layer expects mysql
to be available on the PATH.
What I've done atm is often install the layer requirements in my user profile, and also in the shell.nix. So when I run things from nix-shell, I end up using the shell.nix specified dependencies, while spacemacs ends up using the config.nix specified dependencies. While this hack works, it's not very elegant.
I've read in other places, that people would launch emacs from within the nix-shell, and while this could work, how does one deal with multiple projects each with their own nix-shell, does multiple instances of emacs work nicely together, do copy and paste and switching between buffers work seamlessly? I don't know atm.
Just wanted to know other people's thoughts on this issue, and whether there are ideas for making IDE-centric development workflow work with nix-shell like isolation. I thought that if there was an editor that was made from ground up to allow multiple instances of the editor to run and to have a overall chrome/server that allowed coordination between each instance, sort of like the Chrome browser where each tab is a separate process. Then such an editor would actually work nicely with nix-shell.
I guess there's two issues here:
- Getting project-specific inputs (for instance libraries and headers) and getting Emacs and its modes to find them. shlevy/nix-buffer can provide this for you, although I've found it a little annoying to setup. Eventually I think we can get this to just work with no extra config but that's not true right now.
- Related, is providing "hidden" dependencies of Emacs modes. Usually modes require a few executables to be in your path, but they also make it customizable, usually ending in
-program
or-command
. Just providing those in yourPATH
variable isn't that bad of an option, but it probably will litter your profile. The way I solve this, it by generating my Emacs config within Nix expressions. Each path is "generated" using substitutions. Check out the settings here in default.el. Each@package@
corresponds to a Nix store path and they are generated each time the Emacs wrapper is built within .nixpkgs/config.nix. It's a little complicated and I need to do a writeup on it because it's been extremely useful for me. I'm not sure how easily it fits into Spacemacs, but with some work you can probably get it to work with the "layers".
Edit: It looks like @svenkeidel has written something called nix-sandbox.el
that is very similar to nix-buffer.el. I'll need to investigate what it's doing but it looks like it just sets exec-path
and PATH
while nix-buffer.el
can theoretically run any Elisp code you want to "source" a package's build environment.
@CMCDragonkai, nix-sandbox
does not set the executable path, but it allows to search in the executable path of a nix project with nix-executable-find
.
To integrate it into Emacs, call this function whenever a new a plugin searches for a path of an external dependency:
(setq flycheck-command-wrapper-function
(lambda (cmd) (apply 'nix-shell-command (nix-current-sandbox) cmd))
flycheck-executable-find
(lambda (cmd) (nix-executable-find (nix-current-sandbox) cmd)))
Emacs search for an executable in directories listed in the exec-path
variable, when a nix-shell is activated it updates the $PATH
environment variable with respective paths; my approach is overwrite exec-path
and process-environment
with the ones provided by nix-shell: https://github.com/emacs-pe/nix-mode/blob/master/nix-shell.el, you can use nix-shell-activate
to enable an nix-shell from a directory and nix-shell-deactivate
to disable it.
@marsam Just to clarify, your nix-mode is part of the nixos layer in Spacemacs, but this repository hasn't been integrated into a Spacemacs nixos layer yet right? Or only parts of this repository has been integrated. Because the nixos layer on spacemacs doesn't mention nix-sandbox. https://github.com/syl20bnr/spacemacs/tree/master/layers/%2Bos/nixos
Actually your nix-mode might not be the same nix-mode as the one used in spacemacs as that points to https://github.com/NixOS/nix/blob/master/misc/emacs/nix-mode.el
I'm hoping somebody made progress on this front to automate the integration of Spacemacs and Nix-shell. I haven't had time to explore all the possible options.
@CMCDragonkai sorry for the late response
Just to clarify, your nix-mode is part of the nixos layer in Spacemacs, but this repository hasn't been integrated into a Spacemacs nixos layer yet right?
yes, is my personal nix-mode, is way different from the official nix-mode.
I'm hoping somebody made progress on this front to automate the integration of Spacemacs and Nix-shell. I haven't had time to explore all the possible options.
I've made nix-shell.el
standalone, so you can download it and install it in your load-path
; you can use nix-shell-activate
to activate a nix-shell. Please create an issue if you have any problems.
https://www.reddit.com/r/haskell/comments/935u0q/best_ide_for_nixcabal_builds/e3cbqk9/?context=3
relevant discussion on reddit