aboutsummaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
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.
2026-02-28Use hash set for deleted file removal in projectile-dir-files-alienBozhidar Batsov
The deleted file check used member inside seq-remove, which is O(n*m) where n is total files and m is deleted files. Convert the deleted list to a hash set for O(1) lookups, making the overall operation O(n).
2026-02-28Add safe-local-variable predicates for dir-locals variablesBozhidar Batsov
Variables documented as "should be set via .dir-locals.el" were missing safe-local-variable properties, causing Emacs to prompt for confirmation every time they were encountered. Add stringp for command and directory variables, booleanp for the caching toggle. Intentionally omit projectile-project-related-files-fn since it accepts functions, which cannot be safely evaluated from dir-locals.
2026-02-28Use expand-file-name instead of file-truename in compilation-dirBozhidar Batsov
file-truename resolves symlinks via synchronous I/O, which can hang Emacs when the project is on a remote host via TRAMP. expand-file-name is sufficient here (it normalizes path components) and works safely with remote paths.
2026-02-28Skip projectile-maybe-limit-project-file-buffers on TRAMPBozhidar Batsov
The buffer-limiting function was called before the file-remote-p guard in projectile-find-file-hook-function, triggering expensive buffer enumeration and file-truename calls on every remote file open. Move it inside the existing TRAMP guard.
2026-02-28Fix projectile-update-project-type resetting type cache with wrong testBozhidar Batsov
When called with :precedence, the function recreated the type cache hash table without :test 'equal, defaulting to eql. Since project roots are strings, no cache key would ever match, causing perpetual re-detection of project types until Emacs was restarted.
2026-02-28Update CHANGELOG with bug fixes and performance improvementsBozhidar Batsov
2026-02-28Add tests for fixed/improved functionsBozhidar Batsov
- projectile-purge-file-from-cache: verify it serializes the updated file list (not the stale original) to disk - projectile-default-generic-command: test string commands, symbol commands, lambda commands, and missing commands - projectile-sort-by-modification-time: verify descending sort order - projectile-project-buffer-p: verify the truename cache is used and avoids redundant file-truename calls
2026-02-28Move dirconfig cache defvar and handle nil file-attributesBozhidar Batsov
Move projectile--dirconfig-cache near other cache variables to fix byte-compilation warning. Also skip caching when file-attributes returns nil (e.g. file doesn't exist) to avoid false cache hits.
2026-02-28Fix hook management in projectile-mode enable/disableBozhidar Batsov
Two issues: 1. projectile-find-dir-hook was added on mode enable but never removed on disable, leaking the hook function after turning off the mode. 2. dired-before-readin-hook was added with the LOCAL flag, but projectile-mode is a global mode. This meant the hook only fired in whichever buffer happened to be current when the mode was enabled, not in all dired buffers. Remove the LOCAL flag and clean it up properly on disable.
2026-02-28Use display-warning for failed cache serializationBozhidar Batsov
A plain message is easy to miss in the echo area. Use display-warning so the failure is visible in the *Warnings* buffer and harder to overlook, since a failed write means in-memory and on-disk caches will silently diverge.
2026-02-28Cache file-truename calls in projectile-project-buffer-pBozhidar Batsov
When checking which buffers belong to a project, file-truename was called for every buffer's directory. Many buffers share the same directory, so memoize the results in a hash table passed from projectile-project-buffers. This reduces redundant symlink resolution, which is especially costly over TRAMP.
2026-02-28Cache projectile-parse-dirconfig-file results per projectBozhidar Batsov
The .projectile dirconfig file was being re-read and re-parsed 3-4 times per indexing operation (by paths-to-ignore, patterns-to-ignore, paths-to-ensure, patterns-to-ensure, etc.). This is wasteful, especially over TRAMP where each file read is a network round-trip. Cache the parsed result per project root, keyed by the file's modification time so edits to .projectile are picked up immediately. The cache is also cleared by projectile-invalidate-cache.
2026-02-28Pre-compute timestamps in sort-by-modification/access-timeBozhidar Batsov
The sort comparator was calling file-attributes on every comparison, resulting in O(n log n) stat calls. Pre-compute all timestamps into a hash table first (O(n) stats), then sort using cached values. Also use file-attribute-modification-time/file-attribute-access-time accessors instead of raw nth.
2026-02-28Use eq instead of string= for symbol comparisonsBozhidar Batsov
system-type and the return value of projectile-project-vcs are symbols, not strings. string=/string-equal happened to work due to implicit coercion, but eq is the correct comparison for symbols.
2026-02-28Fix projectile-default-generic-command dropping lambda commandsBozhidar Batsov
The function used fboundp + symbol-function which only works for symbols. Actual lambda/closure values would silently return nil. Use funcall directly, which handles both symbols and lambdas.
2026-02-28Fix misplaced paren in projectile-project-buffers-other-bufferBozhidar Batsov
The NORECORD and FORCE-SAME-WINDOW arguments to switch-to-buffer were outside the function call, so they were never actually passed.
2026-02-28Fix projectile-purge-file-from-cache serializing stale dataBozhidar Batsov
The function was serializing the original file list to disk instead of the updated list with the file removed. This meant purged files would reappear in the cache after restarting Emacs.
2026-02-16Support slnx files for dotnet-sln project types (#1971)Bozhidar Batsov
2026-02-15Bump the dev versionBozhidar Batsov
2026-02-15Fix hardcoded git command in sub-projects and add hg/svn ignored commandsBozhidar Batsov
- Use VCS-appropriate command in projectile-get-sub-projects-files instead of hardcoding projectile-git-command. - Add projectile-hg-ignored-command and projectile-svn-ignored-command defcustoms so ignored-file filtering works for hg and svn projects in native/hybrid indexing mode.
2026-02-15Add TODOs for seq-union and seq-keep when minimum Emacs is bumpedBozhidar Batsov
seq-union requires Emacs 28.1+ and seq-keep requires Emacs 29.1+.
2026-02-15Replace seq-union with seq-uniq + append for Emacs 27 compatibilityBozhidar Batsov
seq-union is not available in Emacs 27's built-in seq.el. Use (seq-uniq (append ...)) which achieves the same result.
2026-02-15Add declare-function for vc-git-grepBozhidar Batsov
The fboundp guard was removed but vc-git is only loaded at runtime, so the byte-compiler needs a declare-function to avoid a warning.