diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 57a961c260..8eee0c7d27 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -165,7 +165,7 @@ project :version "28.1" :group 'tools) -(defvar project-find-functions (list #'project-try-vc) +(defvar project-find-functions (list #'project-try-vc #'project-try-fallback) "Special hook to find the project containing a given directory. Each functions on this hook is called in turn with one argument, the directory in which to look, and should return @@ -662,6 +662,27 @@ project-buffers (push buf bufs))) (nreverse bufs))) +(defcustom project-fallback-markers '(".dir-locals.el") + "List of file name to use as fallback project root markers. + +Each entry should be a relative file name (no directory part). + +The fallback project backend detects a project as a directory +containing one of these files." + :type 'list) + +(defun project-try-fallback (dir) + (let ((root (locate-dominating-file dir #'project-fallback--root-p))) + (and root (cons 'fallback root)))) + +(defun project-fallback--root-p (dir) + (let ((default-directory dir)) + (seq-some (lambda (marker) (file-exists-p marker)) + project-fallback-markers))) + +(cl-defmethod project-root ((project (head fallback))) + (cdr project)) + ;;; Project commands