Skip to content

v3.3.0

Latest

Choose a tag to compare

@bbatsov bbatsov released this 27 Jul 08:02

New features

  • #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.