[ESS] Launching R executables within custom shell environments

Dominic Steinitz dom|n|c @end|ng |rom @te|n|tz@org
Tue Apr 5 16:30:44 CEST 2022


> Dear ESS users,
> 
> I'm interested if there is anyone on this mailing list who uses Emacs
> Speaks Statistics from within Guix or Nix, both of which bake
> reproducibility directly into their operating systems) or from anyone
> who might otherwise be familiar with some elisp code which uses the ESS
> remote session functionality to start an R interpreter from a different
> environment on the local system (such that it behaves great without
> having to worry about conflicting environment variables)?
> 
> That was a mouthful, but I hope that was enough to peak someones
> interest. I'm just looking to see if this problem has already been
> well handled.
> 
> Thanks,
> Kyle

Hi Kyle,

I use `direnv` and https://github.com/purcell/envrc. I can’t remember the exact sequence but I think I did `nix-env -i direnv` and then set up a `.envrc` with the line `use nix` in it. You might have to do `M-x envrc-allow`. Then your nix environment is available in emacs (as well as the same one being in a shell). Then I just `M-x R`. 

FWIW I have

```

 '(package-selected-packages
   '(forge poly-markdown polymode poly-R envrc direnv json-mode stan-mode git-timemachine ein markdown-mode exec-path-from-shell nix-mode ess matlab-mode haskell-mode helm magit use-package))

```

And my current `shell.nix` is

```

let

rOverlay = rself: rsuper: {
  rPackages = rsuper.rPackages.override {
    overrides = {
      smcsamplers = (rself.rPackages.buildRPackage {
        name = "smcsamplers";
        src = rself.fetchFromGitHub {
          owner = "pierrejacob";
          repo = "smcsamplers";
          rev = "097192f7d5df520d9b026d442dfec493a3051374";
          sha256 = "00facn1ylcbai4sbcidpp991899csz2ppmmkv0khvqxfncddr0f2";
        };
        propagatedBuildInputs = [ rsuper.rPackages.coda rsuper.rPackages.MASS rsuper.rPackages.mvtnorm rsuper.rPackages.loo rsuper.rPackages.shape rsuper.rPackages.rstan rsuper.rPackages.tidyverse rsuper.rPackages.doParallel rsuper.rPackages.igraph rsuper.rPackages.ggraph rsuper.rPackages.doRNG rsuper.rPackages.reshape2 ];
      });

      cmdstanr = (rself.rPackages.buildRPackage {
        name = "cmdstanr";
        src = rself.fetchFromGitHub {
          owner = "stan-dev";
          repo = "cmdstanr";
          rev = "2e24ec873c5513b41fba90ee59e0dffcd27a479c";
          sha256 = "sha256:0nrqlidsrykszasdypsldsbhv4dcbrj9awyyzq7rb6kc5y8fnhvi";
        };
        propagatedBuildInputs = [ rsuper.rPackages.coda rsuper.rPackages.MASS rsuper.rPackages.mvtnorm rsuper.rPackages.loo rsuper.rPackages.shape rsuper.rPackages.rstan rsuper.rPackages.tidyverse rsuper.rPackages.doParallel rsuper.rPackages.igraph rsuper.rPackages.ggraph rsuper.rPackages.doRNG rsuper.rPackages.reshape2 rsuper.rPackages.data_table rsuper.rPackages.posterior ];
      });

    };
  };
};

myHaskellPackageOverlay = self: super: {
  myHaskellPackages = super.haskell.packages.ghc921.override {
    overrides = hself: hsuper: rec {

      inline-r = super.haskell.lib.dontCheck (
        hself.callCabal2nixWithOptions "inline-r" (builtins.fetchGit {
          url = "https://github.com/tweag/HaskellR";
          rev = "c3ba1023480e26ade420896bcb629ceaad59f308";
        }) "--subpath inline-r" { });

      singletons = self.haskell.lib.addBuildDepends(
        hself.callHackageDirect {
          pkg = "singletons";
          ver = "3.0.1";
          sha256 = "sha256-ixHWZae6AxjRUldMgpYolXBGsOUT5ZVIw9HZkxrhHQ0=";
        } { }) [ ];

    };
  };
};

in

{ nixpkgs ? import "/Users/dom/nixpkgs" {
  config.allowBroken = true;
  overlays = [ myHaskellPackageOverlay rOverlay ];
  # system = "x86_64-darwin";
}
}:

let
  R-with-my-packages = nixpkgs.rWrapper.override{
    packages = with nixpkgs.rPackages; [
      ggplot2
    ]; };

  pkgs = nixpkgs;

  haskellDeps = ps: with ps; [
    base
    cassava
    conduit
    Frames
    streamly
    (pkgs.haskell.lib.dontCheck Frames-streamly)
    hasql
    http-client
    http-client-tls
    http-conduit
    postgresql-binary
    (pkgs.haskell.lib.dontCheck inline-r)
    resourcet
    time
    vinyl
    xlsx
    zip
  ];

in

pkgs.stdenv.mkDerivation {
  name = "xxx";

  buildInputs = with pkgs.rPackages; [
    pkgs.libintlOrEmpty
    R-with-my-packages
    (pkgs.myHaskellPackages.ghcWithPackages haskellDeps)
    pkgs.darwin.apple_sdk.frameworks.Cocoa
  ];
  shellHook = ''
    R_LIBS_USER=$(Rscript -e ".libPaths()" | cut -c 6- | sed 's/[ \t]*$//' | sed 's/"//g' | sed -z 's/\n/:/g;s/:'''$/\n/' | sed 's/ //g')
    export R_LIBS_USER
    '';
}

```

I am guessing you don’t need the Haskell stuff. `The shellHook` is there so that Haskell picks up the “right” set of R libraries. I am sure it can be improved; I am barely an intermediate nix user. Oh I nearly forgot - because I was trying to fix something, I am pointing at my local copy of Nixpkgs. Clearly it should be pinned to something more permanent and reproducible.
 
Dominic Steinitz
dominic using steinitz.org
http://idontgetoutmuch.org
Twitter: @idontgetoutmuch


	[[alternative HTML version deleted]]



More information about the ESS-help mailing list