diff --git a/CHANGELOG.md b/CHANGELOG.md index 096128f29..bd1b060b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## master (unreleased) +### New features + +* [#1591](https://github.com/bbatsov/projectile/issues/1591): Add `project.el` integration that will make Projectile the default provider for project lookup. + ## 2.6.0 (2022-10-25) ### New features diff --git a/doc/modules/ROOT/pages/usage.adoc b/doc/modules/ROOT/pages/usage.adoc index ac1b8e683..4178f956e 100644 --- a/doc/modules/ROOT/pages/usage.adoc +++ b/doc/modules/ROOT/pages/usage.adoc @@ -379,3 +379,17 @@ You can add additional commands to the commander like this: ---- Place such snippets after ``projectile-mode``'s init code. + +== Using Projectile with project.el + +Starting with version 2.7 Projectile bundles some integration with +`project.el` that makes `project.el` use by default Projectile's +project lookup function (`projectile-project-root`) and project file +lookup function (`projectile-project-files`). + +That's useful as some packages (e.g. `eglot`) support natively only +`project.el`'s API for project discovery. Fortunately, `project.el` +makes it easy to install additional project lookup functions and that's +exactly what Projectile does. + +TIP: You can read more about the integration https://github.com/bbatsov/projectile/issues/1591[here]. diff --git a/projectile.el b/projectile.el index 80a5dd602..8f36c013c 100644 --- a/projectile.el +++ b/projectile.el @@ -5987,6 +5987,38 @@ Otherwise behave as if called interactively. ;;;###autoload (define-obsolete-function-alias 'projectile-global-mode 'projectile-mode "1.0") +;;;; project.el integration +;; +;; Projectile will become the default provider for +;; project.el project and project files lookup. +;; See https://github.com/bbatsov/projectile/issues/1591 for +;; more details. + +;; it's safe to require this directly, as it was added in Emacs 25.1 +(require 'project) + +(cl-defmethod project-root ((project (head projectile))) + (cdr project)) + +(cl-defmethod project-files ((project (head projectile)) &optional dirs) + (let ((root (project-root project))) + ;; Make paths absolute and ignore the optional dirs argument, + ;; see https://github.com/bbatsov/projectile/issues/1591#issuecomment-896423965 + ;; That's needed because Projectile uses relative paths for project files + ;; and project.el expects them to be absolute. + ;; FIXME: That's probably going to be very slow in large projects. + (mapcar (lambda (f) + (concat f root)) + (projectile-project-files root)))) + +(defun project-projectile (dir) + "Return Projectile project of form ('projectile . root-dir) for DIR." + (let ((root (projectile-project-root dir))) + (when root + (cons 'projectile root)))) + +(add-hook 'project-find-functions #'project-projectile) + (provide 'projectile) ;;; projectile.el ends here