about summary refs log tree commit diff
path: root/emacs/.emacs.d/wpc/wpc-nix.el
blob: 501531f23789b01cf08c40bb43a9194ba3bfe463 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
;;; wpc-nix.el --- Nix support -*- lexical-binding: t -*-
;; Author: William Carroll <wpcarro@gmail.com>

;;; Commentary:
;; Configuration to support working with Nix.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Dependencies
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(require 'device)

;; TODO: These may fail at startup. How can I make sure that the .envrc is
;; consulted when Emacs starts?
(prelude/assert (f-exists? (getenv "BRIEFCASE")))
(prelude/assert (f-exists? (getenv "DEPOT")))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Library
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(use-package nix-mode
  :mode "\\.nix\\'")

;; TODO(wpcarro): Ensure the sub-process can resolve <briefcase>.
(defun nix/rebuild-emacs ()
  "Use nix-env to rebuild wpcarros-emacs."
  (interactive)
  (let* ((emacs (if (device/corporate?) "emacs.glinux" "emacs.nixos"))
         (pname (format "nix-build <briefcase/%s>" emacs))
         (bname (format "*%s*" pname)))
    (start-process pname bname
                   "nix-env"
                   "-I" (format "nixpkgs=%s" (f-expand "~/nixpkgs"))
                   "-I" (format "depot=%s" (f-expand "~/depot"))
                   "-I" (format "briefcase=%s" (f-expand "~/briefcase"))
                   "-f" "<briefcase>" "-iA" emacs)
    (display-buffer bname)))

(defun nix/home-manager-switch ()
  "Use Nix to reconfigure the user environment."
  (interactive)
  (start-process "nix/home-manager-switch" "*nix/home-manager-switch*"
                 "home-manager"
                 "-I" (format "nixpkgs=%s" (f-expand "~/nixpkgs"))
                 "-I" (format "home-manager=%s" (f-expand "~/home-manager"))
                 "switch")
  (display-buffer "*nix/home-manager-switch*"))

(defun nix/sly-from-briefcase (attribute)
  "Start a Sly REPL configured with a Lisp matching a derivation
  from my monorepo.

This function was taken from @tazjin's depot and adapted for my monorepo.

  The derivation invokes nix.buildLisp.sbclWith and is built
  asynchronously. The build output is included in the error
  thrown on build failures."
  (interactive "sAttribute: ")
  (lexical-let* ((outbuf (get-buffer-create (format "*briefcase-out/%s*" attribute)))
         (errbuf (get-buffer-create (format "*briefcase-errors/%s*" attribute)))
         (expression (format "let briefcase = import <briefcase> {}; in briefcase.third_party.depot.nix.buildLisp.sbclWith [ briefcase.%s ]" attribute))
         (command (list "nix-build" "-E" expression)))
    (message "Acquiring Lisp for <briefcase>.%s" attribute)
    (make-process :name (format "nix-build/%s" attribute)
                  :buffer outbuf
                  :stderr errbuf
                  :command command
                  :sentinel
                  (lambda (process event)
                    (unwind-protect
                        (pcase event
                          ("finished\n"
                           (let* ((outpath (s-trim (with-current-buffer outbuf (buffer-string))))
                                  (lisp-path (s-concat outpath "/bin/sbcl")))
                             (message "Acquired Lisp for <briefcase>.%s at %s" attribute lisp-path)
                             (sly lisp-path)))
                          (_ (with-current-buffer errbuf
                               (error "Failed to build '%s':\n%s" attribute (buffer-string)))))
                      (kill-buffer outbuf)
                      (kill-buffer errbuf))))))

(provide 'wpc-nix)
;;; wpc-nix.el ends here