dotfiles/.emacs.d/lisp/init-project.el

61 lines
2.7 KiB
EmacsLisp

;;; 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