Files
sydnix/modules/home/users/crumb/emacs/modules/syd-projects.el
2025-05-21 13:14:58 -06:00

112 lines
4.6 KiB
EmacsLisp
Executable File

;;; syd-projects.el -*- lexical-binding: t; -*-
(require 'syd-constants)
(with-eval-after-load 'project ; Built-in
;; Stay out of my config directory!
(setq project-list-file (file-name-concat syd-cache-dir "known-projects"))
;; For each command in `project-switch-commands' will assign it the key found
;; in `project-prefix-map'. We emulate that behaviour but for our own
;; `syd-leader-project-map'.
(let* ((project-key
(lambda (f)
(key-description
(where-is-internal
f
;; If the keymap is not wrapped in a list,
;; `where-is-internal' will also search the
;; global ;; keymaps
(list syd-leader-project-map)
;; First result only.
t))))
(switch-cmd (lambda (command name &optional key)
(append (list command name)
(list (or key (funcall project-key command)))))))
(add-to-list 'project-switch-commands
(funcall switch-cmd #'syd-project-root-find-file "Browse"))))
(defun syd-project-checkout (repo-uri)
(interactive (list (read-string "Repo: ")))
(let* ((repo-name
(when (string-match (rx "/" (group-n 1 (+ (any alphanumeric "-_")))
(? ".git") eol)
repo-uri)
(match-string 1 repo-uri)))
(dest (file-name-concat (expand-file-name "~/git") repo-name)))
(shell-command (format "git clone %s %s" repo-uri dest))
(find-file dest)))
;; Projection provides a Projectile-like project management library atop
;; Emacs built-in project.el. It's more lightweight, while still featureful.
(use-package projection
:straight (:type git
:host github
:repo "msyds/projection"
:files (:defaults "src/*.el"))
;; Enable the `projection-hook' feature.
:hook (after-init . global-projection-hook-mode)
:general (:keymaps 'syd-leader-project-map
"R" #'projection-commands-run-project
"M" #'projection-multi-compile
"T" #'projection-commands-test-project))
;; Allow interactively selecting available compilation targets from the
;; current project type.
(use-package projection-multi
:straight (:type git
:host github
:repo "msyds/projection"
:files (:defaults "src/projection-multi/*.el"))
:general (:keymaps 'syd-leader-project-map
"M" #'projection-multi-compile)
:after projection
:config
(require 'projection-multi-bb)
(setq projection-multi-bb-executable (executable-find "bb")))
;; ;; Embark integration for projection-multi.
;; (use-package projection-multi-embark
;; :after (embark projection-multi)
;; ;; Add the projection set-command bindings to
;; ;; `compile-multi-embark-command-map'.
;; :config (projection-multi-embark-setup-command-map))
(use-package skeletor
:commands (skeletor-create-project-at skeletor-create-project)
:custom ((skeletor-project-directory (expand-file-name "~/src"))
(skeletor-completing-read-function #'completing-read))
:general (:keymaps 'syd-leader-project-map
"n" #'skeletor-create-project
"N" #'skeletor-create-project-at)
:config
;; TODO: Fix the `ns' form in Clojure files.
(defun syd-fix-clojure-file-name! (file-name)
(let ((new-file-name (->> file-name
(string-replace "-" "_")
;; NOTE: Will cause fuckiness if file-name starts
;; with a dot.
(string-replace "." "/"))))
(make-directory (file-name-directory new-file-name) t)
(rename-file file-name new-file-name)))
(defun syd-fix-clojure-file-names! (directory)
(let ((default-directory (file-name-concat directory "src")))
(dolist (file-name (directory-files "." nil "-" t))
(syd-fix-clojure-file-name! file-name))))
(skeletor-define-template "clj-nix"
:substitutions
'(("__PROJECT-OWNER__" . (lambda ()
(read-no-blanks-input "Project owner: "))))
:before-git
(lambda (dir)
;; Use underscores instead of hyphens in clj file names.
(syd-fix-clojure-file-names! dir)
;; REVIEW: Is it safe to make this be async? We require that the command
;; has finished before Git initialises.
(skeletor-shell-command "nix run github:jlesquembre/clj-nix#deps-lock"
dir)))
(skeletor-define-template "haskell-flake"
:title "Haskell (Flake)"
:license-file-name "LICENSE"))
(provide 'syd-projects)