From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Danny Freeman Newsgroups: gmane.emacs.devel Subject: Re: Eglot, project.el, and python virtual environments Date: Wed, 16 Nov 2022 17:24:50 -0500 Message-ID: <878rkale3l.fsf@dfreeman.email> References: <87zgcq68zp.fsf@ericabrahamsen.net> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="14287"; mail-complaints-to="usenet@ciao.gmane.io" Cc: emacs-devel@gnu.org To: Eric Abrahamsen Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Wed Nov 16 23:40:42 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 1ovR5F-0003TE-RB for ged-emacs-devel@m.gmane-mx.org; Wed, 16 Nov 2022 23:40:41 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ovR3T-0003jX-5E; Wed, 16 Nov 2022 17:38:51 -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 1ovR3N-0003fi-KL for emacs-devel@gnu.org; Wed, 16 Nov 2022 17:38:49 -0500 Original-Received: from out0.migadu.com ([94.23.1.103]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ovR3J-0005oz-7L for emacs-devel@gnu.org; Wed, 16 Nov 2022 17:38:43 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dfreeman.email; s=key1; t=1668638312; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tSSqsJbqAksG/7DxokJcWm59YnZwh/He54H5oL1YoWE=; b=lJyTUzDYOxDmDqOzebAGu7FcD6DbTSUBx9SV9KDq2ZzAmSqAtRVq/rEhDH1/Ki5i0ydBSQ vUsLPTVx0HdMLQhuT7I0MjPd0rR+J/R7Xbf2LzkT9Ti+2oj21SZDx6EIlMJl5d2AZUG8R/ opic+l/eDah9jeIJvXD3mUrLBo+/avg= X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. In-reply-to: <87zgcq68zp.fsf@ericabrahamsen.net> X-Migadu-Flow: FLOW_OUT Received-SPF: pass client-ip=94.23.1.103; envelope-from=danny@dfreeman.email; helo=out0.migadu.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 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, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_PASS=-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:299991 Archived-At: Eric Abrahamsen 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 > =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 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`.=20 It uses a var called `eglot-lsp-context` which is `t` when eglot is searching for a project.=20 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.=20 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, --=20 Danny Freeman