From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Ergus Newsgroups: gmane.emacs.devel Subject: Re: [PATCH] Project out of sources compilation Date: Sat, 6 Apr 2024 04:05:22 +0200 Message-ID: References: <4wwljrdnra3bsloehioa46y24ozxajajmvf2elvskxxq3mhtg2@pyv2z5snot6h> <87ttl5w0mr.fsf@gmail.com> <1fd527fc-9643-49d2-8fae-d7e7fd043fe1@gutov.dev> <87le5x34l6.fsf@gmail.com> <27rton4k4r6sacysluk7iikj57ai2tyiak4ldd5nzpts7thmhg@nriej75catir> <09a8189d-07e3-4bc5-a4f4-127dcdcec2d1@gutov.dev> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="pnmcjvlpe4s47zuw" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="1471"; mail-complaints-to="usenet@ciao.gmane.io" Cc: emacs-devel@gnu.org To: Dmitry Gutov Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sat Apr 06 04:06:18 2024 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 1rsvRh-0000Ds-GY for ged-emacs-devel@m.gmane-mx.org; Sat, 06 Apr 2024 04:06:17 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rsvR7-0001fB-6c; Fri, 05 Apr 2024 22:05:41 -0400 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 1rsvR4-0001eF-4O for emacs-devel@gnu.org; Fri, 05 Apr 2024 22:05:38 -0400 Original-Received: from sonic301-1.consmr.mail.bf2.yahoo.com ([74.6.129.40]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rsvR1-0006RE-Eu for emacs-devel@gnu.org; Fri, 05 Apr 2024 22:05:37 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aol.com; s=a2048; t=1712369131; bh=BEq2VjLQdmxNu3TS9YBdzCiPVveujo29fMH0XhA9xAM=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From:Subject:Reply-To; b=pMHsI3hTGKo73fE2y6RustmKKKdYmPYpSJ7qEy5UKCHfa6TlHaBwHNDgaQLPbL1OvjKIoCuMKzgO1nV4Ur53Zm/Tt/ZpodAX2ArmXvbAm3yz7piZdKCmIHGYTX24wOUkOsiOEMCLBKLrjnKH85UM7q+vu8zZYSbcOtJP7k51vfZPvZuaiOq/k5jI1OIlWWui53CNP0+ojv+HgaGLJcX8bjryLEqdtMXRlENspEopZAQhDPl5xh5rChs+vtRtXlVNJey/79GhZKw6wYZU+5hIQLf8MQ7lHADswCJbAsNj91tVNPIN7qZ1A/qNOqTS7WZ9qp8b+t9omGRH0u2on4zbPA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1712369131; bh=epdPsMOiZO4y4CmbDTkoNgvyLox6UiZbvnlGcKDIksa=; h=X-Sonic-MF:Date:From:To:Subject:From:Subject; b=WAeo30SMX1viY+ACSX33oHnA/jRvAHwvN3VNsJdxGKcSS9ilAEkt1t/6U6+JPszqmqwZmfqalbNFA9KIm0QMuwPP6TEylVL1s59XTPHnEz3R97izhlOx8UGKFTg/6QkE8EF0y/smzbg5d/FhfDDUpXldb1PjFSx/PWiqe96VDIPaNglE6BYZm9INOciji8k1dvkdqC7kBiCnPU1AIO4nad8oa6VuA8qnMBZEh1pTQsod4qRoIXADusokmZ/lNd/HKnpoWG4E+KmeWWvql/wzeVHiEDKx2mh6XWtMzLGXUA04PDZ2ICnTreB9ZHNETrsL0sJo7BtjMKwQuE69M9SWZQ== X-YMail-OSG: cv4Mj7oVM1nmU7JhH5FOHPhO5AAmynUiysrt.n4wxhcAgP1MVCl47zEkrGUG2MJ yoHEC8RUX_g_Gm2wUEzBP9qciB4gl1A2xlw60Od_2Sz.Z87Qo9jyTvD4JuSQrXQtES8nr9haZKx. O2JHpiU7EKurJX5NanwCTFi.DozQIMwM5.7d3h05F66v9Znd158JWtgILBSXV9r.3wDmPz3fYnwd 6dhdd_hbcseUZVb4doXPwV1jjbtm2jJpXP2sRBZjdYaUNk_284V45n5Wl3dIOZjoUYv6CFB_gwkG 9urFAR_GtriN.qSi5tCwbbvXE9FWp2AcYeDIdmvBDRc4tAxylsC5jQRy_V.ulqu04wEmHbv6ptnT cmAYL2oIOoTw2EV6WE.3F5H5kPbm07GGdnSmZIn0nhX0h2zVmzInECL2_GORJJZrAb15QkJbtLJ9 2pvYzoNcgBXhLGt4k2_s9dgWaBr4JfN6IoGihz.CGhCOAG_wnwmrCBT2hW2we2O0w1oWE95jg4rs 25BufUko1oMSZao4zZ5yoMSuCy2o8.M2ab0aVbL2fEXFc4UQilVdXZ9X0Fy_U5RjR4xhuk3TECUc TgiKImbQtxs.eXtjAu.7kVEW3y60pJ2rvgQ7mJU.a3i7qc9j9pFy3UfM0w5gRcKKxZ5YaaryPsS1 J9y4oB9u4t3Yo4kvYI07hwkselKQjzTEmlnGsbB55hyqwg2Lq96drav5fBS5WftzuToWpJCq74rS Cdri6uP6pH4UCIhYBvPrkhZQlIjfntD_suD29sd5KahsI3JntOrWbcMiCcX1t5moZevNcenVUyMk Xlx0P_FVH.x1Y0.S_B3G9SGJyzOe0Jp8qtLE4eBFel X-Sonic-MF: X-Sonic-ID: 756f8ef4-cb53-4072-b335-8e2debf6df74 Original-Received: from sonic.gate.mail.ne1.yahoo.com by sonic301.consmr.mail.bf2.yahoo.com with HTTP; Sat, 6 Apr 2024 02:05:31 +0000 Original-Received: by hermes--production-ir2-7bc88bfc75-h6nxx (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID d60b6b7cc766ea5bf4cf41b6c034970b; Sat, 06 Apr 2024 02:05:25 +0000 (UTC) Content-Disposition: inline In-Reply-To: <09a8189d-07e3-4bc5-a4f4-127dcdcec2d1@gutov.dev> X-Mailer: WebService/1.1.22205 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.aol Received-SPF: pass client-ip=74.6.129.40; envelope-from=spacibba@aol.com; helo=sonic301-1.consmr.mail.bf2.yahoo.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, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, 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:317565 Archived-At: --pnmcjvlpe4s47zuw Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline Hi Dmitry: Here I attach a new patch with what I think is the best approach to handle the extra info for projects. This implementation is pretty simple for both sides (user, project.el and backends) and uses your main idea of the generics + a custom. However I decided not to use only the custom as you suggested, because considering the project initialization it will require a complex and error prone approach to initalize the backend variables correctly (for example, when some buffers are already open). With this implementation the backends only need to define the optional generic specializations and the policy is pretty simple to explain (see the doc strings). I also modifies the backend project on github to match this new api, so, you can check it as well. WDYT? Best, Ergus --pnmcjvlpe4s47zuw Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="project-extra-info.patch" diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index da211566a3b..1986c14e861 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -51,6 +51,16 @@ ;; files inside the root must not be considered a part of it). It ;; should be consistent with `project-files'. ;; +;; `project-extra-info' is a user custom variable and a method to +;; specify extra project information like build command or equivalent. +;; The variable is a plist were the values can be strings or functions +;; that receive the project-current as argument. The +;; `project-extra-info' expect project current as first parameter and an +;; extra parameter equivalent to the plist key. The user defined plist +;; takes precedence over the backend defined methods, but all the +;; specializations are optional and the functions calling them may +;; provide conditions in case both are undefined. +;; ;; This list can change in future versions. ;; ;; Transient project: @@ -229,8 +239,8 @@ project-current of the project instance object." (unless directory (setq directory (or project-current-directory-override default-directory))) - (let* ((non-essential (not maybe-prompt)) - (pr (project--find-in-directory directory))) + (let ((pr (project--find-in-directory directory)) + (non-essential (not maybe-prompt))) (cond (pr) ((unless project-current-directory-override @@ -290,8 +300,54 @@ project-external-roots headers search path, load path, class path, and so on." nil) +(defcustom project-extra-info nil + "Project extra info defined in user space. + +This is intended to be set by the user. This is expected to be a plist +with key entries for compile. At the moment the implemented keys are +`:compile-command' and `:compile-dir'. The entries may be either string +constants, paths or functions. This custom has a symmetric generic +method with the same name that are intended to be implemented by the +project backends. When this variable is defined it takes precedence +over the backend methods." + :safe t + :version "30.1" + :type '(plist :key-type (choice (const :compile-dir) + (const :compile-command)) + :value-type (choice string + directory + function))) + +(cl-defgeneric project-extra-info (_project _info) + "Return extra INFO for the current PROJECT. + +This function is intended to be defined by the backend when needed. +Otherwise this returns nil and the `project-compile' command will use +some default values. The current valid values for INFO are the same key +types in project-compile-info: `:compile-dir' and `:compile-command' +This method is independent from the custom variable with same name +because project.el initializes itself lazily and variable propagation +within directories and buffers already open will require too much work +in the user side potentially more error prone." + nil) + +(defun project--get-extra-info (project info) + "Steps to get PROJECT's INFO internally. +1. Parse the user defined variable `project-compile-info'. If the key +exists: + a. Check if it is a function and call it passing project as the first +parameter. + b. If the key is a string return it as is. + c. Otherwise return nil. +2. Else call the backend defined method `project-compile-info'." + (if-let ((value (plist-get project-extra-info info))) + (cond ((functionp value) (funcall value project)) + ((stringp info) info) + (t nil)) + (project-extra-info project info))) + (cl-defgeneric project-name (project) - "A human-readable name for the project. + "A human-readable name for the PROJECT. Nominally unique, but not enforced." (file-name-nondirectory (directory-file-name (project-root project)))) @@ -1389,13 +1445,26 @@ project-compilation-buffer-name-function ;;;###autoload (defun project-compile () - "Run `compile' in the project root." + "Run `compile' in the project build directory. +When the variable `project-extra-info' contains the entries +`:compile-dir' or `:compile-command' or the project backend specializes +the method `project-extra-info' for those values; then this command uses +that instead of the default: `project-root' and `compile-command'." (declare (interactive-only compile)) (interactive) - (let ((default-directory (project-root (project-current t))) - (compilation-buffer-name-function - (or project-compilation-buffer-name-function - compilation-buffer-name-function))) + ;; I am wondering whenever we need to expand connection local + ;; variables at this point... maybe before or inside the let. + (let* ((project (project-current t)) + (dir (or (project--get-extra-info project :compile-dir) + (project-root project))) + (default-directory (if (file-name-absolute-p dir) + dir + (expand-file-name dir (project-root project)))) + (compile-command (or (project--get-extra-info project :compile-command) + compile-command)) + (compilation-buffer-name-function + (or project-compilation-buffer-name-function + compilation-buffer-name-function))) (call-interactively #'compile))) (defun project-recompile (&optional edit-command) --pnmcjvlpe4s47zuw--