about summary refs log tree commit diff
diff options
context:
space:
mode:
authorWilliam Carroll <wpcarro@gmail.com>2020-08-13T17·05+0100
committerWilliam Carroll <wpcarro@gmail.com>2020-08-13T17·05+0100
commitde723c142b31afe6061fca243917dee88cc6c625 (patch)
tree3fc04e38d9fcac0dc5700bdbf342ee8af5a03aa2
parent994a632ac379fcac0637baa0e1e00e4a091d7cbe (diff)
Prefer project.el to projectile
Today @tazjin told me about Emacs's built-in project.el library, which he
recommended that I extend to support monorepo-specific tooling. It worked like a
charm!

Now when I press "<leader>f", it will resolve to either the nearest file named
default.nix or directory name .git.
-rw-r--r--emacs/.emacs.d/wpc/wpc-keybindings.el2
-rw-r--r--emacs/.emacs.d/wpc/wpc-misc.el41
2 files changed, 42 insertions, 1 deletions
diff --git a/emacs/.emacs.d/wpc/wpc-keybindings.el b/emacs/.emacs.d/wpc/wpc-keybindings.el
index 7d6e57db2530..a66906dc6a3f 100644
--- a/emacs/.emacs.d/wpc/wpc-keybindings.el
+++ b/emacs/.emacs.d/wpc/wpc-keybindings.el
@@ -108,7 +108,7 @@
  "S" #'sort-lines
  "=" #'align
  "p" #'flycheck-previous-error
- "f" #'wpc/find-file
+ "f" #'project-find-file
  "n" #'flycheck-next-error
  "N" #'smerge-next
  "W" #'balance-windows
diff --git a/emacs/.emacs.d/wpc/wpc-misc.el b/emacs/.emacs.d/wpc/wpc-misc.el
index b73977ce9119..c10f8d5d1ce2 100644
--- a/emacs/.emacs.d/wpc/wpc-misc.el
+++ b/emacs/.emacs.d/wpc/wpc-misc.el
@@ -6,6 +6,18 @@
 
 ;;; Code:
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Dependencies
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(require 'project)
+(require 'f)
+(require 'dash)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Configuration
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
 ;; I'm borrowing from the dot-time format (i.e. https://dotti.me) to encode the
 ;; timestamp. This displays the UTC time and an offset to show the number of
 ;; hours East or West of UTC my current timezone is using `current-time-zone'.
@@ -186,6 +198,35 @@
   :config
   (projectile-mode t))
 
+(defun project-find-function--briefcase (dir)
+  "Find the nearest default.nix file; otherwise, terminate at the .git
+  directory."
+  (let ((filenames (->> dir f-files (-map #'f-filename)))
+        (dirnames (->> dir f-directories (-map #'f-dirname))))
+    (if (or (-contains? filenames "default.nix")
+            (-contains? dirnames ".git"))
+        (cons 'monorepo dir)
+      (if (f-parent dir)
+          (project-find-function--briefcase (f-parent dir))
+        nil))))
+
+(cl-defmethod project-root ((project (head monorepo)))
+  (cdr project))
+
+(cl-defmethod project-roots ((project (head monorepo)))
+  (list (cdr project)))
+
+(cl-defmethod project-external-roots ((project (head monorepo)))
+  (project-external-roots (cons 'vc (cdr project))))
+
+(cl-defmethod project-ignores ((project (head monorepo)) dir)
+  (project-ignores (cons 'vc (cdr project)) dir))
+
+(cl-defmethod project-files ((project (head monorepo)) &optional dirs)
+  (project-files (cons 'vc (cdr project)) dirs))
+
+(setq project-find-functions (list #'project-find-function--briefcase))
+
 (use-package deadgrep
   :config
   (general-define-key