aboutsummaryrefslogtreecommitdiff
path: root/projectile.el
diff options
context:
space:
mode:
authorBozhidar Batsov <bozhidar@toptal.com>2026-04-25 22:50:36 +0100
committerBozhidar Batsov <bozhidar@toptal.com>2026-04-25 22:50:36 +0100
commita8a90311044f240f9b1d4789a32d5144f8d955ec (patch)
tree30513d86b30bb72a405713fdb7c8969ab8568482 /projectile.el
parent82fd4a5d3ab97cf5a8fdf65c38a68995ec1b3ef1 (diff)
Warn when a + keep entry contains glob metacharactersdirconfig-improvements
The parser silently turns every keep entry into a directory via file-name-as-directory, which means a user-typed +*.json or +/foo.txt becomes "*.json/" or "foo.txt/" and quietly never matches anything. Spot the obvious misuses (anything containing *, ?, or [) at parse time and emit a warning so the user can correct the file or move the pattern to an ignore/ensure rule.
Diffstat (limited to 'projectile.el')
-rw-r--r--projectile.el27
1 files changed, 21 insertions, 6 deletions
diff --git a/projectile.el b/projectile.el
index 7d7d745..7f2b754 100644
--- a/projectile.el
+++ b/projectile.el
@@ -2176,6 +2176,18 @@ Unignored files/directories are not included."
"Return the absolute path to the project's dirconfig file."
(expand-file-name projectile-dirconfig-file (projectile-project-root)))
+(defun projectile--warn-glob-in-keep-entry (entry dirconfig)
+ "Warn that ENTRY in DIRCONFIG looks like a glob pattern after a `+'.
+The `+' prefix is for subdirectories only; the parser silently coerces
+each entry to a directory, so a glob pattern would never match."
+ (display-warning
+ 'projectile
+ (format "%s contains `+%s', but `+' entries are treated as \
+subdirectory paths and globs are not expanded. Use a plain directory \
+or move the pattern to a `-'/`!' rule."
+ dirconfig entry)
+ :warning))
+
(defun projectile--parse-dirconfig-file-uncached ()
"Parse the dirconfig file without caching.
Returns a list of (KEEP IGNORE ENSURE) or nil if the file doesn't exist."
@@ -2200,12 +2212,15 @@ Returns a list of (KEEP IGNORE ENSURE) or nil if the file doesn't exist."
(?! (push (buffer-substring (1+ (point)) (line-end-position)) ensure))
(_ (push (buffer-substring (point) (line-end-position)) ignore)))
(forward-line)))
- (list (mapcar (lambda (f) (file-name-as-directory (string-trim f)))
- (delete "" (reverse keep)))
- (mapcar #'string-trim
- (delete "" (reverse ignore)))
- (mapcar #'string-trim
- (delete "" (reverse ensure)))))))
+ (let ((trimmed-keep (mapcar #'string-trim (delete "" (reverse keep)))))
+ (dolist (entry trimmed-keep)
+ (when (string-match-p "[*?[]" entry)
+ (projectile--warn-glob-in-keep-entry entry dirconfig)))
+ (list (mapcar #'file-name-as-directory trimmed-keep)
+ (mapcar #'string-trim
+ (delete "" (reverse ignore)))
+ (mapcar #'string-trim
+ (delete "" (reverse ensure))))))))
(defun projectile-parse-dirconfig-file ()
"Parse project ignore file and return directories to ignore and keep.