diff options
| author | Bozhidar Batsov <bozhidar@batsov.dev> | 2026-02-14 15:40:27 +0200 |
|---|---|---|
| committer | Bozhidar Batsov <bozhidar@batsov.dev> | 2026-02-14 15:40:27 +0200 |
| commit | 83ee3f34b630b06f3bcd58f519dea203f8925012 (patch) | |
| tree | b17132099441096592decf5e500e23abf369e9e1 /projectile.el | |
| parent | 073d72120acba3de05184f747630bf7a3641a049 (diff) | |
Fix projectile-root-top-down to search top-down, not bottom-up (#1729)
projectile-root-top-down used projectile-locate-dominating-file which
stops at the first (bottommost) match going up the directory tree.
This made it behave identically to projectile-root-bottom-up.
Add projectile-locate-dominating-file-top-down which walks the entire
directory hierarchy and returns the topmost match. For example, with
nested Makefiles at both project/ and project/subdir/, searching from
project/subdir/ now correctly returns project/ instead of
project/subdir/.
Diffstat (limited to 'projectile.el')
| -rw-r--r-- | projectile.el | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/projectile.el b/projectile.el index 407fade..0098b2c 100644 --- a/projectile.el +++ b/projectile.el @@ -1312,6 +1312,27 @@ which we're looking." (setq file nil)))) (and root (expand-file-name (file-name-as-directory root))))) +(defun projectile-locate-dominating-file-top-down (file name) + "Look up the directory hierarchy from FILE for a directory containing NAME. +Unlike `projectile-locate-dominating-file' which returns the first (bottommost) +match, this returns the topmost match. Return nil if not found. +Instead of a string, NAME can also be a predicate taking one argument +\(a directory) and returning a non-nil value if that directory is the one for +which we're looking." + (setq file (abbreviate-file-name file)) + (let ((root nil) + try) + (while (not (or (null file) + (string-match locate-dominating-stop-dir-regexp file))) + (setq try (if (stringp name) + (projectile-file-exists-p (projectile-expand-file-name-wildcard name file)) + (funcall name file))) + (when try (setq root file)) + (if (equal file (setq file (file-name-directory + (directory-file-name file)))) + (setq file nil))) + (and root (expand-file-name (file-name-as-directory root))))) + (defvar-local projectile-project-root nil "Defines a custom Projectile project root. This is intended to be used as a file local variable.") @@ -1324,7 +1345,7 @@ This is intended to be used as a file local variable.") "Identify a project root in DIR by top-down search for files in LIST. If LIST is nil, use `projectile-project-root-files' instead. Return the first (topmost) matched directory or nil if not found." - (projectile-locate-dominating-file + (projectile-locate-dominating-file-top-down dir (lambda (dir) (cl-find-if (lambda (f) |
