Subject: [emacs-guix] elisp: Change guix-set-emacs-environment to use local variables.

From: Janneke Nieuwenhuizen <[email-masked]>
Date: Wed, 22 Jan 2025 09:30:58 +0100

This changes the semantics of "guix-set-emacs-environment" and that's
probably what one would expect.  Keeping old functionality as
"guix-set-emacs-environment-global".

* elisp/guix-misc.el (guix-set-emacs-environment): Rename to...:
(guix-set-emacs-environment-global): ...this.
(guix-set-emacs-environment): New procedure setting a buffer-local environment.
* doc/emacs-guix.texi (Miscellaneous Commands): Update accordingly.
Add hint about "emacs-envrc".
---
 doc/emacs-guix.texi | 17 +++++++++++++----
 elisp/guix-misc.el  | 33 ++++++++++++++++++++++++++++++---
 2 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/doc/emacs-guix.texi b/doc/emacs-guix.texi
index 3219354..d073cb8 100644
--- a/doc/emacs-guix.texi
+++ b/doc/emacs-guix.texi
@@ -11,6 +11,7 @@ This document describes Emacs-Guix, the Emacs interface for the
 @quotation
 Copyright @copyright{} 2014-2019, 2021 Alex Kost@*
 Copyright @copyright{} 2018 Oleg Pykhalov
+Copyright @copyright{} 2018, 2025 Janneke Nieuwenhuizen
 
 Permission is granted to copy, distribute and/or modify this document
 under the terms of the GNU Free Documentation License, Version 1.3
@@ -1764,10 +1765,18 @@ Open a mail buffer to report a bug for GNU Guix similarly to
 @kbd{M-x@tie{}report-emacs-bug} command.
 
 @findex guix-set-emacs-environment
-@item M-x guix-set-emacs-environment
-Set current Emacs environment according to a specified profile.  Note
-that there is no way to restore the original environment (you have to
-restart Emacs if you wish to do it).
+@item M-x guix-set-emacs-environment-global
+Buffer-locally set Emacs environment according to a specified profile.
+Note that there is no way to restore the original environment for this
+buffer (you have to kill the buffer and re-create it if you wish to do
+it).  If you find yourself using this command often, you may want to
+look at the @file{emacs-envrc} package.
+
+@findex guix-set-emacs-environment-global
+@item M-x guix-set-emacs-environment-global
+Globalally set current Emacs environment according to a specified
+profile.  Note that there is no way to restore the original
+environment (you have to restart Emacs if you wish to do it).
 
 @findex guix-pull
 @item M-x guix-pull
diff --git a/elisp/guix-misc.el b/elisp/guix-misc.el
index f4a7aaa..0cc0dfc 100644
--- a/elisp/guix-misc.el
+++ b/elisp/guix-misc.el
@@ -1,7 +1,7 @@
 ;;; guix-misc.el --- Miscellaneous definitions  -*- lexical-binding: t -*-
 
 ;; Copyright © 2014–2018 Alex Kost <[email-masked]>
-;; Copyright © 2018, 2020, 2023 Janneke Nieuwenhuizen <[email-masked]>
+;; Copyright © 2018, 2020, 2023, 2025 Janneke Nieuwenhuizen <[email-masked]>
 
 ;; This file is part of Emacs-Guix.
 
@@ -223,8 +223,8 @@ FILE.  With a prefix argument, also prompt for PROFILE."
     (guix-display-buffer guix-search-paths-buffer-name)))
 
 ;;;###autoload
-(defun guix-set-emacs-environment (&optional profile)
-  "Set Emacs environment to match PROFILE.
+(defun guix-set-emacs-environment-global (&optional profile)
+  "Set global Emacs environment to match PROFILE.
 PROFILE can be a named profile (like '~/.guix-profile',
 '~/.config/guix/work') or a direct link to profile from the
 store, like GUIX_ENVIRONMENT variable (see Info node `(guix)
@@ -248,6 +248,33 @@ If PROFILE is nil, use `guix-current-profile'."
         (when (equal variable "INFOPATH")
           (setq Info-directory-list (split-string value ":")))))))
 
+;;;###autoload
+(defun guix-set-emacs-environment (&optional profile)
+  "Set Emacs environment to match PROFILE.
+PROFILE can be a named profile (like '~/.guix-profile',
+'~/.config/guix/work') or a direct link to profile from the
+store, like GUIX_ENVIRONMENT variable (see Info node `(guix)
+Invoking guix environment' for details).
+
+If PROFILE is nil, use `guix-current-profile'."
+  (interactive (list (guix-read-profile)))
+  (let ((specs (guix-eval-read
+                (guix-make-guile-expression
+                 'search-paths-specifications
+                 (guix-file-name profile)))))
+    (dolist (spec specs)
+      (-let* (((variable separator path) spec)
+              (current-value (getenv variable))
+              (value (if (and separator current-value)
+                         (concat path separator current-value)
+                       path)))
+        (setq-local process-environment
+                    (cons (concat variable "=" value) process-environment))
+        (when (equal variable "PATH")
+          (setq-local exec-path (split-string value ":")))
+        (when (equal variable "INFOPATH")
+          (setq-local Info-directory-list (split-string value ":")))))))
+
 
 ;;; Executing guix commands
 
-- 
2.46.0