You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#1867: Add projectile-per-command-compilation-buffer, so compiling, testing and running a project no longer overwrite each other's output (*compilation*<test>).
#2121: Recognize the subprojects of a monorepo: projectile-find-file-in-subproject (s-p c m f) scopes file completion to one part of the repository, projectile-project-subprojects lists them, and the subproject lifecycle commands now work in any project rather than only where the module's manifest matches the project's own type (projectile-subproject-markers).
#2120: projectile-run-task now also offers the tasks a project's own tooling defines - npm scripts, Deno tasks, Composer scripts, just recipes, go-task tasks and Make targets - named after the tool that defines them (npm:build) and switched off with projectile-discover-tasks.
#2119: Add 34 project types that used to come out as generic projects: node (a package.json with no lock file), bun, deno, nx, turborepo, python-uv, python-pdm, php-composer, php-laravel, xcode, flutter, terraform, pulumi, helm, ansible, docker-compose, just, mise, buck2, pants, gleam, babashka, scala-cli, dub, fpm, alire, foundry, godot, platformio, hugo, jekyll, zola, mkdocs and quarto.
#2119: A project type marker can now be an (:any "file1" "file2") clause, so a build file with several spellings no longer needs a predicate function.
#2115: Add projectile-replace-undo (s-p u), which reverts the last replace applied from the reviewable replace buffer, leaving alone any file whose replaced text has changed since.
#2114: Add project-scoped bookmarks - projectile-bookmark-set (s-p B s), projectile-bookmark-jump (s-p B j) and projectile-bookmark-delete (s-p B d) - which are plain Emacs bookmarks with the completion scoped to the current project (see projectile-bookmark-scope).
#2113: Add projectile-todos (s-p s t), which collects the project's TODO/FIXME-style annotations (projectile-todo-keywords) into the reviewable search buffer.
#2112: Add projectile-dashboard (s-p P), a buffer summarising the current project - name, root, type, file count, branch and working tree status, most-visited files, tasks and lifecycle commands, each of them a button - which also works as a projectile-switch-project-action.
#2111: Add projectile-doctor (s-p H), which reports how Projectile sees the current project - root, type, indexing method and command, available tools, cache state and effective ignore rules - and ends with a list of concrete suggestions.
#2104: Alien indexing now honors Projectile's ignore rules, which it previously skipped entirely, by pushing them into the external tool.
Alien projects will list fewer files than before; set projectile-alien-honors-ignores to nil for the old behavior.
Tools that can't express exclusions (svn, fossil, bzr, darcs, pijul, plain find) are filtered in Emacs Lisp instead, and dirconfig + keep entries stay hybrid/native only.
#2096: Add an optional Embark/Marginalia integration, wired via with-eval-after-load so neither package becomes a dependency.
Changes
#2123: Every lifecycle command now has a subproject variant - projectile-configure-subproject, -install- and -package- join compile, test and run (s-p c m o, s-p c m i, s-p c m p) - and they all say which subproject they'll run in at the prompt.
#2123: Fix the subproject commands discarding the project type's compilation directory, which had a Meson monorepo building in sub/ instead of sub/build/; projectile-compilation-dir now takes the subproject as an optional base directory.
#2122: projectile-globally-ignored-directories now also covers the dependency and build output directories of the common ecosystems - node_modules, target, _build, __pycache__, .venv, .next, .terraform and a couple of dozen more.
Names that projects do sometimes commit (vendor, dist, public, build) are deliberately left out, and projectile-globally-unignored-directories takes any of the others back.
#2121: go.mod is now the Go type's project file, so it can anchor the root of a Go project outside version control and mark a module inside a larger repository.
#2119: Bring the stale build tool markers up to date: Bazel now matches on MODULE.bazel, Gradle on the Kotlin DSL and on a settings file alone, Zig on build.zig, and go-task on all four Taskfile spellings.
#2119: Modernize the lifecycle commands that no longer work: Symfony's console moved to bin/ and its server out of the framework, the Dart CLI subsumed pub, setup.py build is deprecated by the PyPA, and poetry projects run pytest.
#2119: Rails and Django had their development server wired to the compile command, leaving the run command empty; the server is now the run command.
#2119: The PHP types are now registered after the JavaScript ones, so a PHP application isn't detected as a Node project because of the package.json its asset pipeline ships.
#2119: The supported project types table in the manual is now generated from the registry, which had drifted well behind it.
#2114: In projectile-dispatch, "display buffer" moved from B to C-o (mirroring its s-p 4 C-o binding), so B could become the bookmark prefix.
#2110: The grep/ag search integration and the ignore predicates now derive their exclusions from the same gitignore patterns indexing uses, so they answer exactly what indexing would.
projectile-ignored-file-p and projectile-ignored-directory-p take an optional project root instead of a pre-computed list of ignored paths.
Removed projectile-ignored-files, projectile-ignored-directories, their -rel variants, projectile-project-ignored, projectile-project-ignored-files, projectile-project-ignored-directories, projectile-paths-to-ignore and projectile-patterns-to-ignore, which existed only to build those absolute path lists.
#2109: alien indexing now honors dirconfig + keep entries, which it previously ignored without saying so.
#2109: Fix indexing failing outright when a dirconfig had + keep entries and the indexing command was a shell pipeline (the plain find fallback, svn, fossil, pijul).
#2107: Projectile's ignore configuration now speaks gitignore patterns everywhere, matched the same way by every indexing method: a slashless pattern matches at any depth, a pattern with a slash is anchored at the project root, a trailing / means directory-only, and *, **, ? and [...] are wildcards.
The * prefix in projectile-globally-ignored-directories is no longer a marker meaning "at any depth" (that's now the default) - it's a plain wildcard, so *node_modules should become node_modules.
A bare entry is no longer top-level-only under hybrid; write /tmp if you meant only the project root.
Dirconfig ! ensure entries now apply under alien too, and projectile-global-ignore-file-patterns stays Emacs regexps and therefore native-only.
#2104: Ignore matching is now case-sensitive under every indexing method, where native and hybrid previously folded case (so .elc also hid BUILD.ELC).
#2104: Drop .ensime_cache and .eunit from the default projectile-globally-ignored-directories, as ENSIME was archived in 2018 and .eunit is a rebar2 artifact.
#2104: Remove projectile-warn-when-dirconfig-is-ignored, which existed only to warn that alien bypassed the dirconfig.
#2099: Drop the standalone package headers (Version, Package-Requires) from projectile-consult.el, since the phantom Package-Requires made build tooling treat an in-package module as its own package.
Bugs fixed
#2118: Fix projectile-find-file showing "Projectile is indexing" forever with projectile-async-indexing enabled: Projectile waited for the indexing process's sentinel, which Emacs doesn't guarantee to run while a command sits waiting on the process, and now collects the finished command's output itself instead (projectile-async-index-sentinel-timeout).
#2097: Fix projectile-compile-project and projectile-test-project forgetting a command you edited at the prompt in a CMake project, where a command the project type registers as a function was never cached - the function's own answer still isn't, so a preset picker keeps prompting.
#1075: Opening a file the VCS ignores no longer adds it to the file cache under alien/hybrid indexing, so a compiled artifact you happen to visit stops turning up in projectile-find-file.
#2119: Fix the angular project type never matching anything: its two markers were ANDed, but a project has either angular.json (Angular 6+) or .angular-cli.json, never both.
#2119: Fix the Python project types shadowing each other - pyproject.toml was checked before django, python-poetry, python-pipenv and python-tox, and since nearly every Python project has one, those four never matched.
#2119: Fix php-symfony not matching a modern Symfony project: it required an app directory, gone since Symfony 3, and a vendor directory, which only exists after someone has run composer.