Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at devShellTools-shell 92 lines 4.1 kB view raw
1# Functions to build elisp files to locally configure emacs buffers. 2# See https://github.com/shlevy/nix-buffer 3 4{ 5 lib, 6 writeText, 7 inherit-local, 8}: 9 10rec { 11 withPackages = 12 pkgs': 13 let 14 pkgs = builtins.filter (x: x != null) pkgs'; 15 extras = map (x: x.emacsBufferSetup pkgs) ( 16 builtins.filter (builtins.hasAttr "emacsBufferSetup") pkgs 17 ); 18 in 19 writeText "dir-locals.el" '' 20 (require 'inherit-local "${inherit-local}/share/emacs/site-lisp/elpa/inherit-local-${inherit-local.version}/inherit-local.elc") 21 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))) 30 (progn 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))) 35 buf) 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) 47 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) 57 }) exec-path)) 58 59 (inherit-local-permanent eshell-path-env (concat "${lib.makeSearchPath "bin" pkgs}:" (if (boundp 'eshell-path-env) eshell-path-env (getenv "PATH")))) 60 61 (setq nixpkgs--is-nixpkgs-buffer t) 62 (inherit-local 'nixpkgs--is-nixpkgs-buffer) 63 64 ${lib.concatStringsSep "\n" extras} 65 ''; 66 # nix-buffer function for a project with a bunch of haskell packages 67 # in one directory 68 haskellMonoRepo = 69 { 70 project-root, # The monorepo root 71 haskellPackages, # The composed haskell packages set that contains all of the packages 72 }: 73 { root }: 74 let 75 # The haskell paths. 76 haskell-paths = lib.filesystem.haskellPathsInDir project-root; 77 # Find the haskell package that the 'root' is in, if any. 78 haskell-path-parent = 79 let 80 filtered = builtins.filter ( 81 name: lib.hasPrefix (toString (project-root + "/${name}")) (toString root) 82 ) (builtins.attrNames haskell-paths); 83 in 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; 90 in 91 lib.optionalAttrs is-haskell-package (withPackages [ haskell-package-env ]); 92}