diff options
| author | Bozhidar Batsov <bozhidar@toptal.com> | 2026-04-25 23:27:44 +0100 |
|---|---|---|
| committer | Bozhidar Batsov <bozhidar@toptal.com> | 2026-04-25 23:27:44 +0100 |
| commit | 0dc5b507231e8ad53a0ce925471111dda89cff4d (patch) | |
| tree | caaf56cafe993b33d60a7ee4d4103e07a2cda6d3 | |
| parent | 31a5723acce2c4f31b77aaa611c3fe7c47387b93 (diff) | |
Include dirconfig path in the parse-cache hit check
The cache value used to be (MTIME . PARSED-RESULT) keyed on the
project root. If the user changed `projectile-dirconfig-file' to
point at a different file mid-session, the old entry kept getting
returned because the key didn't depend on the path. Store the path
alongside the mtime in the cached value and compare both before
considering a hit. The hash key remains the project root so
`projectile-invalidate-cache' continues to work as-is.
| -rw-r--r-- | projectile.el | 13 | ||||
| -rw-r--r-- | test/projectile-test.el | 18 |
2 files changed, 26 insertions, 5 deletions
diff --git a/projectile.el b/projectile.el index c75ec11..a7c505d 100644 --- a/projectile.el +++ b/projectile.el @@ -673,7 +673,10 @@ project." (defvar projectile--dirconfig-cache (make-hash-table :test 'equal) "Cache for parsed dirconfig files, keyed by project root. -Each value is a cons of (MTIME . PARSED-RESULT).") +Each value is a list of (DIRCONFIG-PATH MTIME PARSED-RESULT); a +cache hit requires both DIRCONFIG-PATH and MTIME to match the +current file, so changing `projectile-dirconfig-file' mid-session +naturally invalidates the entry.") (defvar projectile--alien-dirconfig-warned-projects (make-hash-table :test 'equal) "Set of project roots already warned about alien indexing skipping the dirconfig.") @@ -2335,12 +2338,14 @@ dirconfig file's modification time changes." (cached (gethash project-root projectile--dirconfig-cache)) (attrs (file-attributes dirconfig)) (mtime (when attrs (file-attribute-modification-time attrs))) - (result (if (and cached mtime (equal (car cached) mtime)) - (cdr cached) + (result (if (and cached mtime + (equal (nth 0 cached) dirconfig) + (equal (nth 1 cached) mtime)) + (nth 2 cached) (let ((parsed (projectile--parse-dirconfig-file-uncached))) (when mtime (puthash project-root - (cons mtime parsed) + (list dirconfig mtime parsed) projectile--dirconfig-cache)) parsed)))) (projectile--maybe-warn-prefixless-entries project-root result) diff --git a/test/projectile-test.el b/test/projectile-test.el index 4faf8ae..b62224a 100644 --- a/test/projectile-test.el +++ b/test/projectile-test.el @@ -746,7 +746,23 @@ Just delegates OPERATION and ARGS for all operations except for`shell-command`'. (projectile-parse-dirconfig-file) (expect (gethash root projectile--dirconfig-cache) :not :to-be nil) (projectile-invalidate-cache nil) - (expect (gethash root projectile--dirconfig-cache) :to-be nil)))))) + (expect (gethash root projectile--dirconfig-cache) :to-be nil))))) + (it "re-parses when projectile-dirconfig-file points to a different file" + (projectile-test-with-sandbox + (projectile-test-with-files + ("project/") + (let ((root (file-truename (expand-file-name "project/")))) + (with-temp-file (expand-file-name ".projectile" root) + (insert "-foo\n")) + (with-temp-file (expand-file-name ".projectile-alt" root) + (insert "-bar\n")) + (spy-on 'projectile-project-root :and-return-value root) + (let ((projectile-dirconfig-file ".projectile")) + (expect (projectile-dirconfig-ignore (projectile-parse-dirconfig-file)) + :to-equal '("foo"))) + (let ((projectile-dirconfig-file ".projectile-alt")) + (expect (projectile-dirconfig-ignore (projectile-parse-dirconfig-file)) + :to-equal '("bar")))))))) (describe "prefix-less dirconfig warning" (before-each |
