💥 Replace exec-path-from-shell w/ 'bin/doom env'

IMPORTANT: This is a breaking update for Mac users, as your shell
environment will no longer be inherited correctly (with the removal of
exec-path-from-shell). The quick fix is: 'bin/doom env refresh'. Also,
the set-env! autodef now does nothing (and is deprecated), be sure to
remove calls to it in your config.

Smaller changes:
+ This update also adds --no-* switches to doom quickstart
+ Includes general improvements to the documentation of several bin/doom
  commands.
+ Moves doom/reload* commands to core/autoload/config.el
+ doom/reload-project has been removed (it didn't actually do anything)

The breaking change:
This update adds an "envvar file" to Doom Emacs. This file is generated
by `doom env refresh`, populated with variables scraped from your shell
environment (from both non-interactive and interactive sessions). This
file is then (inexpensively) loaded at startup, if it exists.

+ The file is manually generated with `doom env refresh`.
+ It can be regenerated automatically whenever `doom refresh` is run by
  running `doom env enable` (`doom env clear` will reverse this and
  delete the env file).
+ `doom quickstart` will ask if you want to auto-generate this envvar
  file. You won't need it if you're confident Emacs will always be
  started from the correct environment, however.
+ Your env file can be reloaded from a running Emacs session with `M-x
  doom/reload-env`. Note: this won't work if the Emacs session you're
  running it in doesn't have a correct SHELL set. i.e. don't use this to
  create your first env file!

The idea isn't mine -- it's borrowed from Spacemacs -- and was
introduced to me in #1053 by @yurimx. I was impressed with it. Prior to
this, I was unhappy with exec-path-from-shell (no hate to the dev, I
understand its necessity), and 'doom patch-macos' wasn't ideal for mac
users (needed to be reapplied every time you update Emacs). What's more,
many users (even Linux users) had to install exec-path-from-shell
anyway.

This solution suffers from none of their shortcomings. More reliable
than patch-macos, more performant and complete than
exec-path-from-shell, and easily handled by bin/doom.
This commit is contained in:
Henrik Lissner 2019-03-28 00:06:10 -04:00
parent ab616cfb95
commit 2dc52bc9be
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
19 changed files with 266 additions and 136 deletions

View file

@ -1,5 +1,9 @@
;;; core/autoload/config.el -*- lexical-binding: t; -*-
;;;###autoload
(defvar doom-reloading-p nil
"TODO")
;;;###autoload
(defun doom/open-private-config ()
"TODO"
@ -14,25 +18,70 @@
(interactive)
(doom-project-find-file doom-private-dir))
;;;###autoload
(defun doom/open-env ()
"TODO"
(interactive)
(when (and (not (file-exists-p doom-env-file))
(y-or-n-p "User doesn't have an envvar file, generate one?"))
(doom/reload-env))
(find-file doom-env-file))
;;;###autoload
(defun doom/reload (&optional force-p)
"Reloads your config. This is experimental!
"Reloads your private config.
If called from a noninteractive session, this will try to communicate with a
live server (if one is found) to tell it to run this function.
This is experimental! It will try to do as `bin/doom refresh' does, but from
within this Emacs session. i.e. it reload autoloads files (if necessary),
reloads your package list, and lastly, reloads your private config.el.
If called from an interactive session, tries to reload autoloads files (if
necessary), reinistalize doom (via `doom-initialize') and reloads your private
init.el and config.el. Then runs `doom-reload-hook'."
Runs `doom-reload-hook' afterwards."
(interactive "P")
(require 'core-cli)
(doom-reload-autoloads force-p)
(setq load-path doom-site-load-path)
(let (doom-init-p)
(doom-initialize))
(with-demoted-errors "PRIVATE CONFIG ERROR: %s"
(doom-initialize-modules 'force))
(when (bound-and-true-p doom-packages)
(doom/reload-packages))
(run-hook-wrapped 'doom-reload-hook #'doom-try-run-hook)
(let ((doom-reloading-p t))
(when (getenv "DOOMENV")
(doom-reload-env-file 'force))
(doom-reload-autoloads force-p)
(setq load-path doom-site-load-path)
(let (doom-init-p)
(doom-initialize))
(with-demoted-errors "PRIVATE CONFIG ERROR: %s"
(doom-initialize-modules 'force))
(when (bound-and-true-p doom-packages)
(doom/reload-packages))
(run-hook-wrapped 'doom-reload-hook #'doom-try-run-hook))
(message "Finished!"))
;;;###autoload
(defun doom/reload-env ()
"Regenerates and reloads your shell environment.
Uses the same mechanism as 'bin/doom env reload'."
(interactive)
(compile (format "%s env refresh" (expand-file-name "bin/doom" doom-emacs-dir)))
(while compilation-in-progress
(sit-for 1))
(unless (file-readable-p doom-env-file)
(error "Failed to generate env file"))
(load-env-vars doom-env-file))
;;;###autoload
(defun doom/reload-font ()
"Reload `doom-font', `doom-variable-pitch-font', and `doom-unicode-font', if
set."
(interactive)
(when doom-font
(set-frame-font doom-font t))
(doom|init-fonts))
;;;###autoload
(defun doom/reload-theme ()
"Reset the current color theme and fonts."
(interactive)
(let ((theme (or (car-safe custom-enabled-themes) doom-theme)))
(when theme
(mapc #'disable-theme custom-enabled-themes))
(when (and doom-theme (not (memq doom-theme custom-enabled-themes)))
(let (doom--prefer-theme-elc)
(load-theme doom-theme t)))
(doom|init-fonts)))

View file

@ -21,6 +21,7 @@ ready to be pasted in a bug report on github."
"- System features: %s\n"
"- Details:\n"
" ```elisp\n"
" env bootstrapper: %s\n"
" elc count: %s\n"
" uname -a: %s\n"
" modules: %s\n"
@ -36,6 +37,8 @@ ready to be pasted in a bug report on github."
"n/a")
(display-graphic-p) (daemonp)
(bound-and-true-p system-configuration-features)
(cond ((file-exists-p doom-env-file) 'envvar-file)
((featurep 'exec-path-from-shell) 'exec-path-from-shell))
;; details
(length (doom-files-in `(,@doom-modules-dirs
,doom-core-dir

View file

@ -28,15 +28,6 @@ they are absolute."
;;
;; Commands
;;;###autoload
(defun doom/reload-project ()
"Reload the project root cache."
(interactive)
(projectile-invalidate-cache nil)
(setq-default projectile-project-root nil)
(dolist (fn projectile-project-root-files-functions)
(remhash (format "%s-%s" fn default-directory) projectile-project-root-cache)))
;;;###autoload
(defun doom/find-file-in-other-project (project-root)
"Preforms `projectile-find-file' in a known project of your choosing."

View file

@ -81,18 +81,6 @@ See `display-line-numbers' for what these values mean."
(`nil "disabled")
(_ (symbol-name next))))))
;;;###autoload
(defun doom/reload-theme ()
"Reset the current color theme and fonts."
(interactive)
(let ((theme (or (car-safe custom-enabled-themes) doom-theme)))
(when theme
(mapc #'disable-theme custom-enabled-themes))
(when (and doom-theme (not (memq doom-theme custom-enabled-themes)))
(let (doom--prefer-theme-elc)
(load-theme doom-theme t)))
(doom|init-fonts)))
;;;###autoload
(defun doom/delete-frame ()
"Delete the current frame, but ask for confirmation if it isn't empty."
@ -161,15 +149,6 @@ windows (unlike `doom/window-maximize-buffer') Activate again to undo."
(while (ignore-errors (windmove-up)) (delete-window))
(while (ignore-errors (windmove-down)) (delete-window))))
;;;###autoload
(defun doom/reload-font ()
"Reload `doom-font', `doom-variable-pitch-font', and `doom-unicode-font', if
set."
(interactive)
(when doom-font
(set-frame-font doom-font t))
(doom|init-fonts))
;;;###autoload
(defun doom/set-frame-opacity (opacity)
"Interactively change the current frame's opacity.

95
core/cli/env.el Normal file
View file

@ -0,0 +1,95 @@
;;; core/cli/env.el -*- lexical-binding: t; -*-
(dispatcher! env
(let ((env-file (abbreviate-file-name doom-env-file)))
(pcase (car args)
("refresh"
(doom-reload-env-file 'force))
("enable"
(setenv "DOOMENV" "1")
(print! (green "Enabling auto-reload of %S" env-file))
(doom-reload-env-file 'force)
(print! (green "Done! `doom reload' will now refresh your envvar file.")))
("clear"
(setenv "DOOMENV" nil)
(unless (file-exists-p env-file)
(user-error "%S does not exist to be cleared" env-file))
(delete-file env-file)
(print! (green "Disabled envvar file by deleting %S" env-file)))
(_
(message "No valid subcommand provided. See `doom help env`."))))
"Manages your envvars file.
env [SUBCOMMAND]
Available subcommands:
refresh Create or regenerate your envvar file
enable enable auto-reloading of your envvars file (on `doom refresh`)
clear deletes your envvar file (if it exists) and disables auto-reloading
An envvars file (its location is controlled by the `doom-env-file' variable)
will contain a list of environment variables scraped from your shell environment
and loaded when Doom starts (if it exists). This is necessary when Emacs can't
be launched from your shell environment (e.g. on MacOS or certain app launchers
on Linux).
To generate a file, run `doom env refresh`. If you'd like this file to be
auto-reloaded when running `doom refresh`, run `doom env enable` instead (only
needs to be run once).")
;;
;; Helpers
(defvar doom-ignored-env-vars
'("DBUS_SESSION_BUS_ADDRESS"
"GPG_AGENT_INFO"
"SSH_AGENT_PID"
"SSH_AUTH_SOCK")
"Environment variables to not save in `doom-env-file'.")
;; Borrows heavily from Spacemacs'`spacemacs//init-spacemacs-env'.
(defun doom-reload-env-file (&optional force-p)
"Generates `doom-env-file', if it doesn't exist (or FORCE-P is non-nil)."
(when (or force-p (not (file-exists-p doom-env-file)))
(with-temp-file doom-env-file
(message "%s envvars file at %S"
(if (file-exists-p doom-env-file)
"Regenerating"
"Generating")
(abbreviate-file-name doom-env-file))
(insert
(concat
"# -*- mode: dotenv -*-\n"
"# ---------------------------------------------------------------------------\n"
"# This file was auto-generated by Doom. It contains all environment variables\n"
"# scraped from your default shell (excluding variables blacklisted in\n"
"# doom-ignored-env-vars).\n"
"#\n"
"# It is NOT safe to edit this file. Changes will be overwritten next time\n"
"# that `doom env reload` is executed. Alternatively, create your own env file\n"
"# in your DOOMDIR and load that with `(load-env-vars FILE)`.\n"
"#\n"
"# To auto-regenerate this file when `doom reload` is run, use `doom env enable'\n"
"# or set DOOMENV=1 in your shell environment/config.\n"
"# ---------------------------------------------------------------------------\n\n"))
(let ((env-point (point))
(switches
(cond (IS-WINDOWS '("-c"))
;; Execute twice, once in a non-interactive login shell and
;; once in an interactive shell in order to capture all the
;; init files possible.
((or IS-MAC IS-LINUX) '("-lc" "-ic"))))
(executable (if IS-WINDOWS
"set"
(executable-find "env"))))
(dolist (shell-command-switch switches)
(insert (shell-command-to-string executable)))
;; sort the environment variables
(sort-lines nil env-point (point-max))
;; remove adjacent duplicated lines
(delete-duplicate-lines env-point (point-max) nil t)
;; remove ignored environment variables
(dolist (var doom-ignored-env-vars)
(flush-lines (concat "^" var "=") env-point (point-max)))))))

View file

@ -1,68 +1,87 @@
;;; core/cli/quickstart.el -*- lexical-binding: t; -*-
(dispatcher! (quickstart qs) (doom-quickstart)
(dispatcher! (quickstart qs) (apply #'doom-quickstart args)
"Quickly deploy a private module and Doom.
This deploys a barebones config to ~/.doom.d. The destination can be changed
with the -p option, e.g.
This deploys a barebones config to ~/.doom.d (if it doesn't already exist). The
destination can be changed with the -p option, e.g.
doom -p ~/.config/doom quickstart
This command will refuse to overwrite the private directory if it already
exists.")
Quickstart understands the following switches:
--no-config Don't deploy dummy config to ~/.doom.d
--no-install Don't auto-install packages
--no-env Don't generate an envvars file (see `doom help env`)
--no-fonts Don't install (or prompt to install) all-the-icons fonts
This command is idempotent and is safe to reuse.")
;;
;; Library
(defun doom-quickstart ()
(defun doom-quickstart (&rest args)
"Quickly deploy a private module and Doom.
This deploys a barebones config to `doom-private-dir', installs all missing
packages and regenerates the autoloads file."
;; Create `doom-private-dir'
(let ((short-private-dir (abbreviate-file-name doom-private-dir)))
(if (file-directory-p doom-private-dir)
(print! (yellow "%s directory already exists. Skipping.") short-private-dir)
(print! "Creating %s" short-private-dir)
(make-directory doom-private-dir t)
(print! (green "Done!"))
;; Create init.el, config.el & packages.el
(dolist (file (list (cons "init.el"
(lambda ()
(insert-file-contents (expand-file-name "init.example.el" doom-emacs-dir))))
(cons "config.el"
(lambda ()
(insert (format ";;; %sconfig.el -*- lexical-binding: t; -*-\n\n"
short-private-dir)
";; Place your private configuration here\n")))
(cons "packages.el"
(lambda ()
(insert (format ";; -*- no-byte-compile: t; -*-\n;;; %spackages.el\n\n"
short-private-dir)
";;; Examples:\n"
";; (package! some-package)\n"
";; (package! another-package :recipe (:fetcher github :repo \"username/repo\"))\n"
";; (package! builtin-package :disable t)\n")))))
(cl-destructuring-bind (path . fn) file
(print! "Creating %s%s" short-private-dir path)
(with-temp-file (expand-file-name path doom-private-dir)
(funcall fn))
(print! (green "Done!"))))))
(if (member "--no-config" args)
(print! (yellow "Not copying private config template, as requested"))
(if (file-directory-p doom-private-dir)
(print! (yellow "%s directory already exists. Skipping.") short-private-dir)
(print! "Creating %s" short-private-dir)
(make-directory doom-private-dir t)
(print! (green "Done!"))
;; Create init.el, config.el & packages.el
(dolist (file (list (cons "init.el"
(lambda ()
(insert-file-contents (expand-file-name "init.example.el" doom-emacs-dir))))
(cons "config.el"
(lambda ()
(insert (format ";;; %sconfig.el -*- lexical-binding: t; -*-\n\n"
short-private-dir)
";; Place your private configuration here\n")))
(cons "packages.el"
(lambda ()
(insert (format ";; -*- no-byte-compile: t; -*-\n;;; %spackages.el\n\n"
short-private-dir)
";;; Examples:\n"
";; (package! some-package)\n"
";; (package! another-package :recipe (:fetcher github :repo \"username/repo\"))\n"
";; (package! builtin-package :disable t)\n")))))
(cl-destructuring-bind (path . fn) file
(print! "Creating %s%s" short-private-dir path)
(with-temp-file (expand-file-name path doom-private-dir)
(funcall fn))
(print! (green "Done!")))))))
;; Ask if Emacs.app should be patched
(when IS-MAC
(message "MacOS detected")
(condition-case e
(doom-patch-macos nil (doom--find-emacsapp-path))
(user-error (message "%s" (error-message-string e)))))
(if (member "--no-env" args)
(print! (yellow "Not generating envvars file, as requested"))
(when (or (file-exists-p doom-env-file)
(y-or-n-p "Would you like to generate an envvars file (see `doom help env` for details)?"))
(setenv "DOOMENV" "1")
(doom-reload-env-file 'force-p)))
;; Install Doom packages
(print! "Installing plugins")
(doom-packages-install doom-auto-accept)
(if (member "--no-install" args)
(print! (yellow "Not installing plugins, as requested"))
(print! "Installing plugins")
(doom-packages-install doom-auto-accept))
(print! "Regenerating autoloads files")
(doom-reload-autoloads nil 'force-p)
(when (y-or-n-p "Download and install all-the-icon's fonts?")
(require 'all-the-icons)
(all-the-icons-install-fonts 'yes))
(if (member "--no-fonts" args)
(print! (yellow "Not installing fonts, as requested"))
(when (y-or-n-p "Download and install all-the-icon's fonts?")
(require 'all-the-icons)
(all-the-icons-install-fonts 'yes)))
(print! (bold (green "\nFinished! Doom is ready to go!\n")))
(with-temp-buffer
(doom-template-insert "QUICKSTART_INTRO")

View file

@ -107,7 +107,8 @@ best to run Doom out of ~/.emacs.d and ~/.doom.d.")
(dispatcher! (doctor doc) :noop
"Checks for issues with your environment & Doom config.
Also checks for missing dependencies for any enabled modules.")
Use the doctor to diagnose common problems or list missing dependencies in
enabled modules.")
(dispatcher! (help h) :noop
"Look up additional information about a command.")
@ -119,6 +120,7 @@ Also checks for missing dependencies for any enabled modules.")
(load! "cli/autoloads")
(load! "cli/byte-compile")
(load! "cli/debug")
(load! "cli/env")
(load! "cli/packages")
(load! "cli/patch-macos")
(load! "cli/quickstart")
@ -131,6 +133,8 @@ Also checks for missing dependencies for any enabled modules.")
"Ensure Doom is in a working state by checking autoloads and packages, and
recompiling any changed compiled files. This is the shotgun solution to most
problems with doom."
(when (getenv "DOOMENV")
(doom-reload-env-file 'force))
(doom-reload-doom-autoloads force-p)
(unwind-protect
(progn
@ -142,7 +146,7 @@ problems with doom."
(doom-byte-compile nil 'recompile)))
(dispatcher! (refresh re) (doom-refresh 'force)
"Refresh Doom. Same as autoremove+install+autoloads.
"Refresh Doom.
This is the equivalent of running autoremove, install, autoloads, then
recompile. Run this whenever you:
@ -150,7 +154,11 @@ recompile. Run this whenever you:
1. Modify your `doom!' block,
2. Add or remove `package!' blocks to your config,
3. Add or remove autoloaded functions in module autoloaded files.
4. Update Doom outside of Doom (e.g. with git)")
4. Update Doom outside of Doom (e.g. with git)
It will ensure that unneeded packages are removed, all needed packages are
installed, autoloads files are up-to-date and no byte-compiled files have gone
stale.")
(provide 'core-cli)
;;; core-cli.el ends here

View file

@ -1,5 +1,8 @@
;;; core-os.el -*- lexical-binding: t; -*-
;; TODO Remove me later (deprecated)
(defmacro set-env! (&rest _))
;; clipboard
(setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING))
@ -19,35 +22,6 @@
;; grokked from: http://stackoverflow.com/questions/15873346/elisp-rename-macro
(advice-add #'evil-visual-update-x-selection :override #'ignore)
;; In case it is never defined:
(defmacro set-env! (&rest _vars)
"Inject VARS from your shell environment into Emacs.")
(when (or (daemonp) (display-graphic-p))
;; Syncs ns frame parameters with theme (and fixes mismatching text
;; colr in the frame title)
(when (and IS-MAC (require 'ns-auto-titlebar nil t))
(add-hook 'doom-load-theme-hook #'ns-auto-titlebar-mode))
;; If you launch GUI Emacs from the wrong shell environment, Emacs will be
;; gimped. This regularly happens on MacOS (or daemons started via launchctl
;; or brew services): it runs in an isolated environment, so envvars will be
;; wrong. That includes the PATH Emacs picks up.
;;
;; `exec-path-from-shell' tries to address this, but it is only set up to run
;; for mac users.
(when (require 'exec-path-from-shell nil t)
(defun set-env! (&rest vars)
"Inject VARS from your shell environment into Emacs."
(exec-path-from-shell-copy-envs vars))
(setq exec-path-from-shell-check-startup-files nil
exec-path-from-shell-arguments (delete "-i" exec-path-from-shell-arguments)
exec-path-from-shell-debug doom-debug-mode
exec-path-from-shell-variables
(nconc exec-path-from-shell-variables '("LC_CTYPE" "LC_ALL" "LANG")))
(exec-path-from-shell-initialize)))
(cond (IS-MAC
(setq mac-command-modifier 'super
mac-option-modifier 'meta
@ -61,7 +35,14 @@
ns-use-native-fullscreen nil
;; Visit files opened outside of Emacs in existing frame, rather
;; than a new one
ns-pop-up-frames nil))
ns-pop-up-frames nil)
;; Syncs ns frame parameters with theme (and fixes mismatching text color
;; in the frame title)
(when (and (or (daemonp)
(display-graphic-p))
(require 'ns-auto-titlebar nil t))
(add-hook 'doom-load-theme-hook #'ns-auto-titlebar-mode)))
(IS-LINUX
(setq x-gtk-use-system-tooltips nil ; native tooltips are ugly!

View file

@ -76,6 +76,14 @@ XDG directory conventions if ~/.config/doom exists.")
"Where `doom-reload-package-autoloads' will generate its package.el autoloads
file.")
(defvar doom-env-file (concat doom-local-dir "env")
"The location of your env file, generated by `doom env refresh`.
This file contains environment variables scraped from your non and interactive
shell environment, and is loaded at startup (if it exist)s. This is helpful if
Emacs can't (easily) be launched from the correct shell session (particular for
MacOS users).")
;;
;; Doom core variables
@ -443,6 +451,10 @@ to least)."
noninteractive)
(user-error "Your package autoloads are missing! Run `bin/doom refresh' to regenerate them"))))
;; Load shell environment
(when (file-readable-p doom-env-file)
(load-env-vars doom-env-file))
(require 'core-lib)
(require 'core-modules)
(require 'core-os)

View file

@ -1,10 +1,13 @@
;; -*- no-byte-compile: t; -*-
;;; core/packages.el
;; core.el
(package! load-env-vars)
(package! dotenv-mode)
;; core-os.el
(package! xclip)
(when IS-MAC
(package! exec-path-from-shell)
(if (not IS-MAC)
(package! xclip)
(package! osx-clipboard)
(package! ns-auto-titlebar))

View file

@ -110,7 +110,7 @@
"t" #'doom/reload-theme
"p" #'doom/reload-packages
"f" #'doom/reload-font
"P" #'doom/reload-project)
"e" #'doom/reload-env)
"T" #'doom/toggle-profiler
"V" #'set-variable
"C-v" #'doom/version

View file

@ -21,9 +21,7 @@
(when IS-BSD
;; Use GNU ls as `gls' from `coreutils' if available. Add `(setq
;; dired-use-ls-dired nil)' to your config to suppress the Dired warning
;; when not using GNU ls. We must look for `gls' after
;; `exec-path-from-shell' was initialized to make sure that `gls' is in
;; `exec-path'
;; when not using GNU ls.
(if-let* ((gls (executable-find "gls")))
(setq insert-directory-program gls)
(setq args (delete "--group-directories-first" args))

View file

@ -6,7 +6,5 @@
;; `term' (built-in)
(after! term
(set-env! "SHELL")
(add-hook 'term-mode-hook #'doom|mark-buffer-as-real)
(add-to-list 'doom-detect-indentation-excluded-modes 'term-mode nil #'eq))

View file

@ -4,7 +4,6 @@
;; Packages
(after! go-mode
(set-env! "GOPATH" "GOROOT")
(set-docsets! 'go-mode "Go")
(set-repl-handler! 'go-mode #'gorepl-run)
(set-lookup-handlers! 'go-mode

View file

@ -18,7 +18,6 @@ called.")
(setq python-environment-directory doom-cache-dir
python-indent-guess-indent-offset-verbose nil)
:config
(set-env! "PYTHONPATH" "PYENV_ROOT" "ANACONDA_HOME")
(set-electric! 'python-mode :chars '(?:))
(set-repl-handler! 'python-mode #'+python/open-repl)

View file

@ -15,7 +15,6 @@
(enh-ruby-mode)
(ruby-mode)))
:config
(set-env! "RBENV_ROOT")
(set-electric! '(ruby-mode enh-ruby-mode) :words '("else" "end" "elsif"))
(set-repl-handler! '(ruby-mode enh-ruby-mode) #'inf-ruby)

View file

@ -1,7 +1,6 @@
;;; lang/rust/config.el -*- lexical-binding: t; -*-
(after! rust-mode
(set-env! "RUST_SRC_PATH")
(set-docsets! 'rust-mode "Rust")
(setq rust-indent-method-chain t)

View file

@ -25,7 +25,6 @@
;; `pass'
(after! pass
(set-env! "PASSWORD_STORE_DIR")
(set-evil-initial-state! 'pass-mode 'emacs)
(set-popup-rule! "^\\*Password-Store" :side 'left :size 0.25 :quit nil)
(define-key! pass-mode-map

View file

@ -5,7 +5,6 @@
:defer t
:preface (setq vterm-install t)
:config
(set-env! "SHELL")
(set-popup-rule! "^vterm" :size 0.25 :vslot -4 :select t :quit nil :ttl 0)
(add-hook 'vterm-mode-hook #'doom|mark-buffer-as-real)