From a9304e6451c0ccf9552583bd33c1c75fd70f9f70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Madeleine=20Sydney=20=C5=9Alaga?= Date: Mon, 8 Sep 2025 12:04:30 -0600 Subject: [PATCH] feat(emacs): project --- .../home/users/crumb/emacs/lib/syd-project.el | 1 - modules/home/users/msyds/emacs/init.el | 4 +- .../users/msyds/emacs/lisp/syd/project.el | 92 +++++++++++++++++++ 3 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 modules/home/users/msyds/emacs/lisp/syd/project.el diff --git a/modules/home/users/crumb/emacs/lib/syd-project.el b/modules/home/users/crumb/emacs/lib/syd-project.el index 77bf8c0..8d82ea4 100644 --- a/modules/home/users/crumb/emacs/lib/syd-project.el +++ b/modules/home/users/crumb/emacs/lib/syd-project.el @@ -31,7 +31,6 @@ project\"." (defun syd-project-search () (interactive) - (require 'syd-file) ;; TODO: Prompt for path project root is not found. ;; TODO: Respect gitignore. (syd-search-directory (syd-project-root))) diff --git a/modules/home/users/msyds/emacs/init.el b/modules/home/users/msyds/emacs/init.el index 4cb5535..e1d162b 100644 --- a/modules/home/users/msyds/emacs/init.el +++ b/modules/home/users/msyds/emacs/init.el @@ -42,7 +42,9 @@ syd/smartparens syd/snippets syd/ptemplate - syd/popups)) + syd/popups + syd/pdf + syd/project)) (defun syd-random-permutation (lst &optional seed) "Return a random permutation of list LST using SEED as the random state. The diff --git a/modules/home/users/msyds/emacs/lisp/syd/project.el b/modules/home/users/msyds/emacs/lisp/syd/project.el new file mode 100644 index 0000000..747bc69 --- /dev/null +++ b/modules/home/users/msyds/emacs/lisp/syd/project.el @@ -0,0 +1,92 @@ +;;; -*- lexical-binding: t; -*- + +(require 'syd/base) +(require 'syd/completion) ; For `consult'. +(require 'consult) + +(defun syd-project-root-find-file (file-name) + "Just like `project-root-find-file', but allowing you to select the root +directory itself." + (declare (interactive-only find-file)) + (interactive + (list (let ((root (project-root (project-current t)))) + (read-file-name + "Find file in root: " + root root (confirm-nonexistent-file-or-buffer))))) + (find-file file-name t)) + +(defun syd-search-directory (dir) + (interactive (list (read-directory-name + "Search directory: " + default-directory nil t))) + (cond ((executable-find "rg") + (consult-ripgrep dir)) + ((executable-find "grep") + (message "Couldn't find ripgrep; using grep") + (consult-grep dir)))) + +(cl-defun syd-project-root (&key (dir default-directory)) + "Return the project root of DIR, or nil if DIR belongs to no project." + (when-let* ((project (project-current nil dir))) + (project-root project))) + +(defun syd-project-cd () + "Change the working directory to the root of the current project." + (cd (syd-project-root))) + +(defun syd-project-search () + (interactive) + (require 'syd-file) + ;; TODO: Prompt for path project root is not found. + ;; TODO: Respect gitignore. + (syd-search-directory (syd-project-root))) + +(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")))) + +;; 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 ("src/projection-multi/*.el")) + :general (:keymaps 'syd-leader-project-map + "M" #'projection-multi-compile) + :after projection) + +(provide 'syd/project)