Changed djls check to print a summary when no errors are found, such as No errors found in 12 files., or No templates found to check. when no templates match. Pass --quiet to suppress it.
Added bundled Django 5.2, 6.0, and 6.1 sources and templates for core tag and filter analysis without a Django installation or Python interpreter. Installed or project-local Django sources take precedence.
Added the django_version setting to select a bundled Django release line, otherwise inferred from the project's lockfile or declared dependencies.
Added an S124 hint on {% load %} when DJLS can't read a library's tag or filter registrations, with a code action that opens a prefilled issue.
Added an error notification when the Django project fails to load, shown once per failure until a reload succeeds.
Added a logged warning when a configured venv_path has no discoverable site-packages.
Added a getting started guide, a "Why a language server?" page, and a Logging guide, and reorganized the documentation navigation.
Sped up startup, document edits, template-name completion and resolution, and djls check, especially for projects with complex Django settings.
Expanded Python environment discovery to support active Conda environments, Python installations on PATH, executable symlinks, and additional system package layouts.
Changed automatic interpreter discovery to prefer project virtual environments over VIRTUAL_ENV, including under pre-commit's isolated environments.
Updated djangofmt from 0.2.7 to 1.0.0, bringing roughly 2x faster template formatting and some bug fixes.
Changed the server to keep only the seven most recent daily djls.log.YYYY-MM-DD files and fall back to stderr when a log file can't be created.
Changed the editor output panel to show only DJLS messages at INFO and above. Dependencies default to WARN unless overridden by RUST_LOG; DJLS warnings omit file paths and error details unless DEBUG logging is enabled.
Internal: Made just corpus sync prepare reusable project environments and separated corpus-wide tests and benchmarks from the regular test matrix.
Internal: Reorganized CONTRIBUTING.md around a first-contribution path.
Internal: Made releases draft-first and recoverable, with PyPI and standalone installation checks before publication.
Fixed incorrect tag and filter argument diagnostics for decorated functions, including stringfilter-decorated filters in Django source checkouts, and for unrelated functions sharing the same name.
Fixed argument validation for simple_tag, inclusion_tag, and simple_block_tag to match Django's rules, and missing argument validation for tags defined through helper functions or control flow.
Fixed validation and completion for {% with %} assignments, widthratio ... as variable, for ... reversed, and trailing keywords in {% get_flatpages %}.
Fixed argument validation for Pipeline's stylesheet and javascript tags, Compressor output modes, and Django's templatetag choices.
Fixed false duplicate-option diagnostics and missing diagnostics or references for custom tags with unusual body parsers.
Fixed invalid tag registrations appearing as valid tags when they supply a name twice or pass excess arguments to inclusion_tag.
Fixed unloaded-tag diagnostics and load quick fixes disappearing when an unrelated template library has unknown registrations.
Fixed stale diagnostics during rapid edits and close/reopen cycles.
Fixed server hangs during edits and project reloads, and on templates with repeated unclosed delimiters.
Fixed a pending full project reload being skipped when a template-library refresh was already queued.
Fixed zero-configuration Django settings discovery for standard manage.py projects, including src layouts.
Fixed an invalid, missing, or unreadable Django settings module going unreported; the server now logs a warning.
Fixed relative pythonpath entries resolving outside the project root and explicit entries being shadowed by .pth-discovered editable installs.
Fixed Django settings analysis for paths built with Path.parents[index].
Fixed .env virtual environment directories being read as environment-variable files and producing a warning.
Fixed explicit false and empty LSP initialization options failing to override project configuration.
Fixed djls check scanning the project root when template settings differ only in context processors.
Fixed missing explanations for formatting failures: invalid or unreadable [tool.djangofmt] configuration now logs a warning and skips formatting; syntax errors include their line and column in the debug log.
Fixed excessive log growth from dependency messages such as Salsa's query logging (#836).
Moved the djls-check pre-commit hook to the dedicated djls-pre-commit repository, where each hook revision installs the matching django-language-server release.
Changed Django settings analysis to keep mutually exclusive configuration branches separate instead of combining their values into one partial result.
Changed Django settings analysis to treat closed unsupported Python literals as malformed rather than unresolved.
Changed template semantics and IDE features to use each file's feasible backends and the Template Library definitions active at each source position.
Changed template-library completion and installed-app guidance to retain known results through unrelated discovery problems, while unknown-library and unknown-symbol diagnostics now require an exhaustive miss.
Changed template navigation to avoid reporting templates as missing when configuration or filesystem search is incomplete, while retaining known possible destinations.
Changed unreadable files to be skipped instead of analyzed as empty source.
Changed Python model and template-spec extraction to retain known facts after recoverable syntax errors.
Changed template goto definition to return origin ranges for clients that support definition links.
Changed template tag library discovery to derive libraries from project source and Django settings instead of the runtime inspector.
Changed static Django discovery to preserve inactive-app evidence for S118, S119, and S121 diagnostics without runtime introspection.
Changed Django discovery to run after LSP initialization, refresh in the background, and warm IDE caches without blocking read requests.
Changed startup refreshes to run discovery phases in parallel and report counted progress.
Changed template validation and completion scoping to use localized inventory completeness, suppressing absence diagnostics only where discovery evidence is incomplete.
Changed template formatting to honor LSP/editor formatting options for indentation and final/trailing whitespace.
Bumped Rust toolchain from 1.95 to 1.97.1 and moved workspace crates to Rust 2024.
Internal: Added multi-file scenario support and a pluggable snapshot renderer to the djls-testing mdtest harness.
Internal: Reshaped template tag library storage around loadable and builtin mounts.
Internal: Moved the project model and static source recognizers into djls-project.
Internal: Moved Python spec extraction and template-origin resolution into djls-project, leaving djls-semantic as the project-meaning layer.
Internal: Refactored template semantics around TemplateTree for validation, references, outlines, folding, and opaque-region handling.
Internal: Reworked template analysis around per-library semantic products, sparse per-Template projections, and generation-gated production priming.
Internal: Propagated the Salsa database lifetime through interned Template Library identities and the domain values that retain them.
Internal: Updated realistic template benchmarks to use project-backed source extraction, canonical builtin roles, and snapshot-backed workload contracts.
Internal: Moved corpus tooling and shared test fixtures into djls-testing.
Internal: Reworked Python settings evaluation around module identities, typed import outcomes, invariant-preserving collections, and correlated list alternatives.
Internal: Reworked Django model inheritance around typed base outcomes, C3 ordering, and declaration-owned relation bindings.
Internal: Reduced development and test debug information to line tables to limit Rust build artifact size.
Internal: Expanded contributor guidance for setup, testing environments, corpus data, snapshots, linting, and pinned tool updates.
Removed the runtime inspector subprocess, embedded Python zipapp, and ~/.cache/djls/inspector/ disk cache. The server no longer needs a working Django setup to derive project facts.
Removed the template library snapshot disk cache and startup cache-loading phase.
Internal: Removed djls-workspace; workspace/filesystem logic now lives in djls-source and djls-server.
Internal: Removed the deprecated extract_rules extraction path.
Fixed LSP ranges for diagnostics, hover, document links, document symbols, and code actions when clients use UTF-16 or UTF-32 position encoding.
Fixed djls check returning success when an explicit path could not be read or indexed.
Fixed malformed env-file entries exposing their contents in server logs.
Internal: Added a release preflight check that requires the release tag to match the package version.
Fixed false unknown tag and filter diagnostics when a template library imports or dynamically mutates its Django registration object.
Fixed static path evaluation to follow imported helper aliases without mistaking shadowed Path, str, or os bindings for standard-library helpers.
Fixed static Django settings evaluation through ordinary and from imports, including dotted module chains, module attributes, named package children, and __all__-controlled star exports.
Fixed Python settings evaluation to distinguish list and tuple concatenation while preserving known collection facts through supported iterable extensions.
Fixed relative imports in Django settings modules, including package aliases and overlapping Python search roots.
Fixed project reloads so an analysis task panic no longer prevents later reloads.
Fixed Django relative template paths (./, ../) in {% extends %} and {% include %} resolution, including inheritance chains, document links, goto definition, and find references.
Fixed false tag argument errors for manually parsed tags that strip trailing assignment clauses, such as {% now ... as var %} and {% url ... as var %}.
Fixed static Django settings analysis hanging on projects with many conditional module effects.
Fixed static Python evaluation to honor short-circuiting and and or operands.
Fixed static settings analysis to exclude impossible combinations from repeated and derived configuration predicates.
Fixed static settings analysis to preserve known template backend fields after nested dictionary assignments.
Internal: Fixed CLI summary tests to run without a discoverable Django installation.
Added document symbols for Django template structure outlines.
Added hover documentation for Django template tags, filters, libraries, and template references.
Added folding ranges for Django template block, comment, and import regions.
Added pre-commit hook for running djls check on Django template files.
Added rg-style file filtering flags to djls check: -g/--glob for glob patterns, --no-ignore to skip ignore files, -L/--follow for symlinks, -d/--max-depth for recursion depth, --color always|auto|never, and -q/--quiet.
Added env_file configuration option for loading environment variables from a .env file into the inspector process.
Filesystem cache for template library snapshots (~/.cache/djls/inspector/). On subsequent startups, cached data is loaded in ~2ms instead of waiting 200-700ms for the Python subprocess. The cache is validated in the background on every startup.
Internal: Added venv model scanning, workspace model discovery, and Salsa wiring for compute_model_graph — the model graph is now populated from both site-packages and workspace models.py files with automatic invalidation on edit.
Internal: Added just dev profile recipe for local flamegraph profiling of benchmarks.
Internal: Added [profile.bench] with debug = 2 to Cargo.toml for symbolized bench profiles.
Internal: Replaced the database inspector handle with a backend-neutral project introspector.
Internal: Added a semantic validate_template_file convenience query for file-level template validation.
Internal: Unified djls-corpus to repo-only format, removing the PyPI package path. All corpus entries are now [[repo]] in manifest.toml, fetched as git archives. Removed sha2, toml_edit dependencies and the add CLI command.
Internal: Added license file fetching to djls-corpus lock. License text is saved to crates/djls-corpus/licenses/ for attribution.
Internal: Replaced manual AvailableSymbols cache in TemplateValidator with SymbolIndex. Symbol availability is now precomputed per {% load %} boundary and memoized across revisions, eliminating per-walk rebuilds and hand-rolled invalidation logic.
Internal: Moved check_file orchestration and diagnostic rendering into djls-db. Removed djls-ide, djls-templates, and djls-project dependencies from the CLI binary.
Internal: Moved extraction orchestration from djls-project to djls-db. Removed unused djls-workspace dependency from djls-project.
Widened templatetag extraction to catch any uncaught exception in compilation functions, not just TemplateSyntaxError. Tags that raise ValueError, TypeError, or other exceptions in guards now produce validation constraints.
Parallelized inspector subprocess query and filesystem library discovery during startup, hiding discovery latency behind the slower inspector call.
Internal: LoadState now borrows &str from LoadedLibraries instead of cloning strings, and compute_loaded_libraries returns a reference via returns(ref). Eliminated all string allocations in available_at.
Internal: Consolidated TagIndex from three separate tracked fields into a single roles map, reducing classify from 3 Salsa field accesses to 1. TagClass now borrows from Salsa storage instead of cloning.
Internal: Replaced template BlockTree/SemanticForest structure analysis with TemplateTree, a structural semantic projection used by opaque-region computation and future outline features.
Fixed template parser diagnostics to preserve structured parser errors and source spans while retaining the existing T100 diagnostic code. Malformed filter expressions now produce parser errors instead of being silently ignored.
Suppressed failed to send notification ERROR log spam during server shutdown by disabling the LSP log forwarding layer on shutdown.
Fixed djls check silently ignoring file arguments when - (stdin) was also passed. This command now returns an error for mixed stdin/path input.
Fixed djls serve --connection-type tcp silently using stdio. The command now errors with an unsupported-mode message.
Fixed djls check with no arguments silently reading stdin instead of discovering template files. Stdin is now triggered explicitly by passing - as a path.
Fixed structural validation (unclosed tags, unbalanced blocks) being silently skipped when no Python inspector data was available. builtin_tag_specs() now provides Django's standard tag definitions as a fallback.
Deprecated lazy.lua Neovim plugin spec. It now only shows a migration warning and will be removed in the next release. See Neovim client docs for the new Neovim 0.11+ configuration approach.
Added support for loading server settings from user files (~/.config/djls/djls.toml) and project files (djls.toml, .djls.toml, and pyproject.toml via [tool.djls] table`)
Implemented dynamic settings reloading via workspace/didChangeConfiguration
Added venv_path setting to allow explicit configuration of Python virtual environment
Added unified file and LSP logging using tracing to server
Added virtual FileSystem for workspace file management
Implemented textDocument/didSave LSP method
Added typed argspecs for LSP snippets to tagspecs configuration