about summary refs log tree commit diff stats
path: root/.emacs.d/lisp/init-project.el
diff options
context:
space:
mode:
Diffstat (limited to '.emacs.d/lisp/init-project.el')
-rw-r--r--.emacs.d/lisp/init-project.el60
1 files changed, 60 insertions, 0 deletions
diff --git a/.emacs.d/lisp/init-project.el b/.emacs.d/lisp/init-project.el
new file mode 100644
index 0000000..63aec7d
--- /dev/null
+++ b/.emacs.d/lisp/init-project.el
@@ -0,0 +1,60 @@
+;;; init-project.el --- Project (and Perspective) Configuration File -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+(use-package project
+  :ensure nil
+  :config
+  (defun project-recentf ()
+    "Show a list of recently visited files in a project."
+    (interactive)
+    (if (boundp 'recentf-list)
+        (let* ((project-root (expand-file-name (project-root (project-current))))
+               (project-recentf-files (mapcar
+                                       (lambda (f) (file-relative-name f project-root))
+                                       (seq-filter (apply-partially 'string-prefix-p project-root) recentf-list))))
+          (find-file (expand-file-name
+                      (funcall project-read-file-name-function
+                               "Find recent project files"
+                               project-recentf-files nil 'file-name-history nil)
+                      project-root)))
+      (message "recentf is not enabled")))
+
+  (add-to-list 'project-switch-commands '(?h "Recentf" project-recentf) t)
+  (add-to-list 'project-switch-commands '(?b "Consult Project Buffer" consult-project-buffer) t)
+  (add-to-list 'project-switch-commands '(?r "Consult Ripgrep" consult-ripgrep) t)
+  (add-to-list 'project-switch-commands '(?m "Magit" magit-status) t)
+  (add-to-list 'project-switch-commands '(?R "Replace Regexp" project-query-replace-regexp) t)
+
+  ;; project-root and project-try-local copied/modified from https://github.com/karthink/project-x/blob/master/project-x.el
+  (cl-defmethod project-root ((project (head local)))
+    "Return root directory of current PROJECT."
+    (cdr project))
+  (defun project-try-local (dir)
+    "Treat DIR as a project if it contains a .project file."
+    (if-let ((root (locate-dominating-file dir ".project")))
+        (cons 'local root)))
+  ;; Add this hook last so so that vc takes precedence over local
+  (add-hook 'project-find-functions 'project-try-local 90)
+  :bind
+  ("C-x p P" . project-switch-project)
+  ("C-x f" . project-recentf))
+
+(use-package perspective
+  :config (persp-mode)
+  (defun switch-project (proj)
+    "Switch to project or already open project perspective."
+    (interactive (list (project-prompt-project-dir)))
+    (let* ((persp-name (file-name-nondirectory (directory-file-name proj)))
+           (persp (gethash persp-name (perspectives-hash))))
+      (unless (equal persp (persp-curr))
+        ;; Create or switch to a perspective named after the project
+        (persp-switch persp-name)
+        ;; If the perspective did not exist, switch to the project
+        (when (not persp)
+          (project-switch-project proj)))))
+  :bind
+  ("C-x p p" . switch-project))
+
+(provide 'init-project)
+;;; init-project.el ends here