6

I'm fairly new to NixOS, and am trying to invoke emacs from a Haskell program using the following function:

ediff :: String -> String -> String -> IO ()
ediff testName a b = do
  a' <- writeSystemTempFile (testName ++ ".expected") a
  b' <- writeSystemTempFile (testName ++ ".received") b
  let quote s = "\"" ++ s ++ "\""
  callCommand $ "emacs --eval \'(ediff-files " ++ quote a' ++ quote b' ++ ")\'"

When I run the program that invokes this command using stack test, I get the following result (interspersed with unit test results):

/bin/sh: emacs: command not found
Exception: callCommand: emacs --eval '(ediff-files "/run/user/1000/ast1780695788709393584.expected" "/run/user/1000/ast4917054031918502651.received")'

When I run the command that failed to run above from my shell, it works flawlessly. How can I run processes from Haskell in NixOS, as though I had invoked them directly, so that they can access the same commands and configurations as my user?

1 Answer 1

3

Both your shell and callCommand use the PATH environment variable, so it seems like stack is changing that. It turns out that stack uses a pure nix shell by default, but you also want to access your user environment, which is 'impure'.

To quote the stack documenation

By default, stack will run the build in a pure Nix build environment (or shell), which means the build should fail if you haven't specified all the dependencies in the packages: section of the stack.yaml file, even if these dependencies are installed elsewhere on your system. This behaviour enforces a complete description of the build environment to facilitate reproducibility. To override this behaviour, add pure: false to your stack.yaml or pass the --no-nix-pure option to the command line.

Another solution is to add Emacs to nix.dependencies in stack.yaml (thanks @chepner). It has the benefit that some version of Emacs will always be available when a developer runs the tests, but that Emacs may not be the Emacs they want to use. You may be able to work around that using something like ~/.config/nixpkgs/config.nix, unless they have configured their Emacs elsewhere, like the system configuration or perhaps a home manager. I'd prefer the simple but impure $PATH solution.

Sign up to request clarification or add additional context in comments.

2 Comments

The solution would be to add emacs to the dependency list, though, rather than using an impure environment, right?
Thanks! I haven't had time to use your suggestions just yet, but this is very informative.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.