From b9455643a4636fc00548917176d059130d91460d Mon Sep 17 00:00:00 2001 From: ncaq Date: Tue, 29 Apr 2025 16:23:34 +0900 Subject: [PATCH] fix: run shell with clean environment The problem was that Nix's initialization script checks for an environment variable (`__ETC_PROFILE_NIX_SOURCED`) to prevent duplicate execution. When Emacs calls a shell process, this variable is inherited, causing the Nix `PATH` setup to be skipped. This commit adds a function to run call-process with empty process-environment, ensuring shell initialization scripts run completely fresh, properly including Nix paths in the returned environment variables. --- exec-path-from-shell.el | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/exec-path-from-shell.el b/exec-path-from-shell.el index a6e9abb..a0dd24c 100644 --- a/exec-path-from-shell.el +++ b/exec-path-from-shell.el @@ -157,6 +157,26 @@ The limit is given by `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--call-process-with-clean-env (program &optional infile destination display &rest args) + "Call PROGRAM with a completely clean environment. + +This function is a thin wrapper around `call-process'. +It binds `process-environment' to an empty list so that no inherited +environment variables from Emacs (e.g. PATH, LANG) + are passed to the subprocess. + +Arguments are the same as for `call-process': + + PROGRAM — the executable to run (string) + INFILE — nil, t, or a file name for standard input + DESTINATION — nil, t, or a buffer/file for standard output + DISPLAY — if non-nil, redisplay buffer as output is inserted + ARGS — additional arguments passed to PROGRAM + +Returns the exit code of the called process." + (let ((process-environment nil)) + (apply #'call-process program infile destination display args))) + (defun exec-path-from-shell-printf (str &optional args) "Return the result of printing STR in the user's shell. @@ -183,7 +203,7 @@ shell-escaped, so they may contain $ etc." (with-temp-buffer (exec-path-from-shell--debug "Invoking shell %s with args %S" shell shell-args) (let ((exit-code (exec-path-from-shell--warn-duration - (apply #'call-process shell nil t nil shell-args)))) + (apply #'exec-path-from-shell--call-process-with-clean-env 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" @@ -209,7 +229,7 @@ The result is a list of (NAME . VALUE) pairs." (with-temp-buffer (exec-path-from-shell--debug "Invoking shell %s with args %S" shell shell-args) (let ((exit-code (exec-path-from-shell--warn-duration - (apply #'call-process shell nil t nil shell-args)))) + (apply #'exec-path-from-shell--call-process-with-clean-env 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"