From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: =?UTF-8?B?Sm/Do28gVMOhdm9yYQ==?= Newsgroups: gmane.emacs.devel Subject: Re: Eglot, project.el, and python virtual environments Date: Fri, 18 Nov 2022 18:31:20 +0000 Message-ID: References: <87zgcq68zp.fsf@ericabrahamsen.net> <878rkale3l.fsf@dfreeman.email> Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="00000000000030be6805edc2eabd" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="27265"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Eric Abrahamsen , emacs-devel To: Danny Freeman Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Fri Nov 18 19:32:54 2022 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1ow6AY-0006qt-51 for ged-emacs-devel@m.gmane-mx.org; Fri, 18 Nov 2022 19:32:54 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ow69M-0001GZ-5q; Fri, 18 Nov 2022 13:31:40 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ow69I-0001F6-8H for emacs-devel@gnu.org; Fri, 18 Nov 2022 13:31:38 -0500 Original-Received: from mail-oa1-x2b.google.com ([2001:4860:4864:20::2b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1ow69F-0001Kx-Rc for emacs-devel@gnu.org; Fri, 18 Nov 2022 13:31:35 -0500 Original-Received: by mail-oa1-x2b.google.com with SMTP id 586e51a60fabf-14279410bf4so5114391fac.8 for ; Fri, 18 Nov 2022 10:31:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=QhX1xtQmyyVhCzN0pmlJ/Jw8fw0NRR31K9pK8k5tVO8=; b=AglSV1SmfzAOaQGPTdgol7HE/O4+wAwFo0JZuhA+dMxyaWGvY9CmF11wRjtmNBswsj YVdQ/o1N723BgwmL+9gd5V5scNTCDqbTJUSze8K8XpKeKg2I7XfO4FOQ5ohYjBxAACll XxwSjtXZc2bDTuLhe8gLrxhlec1ejfTXLh4l6LWM/dZkXTIUcu86FEF25cZUe4wRGd94 C3Xqu+oHP0161T77IKI8PKt2CisgIhIaZddGa5Vz4BRWDjwzjnPf2rqQAY77fxnja2lE fbnQ9nhDblXTXp8BIS3E6qciNwXx19Vsb2K6WD12un8Ptchww0XccmE8EZ/sv3Gkcb5r VaRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=QhX1xtQmyyVhCzN0pmlJ/Jw8fw0NRR31K9pK8k5tVO8=; b=wVHDfjQeSetkC6KCbiiOZ/Qfk2f9y/ZruWX7rPQ4yBoStoyTw17hQGxDwOWubFoJw6 7NCwnqBtnPGWnAK1h+C5f5aciUX/zz/TnPIVh5lZalXn36p2747fmMMzsw76zF0rTuPn bf/vGwhgo95foo30oDJrA2IsCvKjy0EHLae6jxVdEkO5jkn7sffZlEPpUxRyn+J7MIFt dRVgGcuXYlOaWvbiI4w8TpUuudafm2L1KK5e9nHASFJXKTspypW9bQYmhNfa9GIYWTNw ZGUNCqNyPAY+toUAz3zsH3bo2GSm19ukedJVRmEwOSWMScPM4prUEsXk2QZ0rTqEGTp+ 3KWA== X-Gm-Message-State: ANoB5plPfodex7ZjpjdEFZlITmWXWiZLSZcMmGupnVofLko2jBuYEKht +NJJzGKKybtfZbq7pGaR4AaKigoO5BYkO4D8x1OwaF+X X-Google-Smtp-Source: AA0mqf60ZwUBvgPYpuSF8uIYT7E65UJ5Zbmn/WceRDp1C4oq5bfQrTq50kd5gbciU9iuO3mmDeLdJWouTgZDFQbDKIE= X-Received: by 2002:a05:6871:4590:b0:132:a103:ae22 with SMTP id nl16-20020a056871459000b00132a103ae22mr4816809oab.215.1668796292052; Fri, 18 Nov 2022 10:31:32 -0800 (PST) In-Reply-To: <878rkale3l.fsf@dfreeman.email> Received-SPF: pass client-ip=2001:4860:4864:20::2b; envelope-from=joaotavora@gmail.com; helo=mail-oa1-x2b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.devel:300117 Archived-At: --00000000000030be6805edc2eabd Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Fwiw, Danny's tip is what I used at a recent day job gig for defining subprojects in a 400k files repo. Jo=C3=A3o On Wed, Nov 16, 2022, 22:39 Danny Freeman wrote: > > Eric Abrahamsen writes: > > > Hi, > > > > Here's another issue that's technically a emacs.help question, but migh= t > > result in some code/documentation updates, so I'm sending it here. > > > > My main day-job code base is an AWS CloudFormation monstrosity involvin= g > > several Python Lambdas, among other things. Basic project structure > > looks like: > > > > project_root > > =E2=94=9C=E2=94=80=E2=94=80 .git > > =E2=94=9C=E2=94=80=E2=94=80 src > > =E2=94=82 =E2=94=94=E2=94=80=E2=94=80 python > > =E2=94=82 =E2=94=9C=E2=94=80=E2=94=80 VeryImportantLambda > > =E2=94=82 =E2=94=82 =E2=94=94=E2=94=80=E2=94=80 .venv > > =E2=94=82 =E2=94=9C=E2=94=80=E2=94=80 MoreImportance > > =E2=94=82 =E2=94=82 =E2=94=94=E2=94=80=E2=94=80 .venv > > =E2=94=82 =E2=94=9C=E2=94=80=E2=94=80 RunInCaseOfEmergency > > =E2=94=82 =E2=94=82 =E2=94=94=E2=94=80=E2=94=80 .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 virtua= l > > environment that needs to stay isolated from the others. Each has > > different packages installed, and in some cases even the Python version= s > > 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 > > --00000000000030be6805edc2eabd Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Fwiw, Danny's tip is what I used at a recent day job = gig for defining subprojects in a 400k files repo.

Jo=C3=A3o

On Wed, Nov 16, 2022, 22:39 Danny Freem= an <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 involvi= ng
> several Python Lambdas, among other things. Basic project structure > looks like:
>
> project_root
> =E2=94=9C=E2=94=80=E2=94=80 .git
> =E2=94=9C=E2=94=80=E2=94=80 src
> =E2=94=82=C2=A0 =C2=A0=E2=94=94=E2=94=80=E2=94=80 python
> =E2=94=82=C2=A0 =C2=A0 =C2=A0 =C2=A0=E2=94=9C=E2=94=80=E2=94=80 VeryIm= portantLambda
> =E2=94=82=C2=A0 =C2=A0 =C2=A0 =C2=A0=E2=94=82=C2=A0 =C2=A0=E2=94=94=E2= =94=80=E2=94=80 .venv
> =E2=94=82=C2=A0 =C2=A0 =C2=A0 =C2=A0=E2=94=9C=E2=94=80=E2=94=80 MoreIm= portance
> =E2=94=82=C2=A0 =C2=A0 =C2=A0 =C2=A0=E2=94=82=C2=A0 =C2=A0=E2=94=94=E2= =94=80=E2=94=80 .venv
> =E2=94=82=C2=A0 =C2=A0 =C2=A0 =C2=A0=E2=94=9C=E2=94=80=E2=94=80 RunInC= aseOfEmergency
> =E2=94=82=C2=A0 =C2=A0 =C2=A0 =C2=A0=E2=94=82=C2=A0 =C2=A0=E2=94=94=E2= =94=80=E2=94=80 .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 virtu= al
> environment that needs to stay isolated from the others. Each has
> different packages installed, and in some cases even the Python versio= ns
> 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<= br> > between Eglot and project.el. Turning on Eglot in one lambda starts th= e
> server for all Python libraries in the whole project, not just the
> current environment. I looked into constructing my own version of the<= br> > 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 identif= ied as
a project. It's really useful when you have a project not in source
control.

See:
```
(defun project-find-project.el (dir)
=C2=A0 "Returns a `manual-project' instance if the project of the = current
DIR has a .project.el file in its root directory."
=C2=A0 (let ((root (locate-dominating-file dir ".project.el"))) =C2=A0 =C2=A0 (when root
=C2=A0 =C2=A0 =C2=A0 (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)
=C2=A0 (when eglot-lsp-context
=C2=A0 =C2=A0 (let ((root (locate-dominating-file dir ".virtualenv&quo= t;)))
=C2=A0 =C2=A0 =C2=A0 (when root
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (cons 'transient root)))))

(add-hook 'project-find-functions #'project-find-virtualenv-for-egl= ot)
```

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

--00000000000030be6805edc2eabd--