2018-06-16 11:42:37 +02:00
|
|
|
;;; core/autoload/projects.el -*- lexical-binding: t; -*-
|
|
|
|
|
2019-04-11 15:15:05 -04:00
|
|
|
(defvar projectile-project-root nil)
|
|
|
|
|
2019-03-02 01:08:56 -05:00
|
|
|
;;;###autoload
|
|
|
|
(autoload 'projectile-relevant-known-projects "projectile")
|
|
|
|
|
|
|
|
|
2018-06-16 11:42:37 +02:00
|
|
|
;;
|
|
|
|
;; Macros
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defmacro without-project-cache! (&rest body)
|
|
|
|
"Run BODY with projectile's project-root cache disabled. This is necessary if
|
|
|
|
you want to interactive with a project other than the one you're in."
|
2018-09-22 12:42:38 -04:00
|
|
|
`(let ((projectile-project-root-cache (make-hash-table :test 'equal))
|
|
|
|
projectile-project-name
|
2019-04-09 03:13:18 -04:00
|
|
|
projectile-project-root
|
2018-09-22 12:42:38 -04:00
|
|
|
projectile-require-project-root)
|
2018-06-16 11:42:37 +02:00
|
|
|
,@body))
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defmacro project-file-exists-p! (files)
|
|
|
|
"Checks if the project has the specified FILES.
|
|
|
|
Paths are relative to the project root, unless they start with ./ or ../ (in
|
|
|
|
which case they're relative to `default-directory'). If they start with a slash,
|
|
|
|
they are absolute."
|
|
|
|
`(file-exists-p! ,files (doom-project-root)))
|
|
|
|
|
|
|
|
|
|
|
|
;;
|
|
|
|
;; Commands
|
|
|
|
|
2019-02-26 13:21:16 -05:00
|
|
|
;;;###autoload
|
|
|
|
(defun doom/find-file-in-other-project (project-root)
|
|
|
|
"Preforms `projectile-find-file' in a known project of your choosing."
|
|
|
|
(interactive
|
|
|
|
(list
|
|
|
|
(completing-read "Find file in project: " (projectile-relevant-known-projects)
|
|
|
|
nil nil nil nil (doom-project-root))))
|
|
|
|
(unless (file-directory-p project-root)
|
|
|
|
(error "Project directory '%s' doesn't exist" project-root))
|
|
|
|
(doom-project-find-file project-root))
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defun doom/browse-in-other-project (project-root)
|
|
|
|
"Preforms `find-file' in a known project of your choosing."
|
|
|
|
(interactive
|
|
|
|
(list
|
|
|
|
(completing-read "Browse in project: " (projectile-relevant-known-projects)
|
|
|
|
nil nil nil nil (doom-project-root))))
|
|
|
|
(unless (file-directory-p project-root)
|
|
|
|
(error "Project directory '%s' doesn't exist" project-root))
|
|
|
|
(doom-project-browse project-root))
|
|
|
|
|
2018-06-16 11:42:37 +02:00
|
|
|
|
|
|
|
;;
|
|
|
|
;; Library
|
|
|
|
|
|
|
|
;;;###autoload
|
2019-04-09 03:13:18 -04:00
|
|
|
(defun doom-project-p (&optional dir)
|
|
|
|
"Return t if DIR (defaults to `default-directory') is a valid project."
|
|
|
|
(and (doom-project-root dir)
|
|
|
|
t))
|
2018-06-16 11:42:37 +02:00
|
|
|
|
|
|
|
;;;###autoload
|
2019-04-09 03:13:18 -04:00
|
|
|
(defun doom-project-root (&optional dir)
|
|
|
|
"Return the project root of DIR (defaults to `default-directory').
|
|
|
|
Returns nil if not in a project."
|
|
|
|
(let ((projectile-project-root (unless dir projectile-project-root))
|
|
|
|
projectile-require-project-root)
|
|
|
|
(projectile-project-root dir)))
|
2018-06-16 11:42:37 +02:00
|
|
|
|
|
|
|
;;;###autoload
|
2018-09-28 13:54:20 -04:00
|
|
|
(defun doom-project-name (&optional dir)
|
2019-04-09 03:13:18 -04:00
|
|
|
"Return the name of the current project.
|
|
|
|
|
|
|
|
Returns '-' if not in a valid project."
|
|
|
|
(if-let* ((project-root (or (doom-project-root dir)
|
|
|
|
(if dir (expand-file-name dir)))))
|
|
|
|
(funcall projectile-project-name-function project-root)
|
|
|
|
"-"))
|
2018-06-16 11:42:37 +02:00
|
|
|
|
|
|
|
;;;###autoload
|
2018-09-28 13:54:20 -04:00
|
|
|
(defun doom-project-expand (name &optional dir)
|
|
|
|
"Expand NAME to project root."
|
2019-04-09 03:13:18 -04:00
|
|
|
(expand-file-name name (doom-project-root dir)))
|
2018-06-16 11:42:37 +02:00
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defun doom-project-find-file (dir)
|
2019-03-28 15:07:14 -04:00
|
|
|
"Fuzzy-find a file under DIR.
|
|
|
|
|
|
|
|
Will resolve to the nearest project root above DIR. If no project can be found,
|
|
|
|
the search will be rooted from DIR."
|
2019-03-26 03:38:37 -04:00
|
|
|
(unless (file-directory-p dir)
|
|
|
|
(error "Directory %S does not exist" dir))
|
2019-04-09 03:13:18 -04:00
|
|
|
(let ((default-directory (file-truename (expand-file-name dir)))
|
|
|
|
(projectile-project-root
|
|
|
|
(or (doom-project-root dir)
|
|
|
|
default-directory)))
|
2019-03-26 03:38:37 -04:00
|
|
|
(call-interactively
|
|
|
|
;; Intentionally avoid `helm-projectile-find-file', because it runs
|
|
|
|
;; asynchronously, and thus doesn't see the lexical `default-directory'
|
|
|
|
(if (featurep! :completion ivy)
|
|
|
|
#'counsel-projectile-find-file
|
|
|
|
#'projectile-find-file))))
|
2018-06-16 11:42:37 +02:00
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defun doom-project-browse (dir)
|
|
|
|
"Traverse a file structure starting linearly from DIR."
|
2019-03-28 18:29:50 -04:00
|
|
|
(let ((default-directory (file-truename (expand-file-name dir))))
|
2018-06-16 11:42:37 +02:00
|
|
|
(call-interactively
|
2019-03-26 03:38:37 -04:00
|
|
|
(cond ((featurep! :completion ivy)
|
|
|
|
#'counsel-find-file)
|
|
|
|
((featurep! :completion helm)
|
|
|
|
#'helm-find-files)
|
|
|
|
(#'find-file)))))
|