all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Ergus <spacibba@aol.com>
To: Dmitry Gutov <dmitry@gutov.dev>
Cc: emacs-devel@gnu.org
Subject: Re: [PATCH] Project out of sources compilation
Date: Sat, 6 Apr 2024 04:05:22 +0200	[thread overview]
Message-ID: <bnexqmzsj5kyu6srxg23l2u4nur4cwo7uauzsp2qzfpxrmmt4r@ty4niqurpkvq> (raw)
In-Reply-To: <09a8189d-07e3-4bc5-a4f4-127dcdcec2d1@gutov.dev>

[-- Attachment #1: Type: text/plain, Size: 791 bytes --]

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

[-- Attachment #2: project-extra-info.patch --]
[-- Type: text/plain, Size: 5481 bytes --]

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)

  parent reply	other threads:[~2024-04-06  2:05 UTC|newest]

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <4wwljrdnra3bsloehioa46y24ozxajajmvf2elvskxxq3mhtg2.ref@pyv2z5snot6h>
2024-03-16 13:12 ` Project out of sources compilation Ergus
2024-03-16 16:50   ` Konstantin Kharlamov
2024-03-16 19:00     ` Ergus
2024-03-16 20:56       ` Konstantin Kharlamov
2024-03-17  2:53   ` Dmitry Gutov
2024-03-17  7:22     ` Ergus
2024-03-17  8:45       ` Eli Zaretskii
2024-03-17 17:33         ` Ergus
2024-03-17 17:38           ` Eli Zaretskii
2024-03-17 17:58             ` Ergus
2024-03-17 11:36   ` Augusto Stoffel
2024-03-17 17:47     ` Ergus
2024-03-19 18:36       ` Ergus
2024-03-27 16:38         ` [PATCH] " Ergus
2024-03-31  2:41           ` Dmitry Gutov
2024-03-31 21:07             ` Ergus
2024-04-01  7:49               ` Dirk-Jan C. Binnema
2024-04-01 13:52                 ` Ergus
2024-04-01 15:09                   ` Dirk-Jan C. Binnema
2024-04-01 17:18                     ` Ergus
2024-04-02 23:23                   ` Dmitry Gutov
2024-04-03 19:47                     ` Ergus
2024-04-06  2:05                     ` Ergus [this message]
2024-04-14  1:44                       ` Dmitry Gutov
2024-04-16 14:56                         ` Ergus
2024-04-22 17:05                         ` Ergus
2024-04-22 18:48                           ` Ergus
2024-04-22 21:20                             ` Mohsin Kaleem
2024-04-23 15:17                               ` Ergus
2024-04-23 19:26                                 ` Mohsin Kaleem
2024-04-26  0:47                               ` Dmitry Gutov
2024-04-02 21:39               ` Richard Stallman
2024-04-02 22:43                 ` Dr. Arne Babenhauserheide
2024-04-05 21:40                   ` Richard Stallman
2024-04-03 10:40                 ` Konstantin Kharlamov
2024-04-03 11:45                   ` Eli Zaretskii
2024-04-03 13:31                     ` Konstantin Kharlamov
2024-04-03 14:11                       ` Eli Zaretskii
2024-04-03 15:00                         ` Konstantin Kharlamov
2024-04-03 15:47                           ` Eli Zaretskii
2024-04-03 17:27                             ` Konstantin Kharlamov
2024-04-03 18:22                               ` Eli Zaretskii
2024-04-03 19:08                                 ` Konstantin Kharlamov
2024-04-03 20:12                                   ` Ergus
2024-04-04  5:26                                     ` Eli Zaretskii
2024-04-04  9:59                                       ` Ergus
2024-04-04 11:59                                         ` Eli Zaretskii
2024-04-04 12:34                                           ` Ergus
2024-04-04 13:02                                             ` Eli Zaretskii
2024-04-04 14:27                                               ` Ergus
2024-04-04 14:41                                                 ` Eli Zaretskii
2024-04-04 18:15                                                   ` Ergus
2024-04-04 18:56                                                     ` Eli Zaretskii
2024-04-04 20:16                                                   ` Konstantin Kharlamov
2024-04-05  5:11                                                     ` Eli Zaretskii
2024-04-04  5:07                                   ` Eli Zaretskii
     [not found]                               ` <87jzlefgi9.fsf@dick>
2024-04-03 18:44                                 ` Konstantin Kharlamov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bnexqmzsj5kyu6srxg23l2u4nur4cwo7uauzsp2qzfpxrmmt4r@ty4niqurpkvq \
    --to=spacibba@aol.com \
    --cc=dmitry@gutov.dev \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.