core: async import of env.vars and add new dotfile variable

* new variable dotspacemacs-import-env-vars-from-shell
 * asynchronous import of environments variables
 * move loadenv function to funcs.el
 * update documentation
This commit is contained in:
syl20bnr 2018-06-15 01:38:07 -04:00
parent 5ab0b7918e
commit 9ee832955a
6 changed files with 58 additions and 31 deletions

View File

@ -55,6 +55,13 @@ exists. Otherwise, fallback to ~/.spacemacs"))
`+distributions'. For now available distributions are `spacemacs-base'
or `spacemacs'.")
(defvar dotspacemacs-import-env-vars-from-shell (and (display-graphic-p)
(or (eq system-type 'darwin)
(eq window-system 'x)))
"If non-nil then Spacemacs will import your PATH and environment variables
from your default shell on startup. This is enabled by default for macOS users
and X11 users.")
(defvar dotspacemacs-enable-emacs-pdumper nil
"If non-nil then enable support for the portable dumper. You'll need
to compile Emacs 27 from source following the instructions in file

View File

@ -155,6 +155,13 @@ It should only modify the values of Spacemacs settings."
;; If non-nil output loading progress in `*Messages*' buffer. (default nil)
dotspacemacs-verbose-loading nil
;; If non-nil then Spacemacs will import your PATH and environment variables
;; from your default shell on startup. This is enabled by default for macOS
;; users and X11 users.
dotspacemacs-import-env-vars-from-shell (and (display-graphic-p)
(or (eq system-type 'darwin)
(eq window-system 'x)))
;; Specify the startup banner. Default value is `official', it displays
;; the official spacemacs logo. An integer value is the index of text
;; banner, `random' chooses a random text banner in `core/banners'

View File

@ -1718,22 +1718,28 @@ There are also some handy globally available key bindings related to workspaces:
| ~SPC b W~ | go to workspace and window by buffer |
* Environment variables and PATH from the shell
When using the Emacs GUI environment variables defined by your shell may not
be available to the Emacs process. This is especially true for macOS.
To import your environment variable and =PATH= at startup set the variable
=dotspacemacs-import-env-vars-from-shell= to non-nil.
The command to fetch the environment variables from your shell is very expensive
and increases the startup time quite a lot.
This should be necessary only to macOS users and X11 users using the GNU
build of Emacs.
For this reason, Spacemacs caches the PATH value and some environment variables
in the file located at =~/.emacs.d/.cache/.env-vars=.
#+BEGIN_EXAMPLE emacs-lisp
(setq-default dotspacemacs-import-env-vars-from-shell (and (display-graphic-p)
(or (eq system-type 'darwin)
(eq window-system 'x))))
#+END_EXAMPLE
Any environment variables that are not found are still written to the cache file
with the value =<VAR>-NOTFOUND-PLEASE-DEFINE-IN-YOUR-SHELL=.
At anytime you can import the environment variables by calling the function
=spacemacs/loadenv=.
Spacemacs won't update the cached values by itself, if you want to update your
shell variables then either delete the cache file or execute the interactive
function =spacemacs/import-path= and restart Emacs to fetch any updated
environment variables.
You can define a different shell than the default shell by setting the variable
=shell-file-name= in the =dotspacemacs/user-init= function of your dotfile.
#+BEGIN_EXAMPLE emacs-lisp
(defun dotspacemacs/user-init ()
(setq shell-file-name "/usr/local/bin/fish"))
#+END_EXAMPLE
* Commands
** Vim key bindings

View File

@ -11,6 +11,29 @@
(defun spacemacs/loadenv ()
"Gets and sets all the environment variables from user shell."
(interactive)
(spacemacs-buffer/message "Importing environment variables..")
(require 'async nil t)
(async-start
`(lambda ()
,(async-inject-variables "\\`shell-file-name\\'")
(split-string (shell-command-to-string "env") "\n"))
(lambda (envvars)
(spacemacs-buffer/message "Imported environment variables:")
(dolist (env envvars)
(if (string-match "^[a-zA-Z_]+[a-zA-Z0-9_]*=" env)
(let* ((var (split-string env "="))
(k (car var))
(v (cadr var)))
(spacemacs-buffer/message " - %s=%s" k v)
(if (string-equal "PATH" k)
(setq exec-path (split-string v path-separator))
(setenv k v))))))))
(defun spacemacs/state-color-face (state)
"Return the symbol of the face for the given STATE."
(intern (format "spacemacs-%s-face" (symbol-name state))))

View File

@ -1,12 +0,0 @@
(defun spacemacs//loadenv ()
"Gets and sets all the environment variables from a terminal instance."
(interactive)
(let ((envvars (split-string (shell-command-to-string "env") "\n")))
(dolist (env envvars)
(if (string-match "^[a-zA-Z_]+[a-zA-Z0-9_]*=" env)
(let* ((var (split-string env "="))
(k (car var))
(v (cadr var)))
(setenv k v))))))
(provide 'spacemacs-environment)

View File

@ -18,11 +18,7 @@
(bind-key :step bootstrap)
(diminish :step bootstrap)
(evil :step bootstrap)
(spacemacs-environment :step bootstrap
:location local
:toggle (or (spacemacs/system-is-mac)
(spacemacs/system-is-linux)
(eq window-system 'x)))
(spacemacs-environment :step bootstrap :location built-in)
(hydra :step bootstrap)
(use-package :step bootstrap)
(which-key :step bootstrap)
@ -498,8 +494,8 @@
(spacemacs|diminish which-key-mode "" " K"))
(defun spacemacs-bootstrap/init-spacemacs-environment ()
(require 'spacemacs-environment)
(spacemacs//loadenv))
(when dotspacemacs-import-env-vars-from-shell
(spacemacs/loadenv)))
;; pre packages