Skip to content

Commit

Permalink
feat(core): better management of environment variables
Browse files Browse the repository at this point in the history
  • Loading branch information
abougouffa committed Jul 15, 2023
1 parent 8dfb0d9 commit 87e498e
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 57 deletions.
18 changes: 3 additions & 15 deletions core/me-loaddefs.el
Original file line number Diff line number Diff line change
Expand Up @@ -463,11 +463,9 @@ Queue FNS to be byte/natively-compiled after a brief delay.
(fn &rest FNS)")
(autoload '+env-save "../elisp/+minemacs" "\
Load environment variables of the current session to the file
\".emacs.d/local/system-env.el\"." t)
Load environment variables from shell and save them to `+env-file'." t)
(autoload '+env-load "../elisp/+minemacs" "\
Load environment variables from the file saved in
\".emacs.d/local/system-env.el\" if available." t)
Load environment variables from `+env-file'." t)
(autoload '+ignore-root "../elisp/+minemacs" "\
Add ROOTS to ignored projects, recentf, etc.
Expand Down Expand Up @@ -716,11 +714,6 @@ This depends on `+cape-hosts' and `+cape-global-capes'.
(fn &optional DISABLE)" t)


;;; Generated autoloads from me-core-ui.el

(register-definition-prefixes "me-core-ui" '("+theme--tweaks-h"))


;;; Generated autoloads from ../modules/extras/me-dap-utils.el

Expand All @@ -731,11 +724,6 @@ Fallback to FALLBACK-RELEASE when it can't get the last one.
(fn USER REPO &optional FALLBACK-RELEASE)")


;;; Generated autoloads from me-defaults.el

(register-definition-prefixes "me-defaults" '("+whitespace-auto-cleanup-modes"))


;;; Generated autoloads from ../modules/extras/me-eglot-ltex.el

Expand Down Expand Up @@ -815,7 +803,7 @@ Register dictionaries for `LANGS` to spell-fu's multi-dict.

;;; Generated autoloads from me-vars.el

(register-definition-prefixes "me-vars" '("+env-save-vars" "emacs/features" "minemacs-" "os/" "sys/arch"))
(register-definition-prefixes "me-vars" '("+env-" "emacs/features" "minemacs-" "os/" "sys/arch"))


;;; Generated autoloads from ../modules/extras/me-writing-mode.el
Expand Down
32 changes: 27 additions & 5 deletions core/me-vars.el
Original file line number Diff line number Diff line change
Expand Up @@ -218,11 +218,33 @@ MinEmacs hooks will be run in this order:
:variable-pitch-font-size 13)
"Default fonts of MinEmacs."))

(defcustom +env-save-vars
'("PATH" "MANPATH" "CMAKE_PREFIX_PATH" "PKG_CONFIG_PATH" "LSP_USE_PLISTS")
"List of the environment variables to saved by `+env-save'.
You need to run Emacs from terminal to get the environment variables.
MinEmacs then save them when calling `+env-save' to be used in GUI sessions as well."
(defcustom +env-file (concat minemacs-local-dir "system-env.el")
"The file in which the environment variables will be saved."
:group 'minemacs-core
:type 'file)

;; List from Doom Emacs
(defcustom +env-deny-vars
'(;; Unix/shell state that shouldn't be persisted
"^HOME$" "^\\(OLD\\)?PWD$" "^SHLVL$" "^PS1$" "^R?PROMPT$" "^TERM\\(CAP\\)?$"
"^USER$" "^GIT_CONFIG" "^INSIDE_EMACS$"
;; X server, Wayland, or services' env that shouldn't be persisted
"^DISPLAY$" "^WAYLAND_DISPLAY" "^DBUS_SESSION_BUS_ADDRESS$" "^XAUTHORITY$"
;; Windows+WSL envvars that shouldn't be persisted
"^WSL_INTEROP$"
;; XDG variables that are best not persisted.
"^XDG_CURRENT_DESKTOP$" "^XDG_RUNTIME_DIR$"
"^XDG_\\(VTNR\\|SEAT\\|SESSION_\\(TYPE\\|CLASS\\)\\)"
;; Socket envvars, like I3SOCK, GREETD_SOCK, SEATD_SOCK, SWAYSOCK, etc.
"SOCK$"
;; ssh and gpg variables that could quickly become stale if persisted.
"^SSH_\\(AUTH_SOCK\\|AGENT_PID\\)$" "^\\(SSH\\|GPG\\)_TTY$"
"^GPG_AGENT_INFO$"
;; Internal Doom envvars
"^DEBUG$" "^INSECURE$" "^\\(EMACS\\|DOOM\\)DIR$" "^DOOMPROFILE$" "^__")
"Environment variables to omit.
Each string is a regexp, matched against variable names to omit from
`+env-file' when saving evnironment variables in `+env-save'."
:group 'minemacs-core
:type '(repeat string))

Expand Down
44 changes: 18 additions & 26 deletions elisp/+minemacs.el
Original file line number Diff line number Diff line change
Expand Up @@ -397,40 +397,32 @@ If N and M = 1, there's no benefit to using this macro over `remove-hook'.

;;;###autoload
(defun +env-save ()
"Load environment variables of the current session to the file
\".emacs.d/local/system-env.el\"."
"Load environment variables from shell and save them to `+env-file'."
(interactive)
(with-temp-buffer
(insert ";; -*- mode: emacs-lisp; no-byte-compile: t; no-native-compile: t; -*-\n\n")
(dolist (env-var +env-save-vars)
(when-let ((var-val (getenv env-var)))
(when (equal "PATH" env-var)
(insert
(format
"\n;; Helper function\n%s\n"
'(defun +add-to-path (path)
(unless (member path exec-path)
(add-to-list 'exec-path path)))))
(insert "\n;; Adding PATH content to `exec-path'\n")
(dolist (path (parse-colon-path var-val))
(when path
(insert
(format
"(+add-to-path \"%s\")\n"
path path))))
(insert "\n"))
(let ((env-vars
(mapcar ; Get environment variables from shell into an alist
(lambda (l) (let ((s (string-split l "="))) (cons (car s) (string-join (cdr s) "="))))
(string-lines (shell-command-to-string "env") "="))))
;; Special treatment for the "PATH" variable, save it to `exec-path'
(when-let ((path (alist-get "PATH" env-vars nil nil #'string=)))
(insert
(format "(setenv \"%s\" \"%s\")\n" env-var var-val))))
(write-file (concat minemacs-local-dir "system-env.el"))))
(format "\n;; Adding PATH content to `exec-path'\n(setq exec-path (delete-dups (append exec-path '%s)))\n\n"
(mapcar (lambda (s) (concat "\"" s "\"")) (parse-colon-path path)))))
;; Save the environment variables to `process-environment' using `setenv'
(insert ";; Adding the rest of the environment variables\n")
(dolist (env-var env-vars)
(unless (cl-some (+apply-partially-right #'string-match-p (car env-var)) +env-deny-vars)
(insert (format "(setenv \"%s\" \"%s\")\n" (car env-var) (cdr env-var))))))
(write-file +env-file)))

;;;###autoload
(defun +env-load ()
"Load environment variables from the file saved in
\".emacs.d/local/system-env.el\" if available."
"Load environment variables from `+env-file'."
(interactive)
(let ((env-file (concat minemacs-local-dir "system-env.el")))
(when (file-exists-p env-file)
(+load env-file))))
(unless (file-exists-p +env-file) (+env-save))
(+load +env-file))

;;;###autoload
(defun +ignore-root (&rest roots)
Expand Down
14 changes: 3 additions & 11 deletions init.el
Original file line number Diff line number Diff line change
Expand Up @@ -128,17 +128,9 @@
(when (file-exists-p user-init-tweaks)
(+load user-init-tweaks))))

;; HACK: When Emacs is launched from the terminal (in GNU/Linux), it inherits
;; the terminal's environment variables, which can be useful specially for
;; running commands under a custom "$PATH" directory. But when Emacs is launched
;; from the desktop manager (KDE, Gnome, etc.), it can omit the terminal's
;; environment variables. The way I solve this is by launching Emacs from
;; terminal, which gives Emacs the full environment variables of the invoking
;; terminal. Then I call the `+env-save' command, which reads the environment
;; variables defined in `+env-save-vars' and stores them in
;; "~/.emacs.d/local/system-env.el". This file is then loaded in the future
;; Emacs sessions (launched either from terminal or from GUI) by calling the
;; `+env-load' command.
;; HACK: Load the environment variables saved from shell using `+env-save' to
;; `+env-file'. `+env-save' saves all environment variables except these matched
;; by `+env-deny-vars'.
(+env-load) ; Load environment variables when available.

;; NOTE: This is MinEmacs' synchronization point. To get a fast Emacs startup,
Expand Down

0 comments on commit 87e498e

Please sign in to comment.