;;; .ptemplate.el --- Emacs package template -*- lexical-binding: t -+-

;;; Commentary:

;; This template generates a project for a Haskell library using Cabal, Direnv,
;; a Nix flake, and a dev-shell via shellFor.

;;; Code:

(require 'ptemplate)
(require 'syd/ptemplate)
(require 'dash)

(defun syd-kebab-to-pascal-case (str)
  (-as-> str it
         (string-split it "-")
         (-map (lambda (x) ; Capitalise first character.
                 (let ((head (substring x 0 1))
                       (tail (substring x 1)))
                   (concat (upcase head)
                           tail)))
               it)
         (apply #'concat it)))

(defun syd-read-haskell-module-list (&optional package-name)
  (-> (read-string "Space-separated modules: "
                   nil
                   nil
                   (-some-> package-name syd-kebab-to-pascal-case))
      (string-split " ")))

(defun syd-haskell-module-to-file (module-name)
  (concat (string-replace "." "/" module-name)
          ".hs"))

(ptemplate!
 :snippet-let
 (template:project-name (syd-ptemplate-project-name))
 (template:modules (syd-read-haskell-module-list template:project-name))
 ;; Default is `auto', which can be real finnicky on these large snippet files.
 (yas-indent-line 'fixed)
 :inherit-rel "../../-/version-controlled"
 :remap ("/package.cabal.yas" (concat template:project-name
                                      ".cabal"))
 :after-copy
 (dolist (module-name template:modules)
   (let ((file-name (syd-haskell-module-to-file module-name)))
     (mkdir (file-name-directory file-name) t)
     (with-current-buffer
         (find-file-noselect
          (file-name-concat file-name-concat "src" file-name))
       (insert (concat "module " module-name  "\n"
                       "  (\n"
                       "  ) where\n"
                       "\f\n"
                       "\f\n\n"))))))

;;; .ptemplate.el ends here
