From 37895e95ca457f7df8f5e40ac2575f34371f6819 Mon Sep 17 00:00:00 2001 From: Pierre Neidhardt Date: Sat, 19 Dec 2020 18:18:18 +0100 Subject: [PATCH] SLY: Replace sbcl-nyxt implementation by a profile-based one. --- .emacs.d/lisp/init-sly.el | 123 ++++++++++---------------------------- 1 file changed, 32 insertions(+), 91 deletions(-) diff --git a/.emacs.d/lisp/init-sly.el b/.emacs.d/lisp/init-sly.el index 311fa1c9..89a6bc99 100644 --- a/.emacs.d/lisp/init-sly.el +++ b/.emacs.d/lisp/init-sly.el @@ -1,102 +1,43 @@ (require 'patch-sly) -(cl-defun ambrevar/guix-environment (&key root - (pure? t) - (preserve-args '()) - load - (packages '()) - (ad-hoc-args '()) - (command-args '())) - (apply #'call-process "guix" nil nil nil - `("environment" - ,(when pure? - "--pure") - ,@(when preserve-args - (mapcar (lambda (s) (format "--preserve=^%s$" s)) - preserve-args)) - ,(when root - (concat "--root=" root)) - ,(when load - (concat "--load=" load)) - ,@packages - ,@(when ad-hoc-args - (cons "--ad-hoc" ad-hoc-args)) - ,@(when command-args - (cons "--" command-args))))) - -(cl-defun ambrevar/lisp-implementation-from-guix-environment (&rest args - &key (load (error "Must provide file to load.")) - ad-hoc-args - command-args - &allow-other-keys) - "Like `ambrevar/guix-environment' but cache profile to speed up switch. -`lisp-repl-core-dumper' is used to speed up SBCL startup." - (let* ((load-mtime (when load - (file-attribute-modification-time (file-attributes load)))) - (root (or (cl-getf args :root) - (concat (expand-file-name "~/.guix-temp-profiles/") - (file-name-sans-extension load)))) - (root-mtime (file-attribute-modification-time (file-attributes root))) - (cache (concat (expand-file-name "~/.cache/lisp-repl-core-") - (file-name-base root)))) - (unless (and (file-exists-p root) - (or (not load-mtime) - (time-less-p load-mtime root-mtime))) - (cl-remf args :ad-hoc-args) - (cl-pushnew "lisp-repl-core-dumper" ad-hoc-args) - (cl-pushnew "coreutils" ad-hoc-args) - (setf command-args (append (list "env" (concat "LISP_REPL_CORE_PATH=" cache)) - command-args)) - (make-directory (file-name-directory root) :parents) - (apply #'ambrevar/guix-environment (append (list :root root) - (list :ad-hoc-args ad-hoc-args) - (list :command-args command-args) - args))) - `((,@(unless (not (eq nil (cl-getf args :pure?))) - '("env" "-i")) - ,(executable-find "bash") "--norc" "--noprofile" "-c" - ,(concat - (format "source '%s/etc/profile'" root) - " && LISP_REPL_CORE_PATH=" cache - " lisp-repl-core-dumper sbcl"))))) +(defun ambrevar/sbcl-for-nyxt (&optional refresh) ;; TODO: Run it in a container? + "Fast, pure Guix environment for Nyxt development. +If REFRESH is non-nil, rebuild the environment." + (cl-flet ((mtime (file) + (when (file-exists-p file) + (file-attribute-modification-time (file-attributes file))))) + (let* ((root (expand-file-name "~/.guix-temp-profiles/nyxt/nyxt")) + (guix-def (expand-file-name "~/common-lisp/nyxt/build-scripts/guix.scm")) + (guix-sbcl-def (expand-file-name "~/common-lisp/nyxt/build-scripts/guix-sbcl-for-nyxt.scm")) + (guix-checkout (format "/var/guix/profiles/per-user/%s/current-guix" (user-login-name)))) + (when (or refresh + (not (file-exists-p root)) + (time-less-p (mtime root) (mtime guix-def)) + (time-less-p (mtime root) (mtime guix-sbcl-def)) + (time-less-p (mtime root) (mtime guix-checkout))) + (make-directory (file-name-directory root) :parents) + (call-process "guix" nil nil nil "package" + ;; May be needed to avoid having to rebuild some packages + ;; after the REPL has started. + "--no-grafts" + (concat "--profile=" root) + (concat "--install-from-file=" guix-sbcl-def)) + ;; Update root mtime in case it's not changed. + ;; Can't use `set-file-times' on links. + (call-process "touch" nil nil nil "-h" root)) + `(("env" "-i" ,(concat "HOME=" (getenv "HOME")) ; HOME is needed for the ASDF cache. + ,(executable-find "bash") "--norc" "--noprofile" "-c" + ,(concat (format "source '%s/etc/profile'" root) + " && sbcl")))))) (when (executable-find "lisp-repl-core-dumper") ;; Warning: ,restart-lisp does not take changes into account, the buffer must be re-created. (setq sly-lisp-implementations `((sbcl-ambrevar ("lisp-repl-core-dumper" "sbcl" "ambrevar")) (sbcl ("lisp-repl-core-dumper" "sbcl")) - (sbcl-nyxt ;; Faster, but not pure. TODO: Run it in a container? - ;; TODO: Add easy way to reload: must delete profile. No need to delete dump if we use -f. - (lambda () - (cl-flet ((ambrevar/prepare-sbcl-for-nyxt - () - (let ((file (make-temp-file "sbcl"))) - (with-temp-file file - (insert - (format "%S" - '(mapc #'asdf:load-system - (delete-if (lambda (s) - (string= "nyxt" (subseq s 0 (min (length s) 4)))) - (append - (asdf:system-depends-on (asdf:find-system :nyxt)) - (asdf:system-depends-on (asdf:find-system :nyxt/gtk)))))))) - file))) - (let ((root (expand-file-name "~/.guix-temp-profiles/nyxt")) - (setup-file (ambrevar/prepare-sbcl-for-nyxt))) - (prog1 - (ambrevar/lisp-implementation-from-guix-environment - :root root - :load "~/common-lisp/nyxt/build-scripts/guix.scm" - :preserve-args '("PERSONAL") - :ad-hoc-args '("glib" "glib-networking" "gsettings-desktop-schemas" - ;; "nss-certs" ; Only needed in containers. - ;; "libfixposix" ; TODO: We should not need this. Delete if there is no issue after a while (Jan 2021?). - ;; For user .gpg decryption: - "gnupg") - :command-args `("lisp-repl-core-dumper" "-f" "-g" ,(format "--load %s" setup-file) "sbcl")) - (let ((delete-by-moving-to-trash nil)) - (delete-file setup-file))))))) - ;; Simple REPL environment (no container): + (sbcl-nyxt (lambda () (ambrevar/sbcl-for-nyxt))) + (sbcl-nyxt-refresh (lambda () (ambrevar/sbcl-for-nyxt :refresh))) + ;; Simple REPL environment for Nyxt, in case sbcl-nyxt does not work. (sbcl-nyxt-failsafe ("guix" "environment" "--pure" "--preserve=^PERSONAL$" ; To find personal config, like engines and bookmarks. "-l" ,(expand-file-name "~/common-lisp/nyxt/build-scripts/guix.scm")