1 # Functions to build elisp files to locally configure emcas buffers.
2 # See https://github.com/shlevy/nix-buffer
14 pkgs = builtins.filter (x: x != null) pkgs';
15 extras = map (x: x.emacsBufferSetup pkgs) (
16 builtins.filter (builtins.hasAttr "emacsBufferSetup") pkgs
19 writeText "dir-locals.el" ''
20 (require 'inherit-local "${inherit-local}/share/emacs/site-lisp/elpa/inherit-local-${inherit-local.version}/inherit-local.elc")
22 ; Only set up nixpkgs buffer handling when we have some buffers active
23 (defvar nixpkgs--buffer-count 0)
24 (when (eq nixpkgs--buffer-count 0)
25 (make-variable-buffer-local 'nixpkgs--is-nixpkgs-buffer)
26 ; When generating a new temporary buffer (one whose name starts with a space), do inherit-local inheritance and make it a nixpkgs buffer
27 (defun nixpkgs--around-generate (orig name &optional ibh)
28 (if (and nixpkgs--is-nixpkgs-buffer (eq (aref name 0) ?\s))
29 (let ((buf (funcall orig name ibh)))
31 (inherit-local-inherit-child buf)
32 (with-current-buffer buf
33 (setq nixpkgs--buffer-count (1+ nixpkgs--buffer-count))
34 (add-hook 'kill-buffer-hook 'nixpkgs--decrement-buffer-count nil t)))
36 (funcall orig name ibh)))
37 (advice-add 'generate-new-buffer :around #'nixpkgs--around-generate)
38 ; When we have no more nixpkgs buffers, tear down the buffer handling
39 (defun nixpkgs--decrement-buffer-count ()
40 (setq nixpkgs--buffer-count (1- nixpkgs--buffer-count))
41 (when (eq nixpkgs--buffer-count 0)
42 (advice-remove 'generate-new-buffer #'nixpkgs--around-generate)
43 (fmakunbound 'nixpkgs--around-generate)
44 (fmakunbound 'nixpkgs--decrement-buffer-count))))
45 (setq nixpkgs--buffer-count (1+ nixpkgs--buffer-count))
46 (add-hook 'kill-buffer-hook 'nixpkgs--decrement-buffer-count nil t)
48 ; Add packages to PATH and exec-path
49 (make-local-variable 'process-environment)
50 (put 'process-environment 'permanent-local t)
51 (inherit-local 'process-environment)
52 ; setenv modifies in place, so copy the environment first
53 (setq process-environment (copy-tree process-environment))
54 (setenv "PATH" (concat "${lib.makeSearchPath "bin" pkgs}:" (getenv "PATH")))
55 (inherit-local-permanent exec-path (append '(${
56 builtins.concatStringsSep " " (map (p: "\"${p}/bin\"") pkgs)
59 (inherit-local-permanent eshell-path-env (concat "${lib.makeSearchPath "bin" pkgs}:" (if (boundp 'eshell-path-env) eshell-path-env (getenv "PATH"))))
61 (setq nixpkgs--is-nixpkgs-buffer t)
62 (inherit-local 'nixpkgs--is-nixpkgs-buffer)
64 ${lib.concatStringsSep "\n" extras}
66 # nix-buffer function for a project with a bunch of haskell packages
70 project-root, # The monorepo root
71 haskellPackages, # The composed haskell packages set that contains all of the packages
76 haskell-paths = lib.filesystem.haskellPathsInDir project-root;
77 # Find the haskell package that the 'root' is in, if any.
80 filtered = builtins.filter (
81 name: lib.hasPrefix (toString (project-root + "/${name}")) (toString root)
82 ) (builtins.attrNames haskell-paths);
84 if filtered == [ ] then null else builtins.head filtered;
85 # We're in the directory of a haskell package
86 is-haskell-package = haskell-path-parent != null;
87 haskell-package = haskellPackages.${haskell-path-parent};
88 # GHC environment with all needed deps for the haskell package
89 haskell-package-env = builtins.head haskell-package.env.nativeBuildInputs;
91 lib.optionalAttrs is-haskell-package (withPackages [ haskell-package-env ]);