Problem
I'm using Emacs with projectile and vterm for my development workflow. I've configured vterm to use screen as its shell:
(setq vterm-shell "screen") I've created a function that opens a vterm terminal in my project root:
(defun open-terminal-in-project-root () (interactive) (let* ((project-root (projectile-project-root)) (buffer-name (format "*terminal-%s*" (projectile-project-name))) (existing-buffer (get-buffer buffer-name))) (if existing-buffer (pop-to-buffer existing-buffer) (let ((default-directory project-root)) (vterm) (rename-buffer buffer-name t))))) When I navigate away from the project root in the terminal, I'd like to be able to quickly return. My plan is to set a PROJECTILE_ROOT environment variable when the terminal starts, which I could then use in a shell function to return to that directory.
What I've tried
I've attempted to set the environment variable using:
(vterm-send-string (format "export PROJECTILE_ROOT=\"%s\"\n" project-root)) But this doesn't seem to work with screen as the shell. When I check with env | grep PROJECTILE, the variable isn't set.
Question
How can I reliably set an environment variable in a vterm terminal that's running screen in Emacs? Is there a special approach needed for the screen+vterm combination?
EDIT:
Thank you for the helpful explanation. I tried using vterm-environment as suggested:
(defun open-terminal-in-project-root () (interactive) (let* ((project-root (projectile-project-root)) (buffer-name (format "*terminal-%s*" (projectile-project-name))) (existing-buffer (get-buffer buffer-name))) (if existing-buffer (pop-to-buffer existing-buffer) (let ((default-directory project-root) (vterm-environment (list (format "PROJECTILE_ROOT=%s" project-root)))) (vterm) (rename-buffer buffer-name t))))) I confirmed that vterm-environment works correctly when I use bash directly - the variable appears when checking with env | grep PROJECTILE_ROOT.
However, I realized the issue is with my vterm-shell configuration. I have:
(setq vterm-shell "screen") The environment variable is being passed to screen itself rather than the shell inside screen.
So the core issue appears to be: How can I pass environment variables to the shell inside screen when using vterm?
I'm considering using a wrapper script approach like:
#!/bin/bash PROJECT_ROOT="$1" export PROJECTILE_ROOT="$PROJECT_ROOT" exec screen "${@:2}" And then setting:
(vterm-shell (format "~/bin/vterm-screen-wrapper.sh %s" (shell-quote-argument project-root))) Is this the right approach for this situation? Are there any pitfalls I should be aware of?