[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/exec-path-from-shell ad68d36747 102/114: Instead of checki
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/exec-path-from-shell ad68d36747 102/114: Instead of checking startup files, just warn if execution is slow |
Date: |
Tue, 5 Sep 2023 04:00:07 -0400 (EDT) |
branch: elpa/exec-path-from-shell
commit ad68d367475e698cee043df3af160d85d5fa29e4
Author: Steve Purcell <steve@sanityinc.com>
Commit: Steve Purcell <steve@sanityinc.com>
Instead of checking startup files, just warn if execution is slow
See #100
---
README.md | 40 +++++++++++++++++++++++++++++-----------
exec-path-from-shell.el | 41 ++++++++++++++++++-----------------------
2 files changed, 47 insertions(+), 34 deletions(-)
diff --git a/README.md b/README.md
index 9f7acccafc..a50fc66cc2 100644
--- a/README.md
+++ b/README.md
@@ -97,15 +97,21 @@ but instead do this:
export PATH=/usr/local/bin:/usr/bin:/bin
```
-You should also set your environment variables so that they are
-available to both interactive and non-interactive shells. In practical
-terms, for most people this means setting them in `~/.profile`,
-`~/.bash_profile`, `~/.zshenv` instead of `~/.bashrc` and
-`~/.zshrc`. By default, `exec-path-from-shell` checks for this
-mistake, at the cost of some execution time. If your config files are
-set up properly, you can set `exec-path-from-shell-arguments`
-appropriately (often to `nil`) before calling
-`exec-path-from-shell-initialize` to avoid this overhead.
+To be safe, `exec-path-from-shell` starts an interactive (and login)
+shell by default, but this can be much slower than necessary.
+Interactive shells often have fancy features enabled that are only
+helpful when one interacts directly with the shell, and this can
+frequently cause startup time to exceed 750ms. This can be avoided:
+
+* Follow best practice by setting your environment variables so that
+ they are available to both interactive and non-interactive shells.
+ In practical terms, for most people this means setting them in
+ `~/.profile`, `~/.bash_profile`, `~/.zshenv` instead of `~/.bashrc`
+ and `~/.zshrc`.
+* Once a non-interactive shell sets your environment variables
+ correctly, adjust `exec-path-from-shell-arguments` appropriately
+ (often to `nil`) before calling `exec-path-from-shell-initialize` so
+ that it will start a non-interactive shell.
To learn more about how popular shells load start-up files, read
[this helpful
article](https://blog.flowblok.id.au/2013-02/shell-startup-scripts.html).
@@ -113,8 +119,20 @@ To learn more about how popular shells load start-up
files, read
Making `exec-path-from-shell` faster
------------------------------------
-* Invoking the shell has a non-trivial overhead. Don't call
`exec-path-from-shell-copy-env` repeatedly, since each invocation starts a
shell. Instead, set `exec-path-from-shell-variables` to the full list of vars
you want, and call `exec-path-from-shell-initialize` once.
-* Non-interactive shells start up faster. Follow the steps in the section
above so that you can run your shell without `-i` and still get the right
environment variable settings. When `"-i"` is then removed from
`exec-path-from-shell-arguments`, this package becomes more efficient.
+If evaluation takes more than
+`exec-path-from-shell-warn-duration-millis` (500ms by default) then
+`exec-path-from-shell` will print a warning.
+
+* Non-interactive shells start up faster. Follow the steps in the
+ section above so that you can run your shell without `-i` and still
+ get the right environment variable settings. When `"-i"` is then
+ removed from `exec-path-from-shell-arguments`, this package becomes
+ more efficient.
+* Invoking the shell has a non-trivial overhead in any case. Don't
+ call `exec-path-from-shell-copy-env` repeatedly, since each
+ invocation starts a shell. Instead, set
+ `exec-path-from-shell-variables` to the full list of vars you want,
+ and call `exec-path-from-shell-initialize` once.
Further help
------------
diff --git a/exec-path-from-shell.el b/exec-path-from-shell.el
index 6caa746ae6..87a9e88f69 100644
--- a/exec-path-from-shell.el
+++ b/exec-path-from-shell.el
@@ -87,12 +87,9 @@
:type '(repeat (string :tag "Environment variable"))
:group 'exec-path-from-shell)
-(defcustom exec-path-from-shell-check-startup-files t
- "If non-nil, warn if variables are being set in the wrong shell startup
files.
-Environment variables should be set in .profile or .zshenv rather than
-.bashrc or .zshrc."
- :type 'boolean
- :group 'exec-path-from-shell)
+(defcustom exec-path-from-shell-warn-duration-millis 500
+ "Print a warning message if shell execution takes longer than this many
milliseconds."
+ :type 'integer)
(defcustom exec-path-from-shell-shell-name nil
"If non-nil, use this shell executable.
@@ -141,6 +138,19 @@ The default value denotes an interactive login shell."
"Return non-nil iff SHELL supports the standard ${VAR-default} syntax."
(not (string-match "\\(fish\\|t?csh\\)$" shell)))
+(defmacro exec-path-from-shell--warn-duration (&rest body)
+ "Evaluate BODY and warn if execution duration exceeds a time limit.
+The limit is given by `exec-path-from-shell-warn-duration-millis'."
+ (let ((start-time (gensym))
+ (duration-millis (gensym)))
+ `(let ((,start-time (current-time)))
+ (prog1
+ (progn ,@body)
+ (let ((,duration-millis (* 1000.0 (float-time (time-subtract
(current-time) ,start-time)))))
+ (if (> ,duration-millis exec-path-from-shell-warn-duration-millis)
+ (message "Warning: exec-path-from-shell execution took %dms.
See the README for tips on reducing this." ,duration-millis)
+ (exec-path-from-shell--debug "Shell execution took %dms"
,duration-millis)))))))
+
(defun exec-path-from-shell-printf (str &optional args)
"Return the result of printing STR in the user's shell.
@@ -166,7 +176,8 @@ shell-escaped, so they may contain $ etc."
(concat "sh -c " (shell-quote-argument
printf-command)))))))
(with-temp-buffer
(exec-path-from-shell--debug "Invoking shell %s with args %S" shell
shell-args)
- (let ((exit-code (apply #'call-process shell nil t nil shell-args)))
+ (let ((exit-code (exec-path-from-shell--warn-duration
+ (apply #'call-process shell nil t nil shell-args))))
(exec-path-from-shell--debug "Shell printed: %S" (buffer-string))
(unless (zerop exit-code)
(error "Non-zero exit code from shell %s invoked with args %S.
Output was:\n%S"
@@ -225,26 +236,10 @@ As a special case, if the variable is $PATH, then the
variables
The result is an alist, as described by
`exec-path-from-shell-getenvs'."
(let ((pairs (exec-path-from-shell-getenvs names)))
- (when exec-path-from-shell-check-startup-files
- (exec-path-from-shell--maybe-warn-about-startup-files pairs))
(mapc (lambda (pair)
(exec-path-from-shell-setenv (car pair) (cdr pair)))
pairs)))
-(defun exec-path-from-shell--maybe-warn-about-startup-files (pairs)
- "Warn the user if the value of PAIRS seems to depend on interactive shell
startup files."
- (let ((without-minus-i (remove "-i" exec-path-from-shell-arguments)))
- ;; If the user is using "-i", we warn them if it is necessary.
- (unless (eq exec-path-from-shell-arguments without-minus-i)
- (let* ((exec-path-from-shell-arguments without-minus-i)
- (alt-pairs (exec-path-from-shell-getenvs (mapcar 'car pairs)))
- different)
- (dolist (pair pairs)
- (unless (equal pair (assoc (car pair) alt-pairs))
- (push (car pair) different)))
- (when different
- (message "You appear to be setting environment variables %S in your
.bashrc or .zshrc: those files are only read by interactive shells, so you
should instead set environment variables in startup files like .profile,
.bash_profile or .zshenv. Refer to your shell's man page for more info.
Customize `exec-path-from-shell-arguments' to remove \"-i\" when done, or
disable `exec-path-from-shell-check-startup-files' to disable this message."
different))))))
-
;;;###autoload
(defun exec-path-from-shell-copy-env (name)
"Set the environment variable $NAME from the user's shell.
- [nongnu] elpa/exec-path-from-shell 17fe8465cd 063/114: Merge pull request #44 from ksjogo/master, (continued)
- [nongnu] elpa/exec-path-from-shell 17fe8465cd 063/114: Merge pull request #44 from ksjogo/master, ELPA Syncer, 2023/09/05
- [nongnu] elpa/exec-path-from-shell 6be6e33bbe 057/114: Demote the warning to a message, ELPA Syncer, 2023/09/05
- [nongnu] elpa/exec-path-from-shell 731d805ed3 072/114: Also run exec-path-from-shell-initialize on Linux in example, ELPA Syncer, 2023/09/05
- [nongnu] elpa/exec-path-from-shell 5e355fbc50 076/114: Merge pull request #68 from timhillgit/master, ELPA Syncer, 2023/09/05
- [nongnu] elpa/exec-path-from-shell 20ad9805fd 077/114: Add Patreon badge, ELPA Syncer, 2023/09/05
- [nongnu] elpa/exec-path-from-shell 4d0af12747 081/114: Merge pull request #77 from jabranham/byte-compile, ELPA Syncer, 2023/09/05
- [nongnu] elpa/exec-path-from-shell d8aa7765a1 084/114: Merge pull request #82 from mernst/installation-instructions, ELPA Syncer, 2023/09/05
- [nongnu] elpa/exec-path-from-shell 53ca76b97f 089/114: Link to flowbok article about shell startup files, ELPA Syncer, 2023/09/05
- [nongnu] elpa/exec-path-from-shell 3cfedb8791 088/114: Merge pull request #90 from lassik/error-if-remote, ELPA Syncer, 2023/09/05
- [nongnu] elpa/exec-path-from-shell 2d152d1781 095/114: Clarify what the sample usage snippet does, ELPA Syncer, 2023/09/05
- [nongnu] elpa/exec-path-from-shell ad68d36747 102/114: Instead of checking startup files, just warn if execution is slow,
ELPA Syncer <=
- [nongnu] elpa/exec-path-from-shell 6336db9be1 111/114: Add Emacs 28.1 to CI matrix, ELPA Syncer, 2023/09/05
- [nongnu] elpa/exec-path-from-shell 03fc0a38af 114/114: Release 2.1, ELPA Syncer, 2023/09/05
- [nongnu] elpa/exec-path-from-shell d17c4e0b73 094/114: Notes about increasing speed, ELPA Syncer, 2023/09/05
- [nongnu] elpa/exec-path-from-shell 81125c5adb 093/114: Add FUNDING.yml, ELPA Syncer, 2023/09/05
- [nongnu] elpa/exec-path-from-shell e1f14450f1 098/114: Fix MELPA URL, add author footer, ELPA Syncer, 2023/09/05
- [nongnu] elpa/exec-path-from-shell 39aca32dda 001/114: Initial check-in, ELPA Syncer, 2023/09/05
- [nongnu] elpa/exec-path-from-shell 9c25f03459 006/114: Simplify initialization, ELPA Syncer, 2023/09/05
- [nongnu] elpa/exec-path-from-shell 0b81e0bf05 007/114: Copy $MANPATH on initialization, too, ELPA Syncer, 2023/09/05
- [nongnu] elpa/exec-path-from-shell f349bc25aa 009/114: Merge pull request #2 from lunaryorn/init-manpath, ELPA Syncer, 2023/09/05
- [nongnu] elpa/exec-path-from-shell f88aa7edec 010/114: Make the list of copied variables customizable. (See #2), ELPA Syncer, 2023/09/05