Subject: bug#77593: (Proof-of-Concept) Create projects with project templates

From: Elijah Gabe Pérez <[email-masked]>
Date: Sun, 06 Apr 2025 20:37:11 -0600

Hello, i want to share this package concept for create projects with
templates, this idea is similar to what EDE and skeletor.el (from MELPA)
offers.

The project template system aims to be simple to use for the user
and simple for people who wants to create new project templates.

New project templates are created in this way:

  |-- DIRECTORY_WHERE_TEMPLATES_LIVE
  | |-- PROJECT_TYPE_TEMPLATE_DIR
  | | |-- PROJECT_FILE...
  | | |-- PROJECT_FILE_2...
  | | |-- `project-template-info'
  | |-- ANOTHER_PROJECT_TYPE_TEMPLATE_DIR
  | | |-- ANOTHER_PROJECT_FILE...
  | | |-- ANOTHER_PROJECT_FILE_2...
  | | |-- `project-template-info'

The templates are created as real directories and files that should be
stored in a directory (DIRECTORY_WHERE_TEMPLATES_LIVE) which should
contain a file (project-template-info) that specifies project type (for
prompt to user which project type want to create); also offers
integration with project.el (for indexing the project created to project
list) and vc.el (if user wants use a versions control in the created
project).

The `project-template-info' scheme is something like this:
  ;;; -*- lisp-data -*-
  ;;; This file contains project type to use in project-templates.
  (:type "Make")

For create a new project the user will need to run
`project-templates-create-new-project' command which will prompt for:
 - Project type (it will be a list which contains all the project templates fetched)
 - Project name
 - Version Control to use (It preselect `None')
 - Add project to projects list (project.el)
 - Directory to where create the project

I made a test concept (it don't create a real project yet).
In case you want to try it.

>From dc1034909638adcdf209f5b240780a8e4b9c09df Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?El=C3=ADas=20Gabriel=20P=C3=A9rez?= <[email-masked]>
Date: Sun, 6 Apr 2025 11:32:12 -0600
Subject: [PATCH] Add project creation capabilities with project templates. 
 (bug#)

TODO: ChangeLog
---
 etc/project-templates/make/make               |   1 +
 .../make/project-template-info                |   3 +
 lisp/progmodes/project-templates.el           | 110 ++++++++++++++++++
 3 files changed, 114 insertions(+)
 create mode 100644 etc/project-templates/make/make
 create mode 100644 etc/project-templates/make/project-template-info
 create mode 100644 lisp/progmodes/project-templates.el

diff --git a/etc/project-templates/make/make b/etc/project-templates/make/make
new file mode 100644
index 00000000000..bc60bf4b019
--- /dev/null
+++ b/etc/project-templates/make/make
@@ -0,0 +1 @@
+TODO:
diff --git a/etc/project-templates/make/project-template-info b/etc/project-templates/make/project-template-info
new file mode 100644
index 00000000000..2becad17311
--- /dev/null
+++ b/etc/project-templates/make/project-template-info
@@ -0,0 +1,3 @@
+;;; -*- lisp-data -*-
+;;; This file contains project type to use in project-templates.
+(:type "Make")
diff --git a/lisp/progmodes/project-templates.el b/lisp/progmodes/project-templates.el
new file mode 100644
index 00000000000..79338670ead
--- /dev/null
+++ b/lisp/progmodes/project-templates.el
@@ -0,0 +1,110 @@
+;;; project-templates.el --- Create projects with templates  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2025 Free Software Foundation, Inc.
+;; Version: 0.1.0
+;; Package-Requires: ((emacs "26.1") (project "0.11.1"))
+
+;; Author: Elijah Gabe Pérez <[email-masked]>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This file allow to create projects based in directory templates, also
+;; offers integration with project.el for indexing the projects created.
+;;
+;; New project templates are created in this way:
+;; ├── DIRECTORY_WHERE_TEMPLATES_LIVE
+;; │ ├── PROJECT_TYPE_TEMPLATE_DIR
+;; │ │ ├── PROJECT_FILE...
+;; │ │ ├── PROJECT_FILE_2...
+;; │ │ └── `project-template-info'
+;; │ ├── ANOTHER_PROJECT_TYPE_TEMPLATE_DIR
+;; │ │ ├── ANOTHER_PROJECT_FILE...
+;; │ │ ├── ANOTHER_PROJECT_FILE_2...
+;; │ │ └── `project-template-info'
+;; Create a new sub-directory in `project-user-templates-directory' path
+;; and inserting there all the directories and files needed for the project.
+;; It's needed to create a file named: `project-template-info' inside
+;; project template directory which should contain the project type.
+;; That file will not be included in the created project.
+
+;;; Code:
+
+(defgroup project-templates nil
+  "Create project templates."
+  :version "30.1"
+  :group 'tools)
+
+(defcustom project-user-templates-directory (expand-file-name "project-templates" user-emacs-directory)
+  "User directory where the project templates are stored."
+  :type 'directory
+  :group 'project-templates
+  :version "30.1")
+
+(defconst project-template-default-dir (expand-file-name "project-templates" "../../etc")
+  "Default directory where project templates are stored.")
+
+(defconst project-template--info-file "project-template-info"
+  "File used to store project template information.")
+
+(defun project-templates--get-subdirectories (dir)
+  "Return all sub-directories in DIR as a list."
+  (if (file-directory-p dir)
+      (let ((dirs (file-name-as-directory dir)))
+        (seq-filter #'file-directory-p
+                    (directory-files dirs t "^[^.]")))))
+
+(defun project-templates--get-project-type (dir)
+  "Return project type in DIR as a list."
+  ;; Search in current directory DIR for project-template--info-file
+  ;; and it's information
+  (if-let* ((file (locate-file project-template--info-file `(,dir))))
+      (with-temp-buffer
+        (insert-file-contents file)
+        (read (current-buffer)))))
+
+;; TODO: Add project `project-templates-create-new-project' to menu-bar-project-menu
+(defun project-templates-create-new-project ()
+  (interactive)
+  "Create a new project from a template."
+  (let* ((subdirs (append (project-templates--get-subdirectories
+                           project-template-default-dir)
+                          (project-templates--get-subdirectories
+                           project-user-templates-directory)))
+         ;; DIR is used to know where is the path for the selected
+         ;; project type.
+         (projs-data (mapcar (lambda (dir)
+                               (append (project-templates--get-project-type dir)
+                                       `(:dir ,dir)))
+                             subdirs))
+         (types (flatten-list (mapcar (lambda (data) (plist-get data :type)) projs-data)))
+         (choice (completing-read "Select Project type: " types nil t))
+         (proj-name (read-string "Insert Project name: "))
+         (vc (completing-read "Which VC backend should new project use (default: None): "
+                              (append vc-handled-backends '(None))
+                              nil t nil nil "None"))
+         (index-p (yes-or-no-p "Should project be indexed in your project list"))
+         (create-dir (read-directory-name "Create to: ")))
+    ;; TEMP:
+    (print projs-data)
+    (print types)
+    (print choice)
+    ;; path to chosen project type template
+    (print (plist-get (cdr (alist-get :type projs-data)) :dir))))
+
+(provide 'project-templates)
+;;; project-templates.el ends here
-- 
2.49.0

-- 
                                          - E.G via GNU Emacs and Org.