emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Managing environments (Python venv, guix environment, etc.)


From: sbaugh
Subject: Managing environments (Python venv, guix environment, etc.)
Date: Thu, 14 Jul 2016 17:36:08 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux)

Hi emacs-devel,

There are a number of tools which create a reproducible working
environment for projects by changing environment variables such as PATH
and LIBRARY_PATH to point at project-specific directories containing
project-specific versions of libraries and executables. Two examples
among many: Python's "virtualenv" and Guix's "guix environment".

A typical shell-based workflow with these tools would involve starting
your shell and activating the tool so it mutates your environment and
puts you into the working environment specific to that project. With
multiple terminals, one can have multiple shells open at the same time
to work on multiple different projects each with a different
environment.

One could run several Emacs processes with different environments to
work on different projects, but that's very painful. So I'm trying to
teach Emacs how to handle multiple environments within the same
process. Currently, Emacs can only operate in one environment at a time,
since exec-path and process-environment are single global variables that
are referenced directly by many different Elisp functions.

Here's the ideal: The recently added support for projects in project.el
is augmented to also know about the environment of those projects. When
compile, async-shell-command, etc., are invoked in a buffer belonging to
a project, the executed process is run with the environment defined for
that project. Any other Elisp functions that inspect the environment
should reference the environment defined for the current project.

But I would count it as a failure if multiple-environment support
required every Elisp package that runs processes to be explicitly
modified to support it. Even just modifying everything in Emacs itself
would be a major undertaking. So backwards-compatibility through some
clever hacks is important.

But I am only a humble novice, and am unsure about the best way to
achieve this. Here are a few ideas I had:

- Make exec-path and process-environment buffer-local

  I am told that this will cause a lot of bizarre behavior. In
  particular, I understand that this won't work with M-x compile, which
  reuses another buffer to run the compilation.

- Make exec-path and process-environment a different kind of
  buffer-local dynamic variable

  The behavior of this variable would be that when it is defined locally
  in the current buffer, it behaves like a normal dynamic variable. And
  when it is not defined locally in the current buffer, looking up the
  variable will look up the variable dynamically instead of looking for
  a global value set with setq-default.
  This would mean that when M-x compile is invoked from some buffer, if
  exec-path and process-environment are not buffer-local in the compile
  buffer, those variables will be looked up dynamically, and found in
  the buffer-locals of the buffer that was current at the time of the
  M-x compile invocation.
  I don't know if this is possible given the implementation of dynamic
  variables in Emacs Lisp.

- Use the same functionality as TRAMP, somehow

  TRAMP supports transparently running processes in multiple arbitrary
  environments (usually ones accessible over the network, but local
  environments should work too).
  But I'm not really familiar with how TRAMP works, so I'm not sure if
  it's possible to make use of its process-running capabilities without
  using magic filenames, and without copying files back and forth (an
  ugly overhead in this case since the files would all be local).

- Use dir-locals

  I'm not sure how this could work, given the problems with making
  exec-path and process-environment buffer-local, but including it to be
  complete.

If any of the great masters have suggestions about how to achieve this,
I would greatly appreciate it. Thanks.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]