aboutsummaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2026-04-25Small dirconfig cleanupsdirconfig-polishBozhidar Batsov
- projectile-get-project-directories: replace the (or keep '("")) trick with an explicit (if keep ... (list project-dir)). The behavior is unchanged but the empty-keep case no longer reads as a string-concat with the empty string. - projectile-dirconfig-file: expand the docstring to spell out the dual marker/config role — empty file is enough to mark a project, non-empty content drives parsing.
2026-04-25Include dirconfig path in the parse-cache hit checkBozhidar Batsov
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.
2026-04-25Fire the + glob keep warning once per projectBozhidar Batsov
The other two dirconfig warnings (alien-mode bypass and prefix-less entries) are gated by per-project hash sets so they fire at most once per Emacs session. The glob-keep warning was the odd one out — it lived inside the uncached parser and re-fired on every cache miss, and it emitted one display-warning per offending entry rather than a single consolidated message. Move it into the cached wrapper alongside the others, gate it on projectile--glob-keep-warned-projects, and roll multiple offending entries into one warning that lists them.
2026-04-26Merge pull request #1994 from bbatsov/dirconfig-refactorBozhidar Batsov
Refactor dirconfig parser: struct, pure classifier, deprecation warning
2026-04-25Soft-deprecate prefix-less dirconfig entriesdirconfig-refactorBozhidar Batsov
The implicit "any unprefixed line is an ignore pattern" rule is the last source of subtle parser surprises — it's the reason why a single leading space silently changes a +-keep into a literal ignore pattern, and it makes typo'd comments slip through as ignores. Mark these lines as :legacy-ignore in the classifier, record them in a new prefixless-ignore slot on the dirconfig struct, and emit a one-time warning per project listing the offending entries. The behavior is unchanged — the lines still go into the ignore list — but users now get a nudge to write them as -entry. The warning can be silenced via projectile-warn-on-prefixless-dirconfig-lines.
2026-04-25Split the dirconfig parser into a pure line classifierBozhidar Batsov
The old parser walked a temp buffer with point and pcase'd on char-after, mixing IO, prefix dispatch, and bucket bookkeeping into one function. Pull the dispatch out into projectile--dirconfig-classify-line, which takes a string and returns a (BUCKET . VALUE) tag. The pure function is unit-testable without buffer plumbing, the IO wrapper shrinks to a one-shot read + dispatch, and the awkward (pcase ((pred (lambda ...)) ...)) for the comment-prefix check becomes a straightforward cond. No behavior change.
2026-04-25Return a projectile-dirconfig struct from the parserBozhidar Batsov
Replace the positional (KEEP IGNORE ENSURE) triple with a cl-defstruct. Every internal call site used car/cadr/caddr to pull out a slot, which is unreadable and error-prone — slot accessors make the intent explicit and let cl-defstruct grow a fourth field later without touching every consumer. Existing callers that compared against the raw triple (a couple of internal helper tests) are updated to construct the struct with make-projectile-dirconfig.
2026-04-26Merge pull request #1993 from bbatsov/dirconfig-improvementsBozhidar Batsov
Improvements to .projectile (dirconfig) parsing and ergonomics
2026-04-25Warn when a + keep entry contains glob metacharactersdirconfig-improvementsBozhidar Batsov
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.
2026-04-25Add real-file integration tests for the dirconfig parserBozhidar Batsov
The existing parser tests stub insert-file-contents; nothing exercises the full IO path. Add three sandbox-based tests: a mixed +/-/!/no-prefix file, a non-ASCII round-trip, and a file with no trailing newline. These guard against IO-layer regressions that the stubbed tests can't see.
2026-04-25Warn when alien indexing bypasses a populated .projectileBozhidar Batsov
Under alien indexing the dirconfig file is silently ignored, which is the most common confusion in the issue tracker (#1322, #1075, #1534, #1941). Show a one-shot display-warning the first time we index a project where alien mode meets a non-empty .projectile. The new projectile-warn-when-dirconfig-is-ignored option lets users who already understand the trade-off silence the warning.
2026-04-25Document the dirconfig format more preciselyBozhidar Batsov
The parser docstring only described + and - prefixes even though the function returns a 3-tuple including the ! ensure bucket. Fill that in, and pull the path-vs-glob distinction out of the prose in projects.adoc into a subsection of its own — that ambiguity is at the root of recurring confusion (#740, #1109, #680, #1941).
2026-04-25Add tests for the dirconfig cacheBozhidar Batsov
The mtime-keyed cache around projectile-parse-dirconfig-file had no direct coverage. Cover the four invariants that matter: a cache hit on repeat calls, a re-parse when mtime advances, no caching of a nil result for a missing file, and entry removal via projectile-invalidate-cache (the path that previously crashed in #1854).
2026-04-25Skip leading whitespace in dirconfig prefix dispatchBozhidar Batsov
A user accidentally typing " -path/" or " # comment" in .projectile would have the line silently routed to the ignore bucket with the prefix character left intact, because the parser dispatched on the first character of the line without trimming. Skip leading spaces and tabs before the pcase so the +/-/! and comment-prefix markers are matched regardless of indentation. Reported in #1508.
2026-03-10Disambiguate process buffer names for same-named projectsBozhidar Batsov
Fixes #1815 Fixes #1715 When two projects share the same name (e.g. both named "src"), projectile-generate-process-name now detects the collision and falls back to using the abbreviated project path in the buffer name instead of just the project name.
2026-03-10Check globally-ignored-file-suffixes in native indexingBozhidar Batsov
Fixes #1959 projectile-ignored-file-p now checks projectile-globally-ignored-file-suffixes in addition to projectile-globally-ignored-files and file patterns. Previously the suffix check only happened in projectile-remove-ignored which is used by hybrid indexing but not native indexing.
2026-03-10Allow projectile-dired commands to prompt for a projectBozhidar Batsov
Closes #1684 With a prefix argument, projectile-dired, projectile-dired-other-window, and projectile-dired-other-frame now prompt for a known project to open in dired, rather than always using the current project.
2026-03-10Filter projectile-replace results through project ignore rulesBozhidar Batsov
Closes #1227 projectile-replace now intersects the files found by rg/ag/grep with the project's file list from projectile-dir-files, ensuring that files ignored via .projectile or other ignore rules are excluded from replacement. Previously the external search tool's results were used directly, which could include backup files and other ignored entries.
2026-03-10Add projectile-find-file-all to find files ignoring VCS rulesBozhidar Batsov
Closes #1001 Add a new command that lists all files under the project root using a generic file listing command (fd or find), bypassing .gitignore, .projectile, and other ignore mechanisms. This is useful when you need to find files that are normally excluded from the project.
2026-03-10test: add mercurial switch-project root regressionkovan
2026-03-05Fix compilation-find-file advice for dirs without direct filesBozhidar Batsov
Fixes #1923 When compilation output references a file via a relative path, the advice now also checks if the file exists relative to the project root and adds its parent directory to the search path. This handles the edge case where a directory only contains subdirectories (no files directly) and therefore was not included in the file-derived directory list from projectile-current-project-dirs.
2026-03-04Update CHANGELOG with round 4 codebase fixesBozhidar Batsov
2026-03-04Add tests for round 4 codebase fixesBozhidar Batsov
- Test projectile-ignored-project-p truename normalization - Test projectile-determine-find-tag-fn fallback behavior - Update projectile-files-via-ext-command test for empty string guard
2026-03-04Wrap add-dir-local-variable in save-selected-window in toggle-read-onlyBozhidar Batsov
add-dir-local-variable switches to the .dir-locals.el buffer. Without save-selected-window, kill-buffer and the subsequent buffer-file-name check operated on unpredictable buffers. This matches the pattern already used in projectile-add-dir-local-variable.
2026-03-04Replace broken sort with partition in projectile--other-extension-filesBozhidar Batsov
The seq-sort comparator ignored its second argument, producing undefined ordering. The intent was just to prioritize files from sibling directories. Replace with a clear two-bucket partition: sibling-dir files first, then the rest.
2026-03-04Don't save .dir-locals.el on user abort in projectile-edit-dir-localsBozhidar Batsov
unwind-protect ran save-buffer even when the user aborted skeleton insertion with C-g, creating a .dir-locals.el with empty/partial content. Run save-buffer sequentially after the skeleton instead, so aborting leaves no file on disk.
2026-03-04Normalize project root to truename in projectile-ignored-project-pBozhidar Batsov
projectile-ignored-projects returns truename-resolved paths, but callers pass abbreviated or unnormalized paths. The member check would fail to match (e.g., ~/work/ vs /Users/bob/work/). Resolve project-root to truename before comparing.
2026-03-04Fix projectile-files-to-ensure expanding wildcards in wrong directoryBozhidar Batsov
file-expand-wildcards uses default-directory for relative patterns, which was whatever the current buffer had rather than the project root. Bind default-directory to the project root and return relative paths so projectile-expand-paths resolves them correctly downstream.
2026-03-04Fall back to xref-find-definitions instead of removed find-tagBozhidar Batsov
find-tag was removed in Emacs 29. When the configured tags backend (ggtags or etags-select) is unavailable, fall back to xref-find-definitions instead, which is available since Emacs 25.1.
2026-03-04Use public xref-show-xrefs API in projectile-find-referencesBozhidar Batsov
Replace private xref--show-xrefs with public xref-show-xrefs. The private function's signature changed across Emacs versions. Keep xref-references-in-directory to scope the search to Projectile's project root.
2026-03-04Use string-search instead of string-match in projectile-select-filesBozhidar Batsov
The filename text at point (from thing-at-point or region) was used directly as a regexp pattern in string-match. Characters like [ ] ( ) would cause invalid-regexp errors or incorrect matches. Use string-search for literal substring matching instead.
2026-03-04Don't execute empty string as shell command for non-git sub-projectsBozhidar Batsov
projectile-get-sub-projects-command returned "" for non-git VCSes, which passed the stringp guard in projectile-files-via-ext-command and spawned a useless shell process. Return nil instead, and also make the guard defensive against empty strings to match the docstring's contract.
2026-02-28Update CHANGELOG with round 3 codebase fixesBozhidar Batsov
2026-02-28Add tests for round 3 codebase fixesBozhidar Batsov
- Test sort-by-modification-time handles nil file-attributes - Test projectile--merge-related-files-fns merges correctly across keys, within same key, and does not mutate original return values - Test projectile-load-project-cache does not store nil on corrupt cache files
2026-02-28Use append instead of nconc in projectile--merge-related-files-fnsBozhidar Batsov
nconc destructively modifies the existing plist value, which can corrupt shared data from related-files-fn return values. It also silently drops values when the existing list is nil (nconc of nil doesn't update the plist entry in place). Using append with explicit plist-put fixes both issues.
2026-02-28Error early on nil command in projectile--run-project-cmdBozhidar Batsov
When no command is configured for a project type and compilation-read-command is nil (skipping the prompt), the nil command would reach (compile nil) and signal a cryptic wrong-type-argument error. Signal a clear user-error instead.
2026-02-28Use file-truename in projectile-recentf-files for symlink matchingBozhidar Batsov
recentf stores canonical paths (with symlinks resolved), so the project root must also be truename-resolved for string-prefix-p matching to work when the project path contains symlinks.
2026-02-28Handle deleted files in sort-by-modification/access-timeBozhidar Batsov
file-attributes returns nil for deleted files, causing file-attribute-modification-time to error. Use 0 as the fallback timestamp so deleted files sort to the end instead of crashing.
2026-02-28Share truename cache across buffers in projectile-open-projectsBozhidar Batsov
Like projectile-project-buffers, pass a shared truename-cache hash table to projectile-project-buffer-p to avoid redundant file-truename calls when iterating over the buffer list.
2026-02-28Remove unused compile-dir arg from configure-command format callBozhidar Batsov
The format call passed both project-root and compile-dir, but no project type's configure command uses two %s placeholders (meson uses one for the project root). The extra argument was silently ignored.
2026-02-28Remove unnecessary temp buffer in projectile--cache-project-commands-pBozhidar Batsov
The function created a temp buffer and ran hack-dir-local-variables on every compile/test/run invocation just to read a variable that dir-locals already set buffer-locally in file buffers. Simply read the variable directly.
2026-02-28Add 30s timeout to projectile-check-vcs-status busy-waitBozhidar Batsov
The unbounded (while (vc-dir-busy) ...) loop could freeze Emacs indefinitely if vc-dir hangs (e.g., broken remote repo). This is especially dangerous when called for every known project via projectile-check-vcs-status-of-known-projects.
2026-02-28Pass new-process to buffer name generation in projectile--eatBozhidar Batsov
The new-process argument was ignored when generating the eat buffer name (hardcoded nil), so requesting a new process via prefix arg would always reuse the same buffer name. This matches the behavior already used in projectile--vterm.
2026-02-28Use mapcan instead of mapcar in cmake-command-presetsBozhidar Batsov
mapcar wraps each recursive result in a list, producing nested lists that only work because flatten-tree compensates downstream. mapcan properly concatenates the results into a flat list.
2026-02-28Don't store nil in project cache on corrupt/empty cache filesBozhidar Batsov
When projectile-unserialize returns nil (corrupt or empty file), don't store nil in projectile-projects-cache. A nil entry prevents future reload attempts until the user manually invalidates.
2026-02-28Fix duplicate projectile-project-root call in cache-current-fileBozhidar Batsov
Reuse the already-resolved `current-project` binding instead of calling projectile-project-root a second time. Avoids redundant root resolution and a subtle correctness risk if the two calls returned different values.
2026-02-28Update CHANGELOG with round 2 codebase fixesBozhidar Batsov
2026-02-28Add tests for round 2 codebase fixesBozhidar Batsov
- Test that projectile-update-project-type resets cache with 'equal test - Test safe-local-variable predicates for project settings variables - Test that projectile-project-type passes project-root through to detect-project-type
2026-02-28Avoid redundant projectile-project-root call in detect-project-typeBozhidar Batsov
projectile-project-type already resolves the project root. Pass it through to projectile-detect-project-type so it doesn't resolve it a second time just for the cache key.
2026-02-28Use append instead of nconc in projectile-get-all-sub-projectsBozhidar Batsov
nconc destructively modifies the list returned by projectile-get-immediate-sub-projects, which could affect any caller holding a reference to that list. Use append for a non-destructive alternative.