51 lines
1.6 KiB
EmacsLisp
51 lines
1.6 KiB
EmacsLisp
;;; syd-project.el -*- lexical-binding: t; -*-
|
|
|
|
(eval-when-compile (require 'cl-lib))
|
|
(require 'project)
|
|
|
|
(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)))
|
|
|
|
(define-obsolete-function-alias 'syd-cd-project 'syd-project-cd
|
|
"2025-02-20")
|
|
|
|
(defmacro syd-with-project-root (root &rest body)
|
|
"Execute BODY with ROOT recognised as what project.el calls a \"transient
|
|
project\"."
|
|
(declare (indent defun))
|
|
(let ((root* (gensym "root"))
|
|
(forget-after-p (gensym "forget-after-p")))
|
|
`(let* ((,root* ,root)
|
|
(,forget-after-p
|
|
(not (member ,root* (project-known-project-roots)))))
|
|
(let ((project-find-functions (lambda (_) (cons 'transient ,root*))))
|
|
,@body)
|
|
(when ,forget-after-p
|
|
(project-forget-project ,root*)))))
|
|
|
|
(defun syd-project-search ()
|
|
(interactive)
|
|
(require 'syd-file)
|
|
;; TODO: Prompt for path project root is not found.
|
|
(syd-search-directory (syd-project-root)))
|
|
|
|
(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))
|
|
|
|
(provide 'syd-project)
|
|
;;; syd-project.el ends here
|