# Changelog

## master (unreleased)

### Changes

* `projectile-find-references` now honours Projectile's ignore configuration (`.projectile` and the globally-ignored files/directories) and is scoped via the project's file set, like `projectile-grep`/`-ag`/`-ripgrep`. It previously went through the semantic-symref API, which searched the whole tree and ignored that configuration. It also now defaults the prompt from the active region (not just the symbol at point) and no longer carries a dead pre-27 display fallback. The search remains a backend-agnostic textual one; for semantic references use the built-in `xref-find-references` (which is also scoped to the Projectile project).
* Remove the built-in tags support: `projectile-find-tag`, `projectile-regenerate-tags`, `projectile-visit-project-tags-table`, and the `projectile-tags-command`/`projectile-tags-backend` options (along with the ggtags/etags-select special casing). ctags/etags navigation has been largely superseded by `xref` and LSP (`eglot` is built in since Emacs 29). Use `xref-find-definitions` directly, or `projectile-find-references` for project-wide references. `projectile-tags-file-name` is kept, since it's still used to exclude a generated tags file from indexing.
* Remove `projectile-browse-dirty-projects` and `projectile-vcs-dirty-state`. The implementation spun up `vc-dir` and busy-waited (`sleep-for`) up to 30 seconds per project across every known project, scraping status strings - slow, blocking, and niche. Use Magit, `vc-dir`, or a dedicated tool to find projects with uncommitted changes.
* Remove the idle timer (`projectile-enable-idle-timer`, `projectile-idle-timer-seconds`, `projectile-idle-timer-hook`). It existed mainly to re-run `projectile-regenerate-tags` on an idle timer, which makes little sense in an LSP/xref world, and it was off by default. Use a plain `run-with-idle-timer` if you really want this behavior.
* Remove `projectile-commander` (and `def-projectile-commander-method`), the single-key command dispatcher. It's superseded by `projectile-dispatch`, the `transient` menu added in this cycle. The kbd:[s-p m] binding and the `C-u s-p p` project-switch prefix now invoke `projectile-dispatch` instead (the prefix falls back to `projectile-switch-project-action` when `transient` isn't installed).
* A cold `projectile-find-file` (and any command that lists project files) no longer freezes Emacs while the project is indexed under the `alien`/`hybrid` methods. The indexing command runs asynchronously and is awaited in a way that keeps Emacs responsive to redisplay and `C-g` (which aborts the indexing), instead of blocking until it finishes. The resulting file list is identical; only the responsiveness during indexing differs. Controlled by the new `projectile-async-indexing` (default on); it has no effect under `native` indexing, in batch mode, or while a keyboard macro runs, all of which index synchronously as before.
* Speed up native indexing further: `projectile-index-directory` now reads each directory with `directory-files-and-attributes`, so an entry's type comes from the listing call instead of a `file-directory-p` stat per file. That stat was a separate filesystem round-trip each, which dominated the walk on large and remote (TRAMP) trees - it's now one round-trip per directory instead of one per file. Symlinks pointing at directories are still followed, matching the previous behaviour. Roughly 40% faster on a local 12k-file tree; the win is far larger over TRAMP.
* Speed up native indexing's post-walk step: `projectile-dir-files-native` strips the project-root prefix with a single `substring` per file instead of `file-relative-name`, which paid for an `expand-file-name`/`abbreviate-file-name` per file. `projectile-project-files` also skips re-relativising the listing when the only directory walked is the project root itself (the common single-directory case). Together that removes roughly two seconds of overhead per 90k files indexed.
* [#1872](https://github.com/bbatsov/projectile/issues/1872): Clarify in the `projectile-register-project-type` docstring and the manual that a list of `marker-files` must *all* be present for a type to match (logical AND), and that a predicate function should be used to match when any one of several files is present.
...
...
