Fwiw, Danny's tip is what I used at a recent day job gig for defining subprojects in a 400k files repo.

João

On Wed, Nov 16, 2022, 22:39 Danny Freeman <danny@dfreeman.email> wrote:

Eric Abrahamsen <eric@ericabrahamsen.net> writes:

> Hi,
>
> Here's another issue that's technically a emacs.help question, but might
> result in some code/documentation updates, so I'm sending it here.
>
> My main day-job code base is an AWS CloudFormation monstrosity involving
> several Python Lambdas, among other things. Basic project structure
> looks like:
>
> project_root
> ├── .git
> ├── src
> │   └── python
> │       ├── VeryImportantLambda
> │       │   └── .venv
> │       ├── MoreImportance
> │       │   └── .venv
> │       ├── RunInCaseOfEmergency
> │       │   └── .venv
>
> I'm using the python-lsp-server python package in each Python
> subdirectory, and the key is that each of those directories is a virtual
> environment that needs to stay isolated from the others. Each has
> different packages installed, and in some cases even the Python versions
> are different (though I'm trying to get rid of that).
>
> When I was using lsp-mode this wasn't difficult, because lsp-mode and
> project.el are essentially orthogonal: if I visited a python file in a
> given lambda directory, I could use `pyvenv-activate' to activate that
> environment, and then the `lsp' invocation would confine itself to
> python files within the environment. Project.el just provided
> project-wide navigation.
>
> Now I'm trying to move to Eglot, and there is tighter integration
> between Eglot and project.el. Turning on Eglot in one lambda starts the
> server for all Python libraries in the whole project, not just the
> current environment. I looked into constructing my own version of the
> call to `eglot', but it is tightly tied to a project, all the way down.
>
> Is anyone else handling this situation? Any suggestions how to make it
> work?
>
> Thanks,
> Eric


I have NOT been in this situation, but it sounds like you want to keep
using project.el as is, but override eglot's usage of project.el to
identify root directory to start a lsp server in.

I think the place to start looking would be the function
`eglot--current-project`.

It uses a var called `eglot-lsp-context` which is `t` when eglot is
searching for a project.

Knowing this, there is another var called `project-find-functions` that
project.el uses when searching for project roots, which can be used for
finding custom project roots. I have one that looks for a file named
".project.el". If that file exists then that directory is identified as
a project. It's really useful when you have a project not in source
control.

See:
```
(defun project-find-project.el (dir)
  "Returns a `manual-project' instance if the project of the current
DIR has a .project.el file in its root directory."
  (let ((root (locate-dominating-file dir ".project.el")))
    (when root
      (cons 'transient root))))

(add-hook 'project-find-functions #'project-find-project.el)
```

Now, I am not a python programmer, but lets pretend that python
virtualenviroment depends on a file located in the directory you want to
activate one of these virtual environments, say `.virtualenv`.

You can write a project-find-functions implementation that looks for
these virutalenv files ONLY when eglot-lsp-context is active.

```
(defun project-find-virtualenv-for-eglot (dir)
  (when eglot-lsp-context
    (let ((root (locate-dominating-file dir ".virtualenv")))
      (when root
        (cons 'transient root)))))

(add-hook 'project-find-functions #'project-find-virtualenv-for-eglot)
```

I did not test this, but I think it should send you down the right path.
Eglot should see your aws lambda folders as the project root, and
project.el should see the parent.

If python virtual environments do not have any kind of file marker in
the filesystem, you could use a dummy file in those directories like
`.eglot-project` or something.

Hope this helps,
--
Danny Freeman