What's New in RobotCode v2.5.0
If you've ever opened a large Robot Framework project and gone for coffee while RobotCode was still thinking — this release is for you. Version 2.5.0 is all about speed: faster startup, faster analysis, faster code completion. And a few new tricks on top.
Instant Startup with Analysis Caching
The biggest change you'll notice: RobotCode remembers. When you open a project for the second time, all the analysis work from your last session is still there — diagnostics, code completion, navigation, everything loads almost instantly.
Behind the scenes, RobotCode now stores fully resolved analysis data in a local SQLite database. Instead of re-analyzing every file on every IDE start, it loads cached results and only re-processes files that actually changed. For projects with hundreds of Robot files, this can cut startup from minutes down to seconds.
This is enabled by default — there's nothing to configure. The cache is automatically invalidated when your source files change, when library dependencies are updated, when environment variables or command-line variables differ, or when you update RobotCode itself. If something changes, the affected parts are re-analyzed — everything else comes straight from cache.
Since this is a new feature, you can disable it if you run into any issues:
# robot.toml
[tool.robotcode-analyze.cache]
cache-namespaces = falseor via the CLI:
robotcode analyze --no-cache-namespacesMultiple processes (the language server, CLI commands, parallel analyze runs) can safely access the cache at the same time thanks to file-level locking. No corruption, no conflicts.
Performance: The Numbers
Even without the cache, this release is noticeably faster. Here's what changed:
No more 30-minute hangs on large projects. Robot Framework's
variable_not_foundruns a fuzzy "Did you mean…?" search on every unresolved variable — a nice idea, but O(n×m) over all variable candidates. For big projects (375+ files), this could freeze the analysis for over 30 minutes. RobotCode now skips that search entirely since it never uses the suggestion text. Problem solved. (#587)Keyword matching is 94% faster. The
KeywordMatcherused to be instantiated from scratch on every lookup — about 7.5 million times per analysis run. It's now cached on theKeywordDocitself. Combined with a new dict-based index inKeywordStore, keyword lookups went from linear scan to O(1) for non-embedded keywords. Overall analysis time dropped by 22% with 31% fewer function calls.File resolution is 28% faster. Swapping
pathlib.Pathforos.pathstring operations in the hot path of file resolution plus lazy-caching of validsys.pathentries cut warm-start wall time by nearly a third.Less memory per document. Each document used to keep two cached AST models. Now there's just one, saving around 200–500 KB per file. That adds up quickly in a big workspace.
Faster cache loading. Cached namespace data now includes source hints that let RobotCode skip expensive filesystem lookups (
find_resource) when the cached paths still exist on disk. Cache entries use lazy deserialization — data blobs are only unpickled on actual cache hits, not on every lookup.ArgumentSpec.resolve()actually caches now. A subtle bug causedRobotArgumentSpecto be recreated on every call (100K times per run) instead of being cached. Fixed — instantiation calls dropped by 98.7%.
Smarter Code Completion for Type Hints
If you write Python libraries with type hints like Literal["fast", "slow", "auto"], RobotCode now picks up on those and shows the allowed values directly in the completion list. This works for Union types containing Literal too, so Literal["x", "y"] | int will offer x and y as suggestions.
No more switching to the library docs just to look up which string values a keyword accepts — the editor tells you right there.
Find Unused Keywords & Variables from the CLI
Unused keywords and variables are the kind of thing that quietly accumulates in any project. RobotCode can now detect them when running robotcode analyze code from the command line — great for CI pipelines or periodic cleanup sessions.
Enable it in your robot.toml:
[tool.robotcode-analyze.code]
collect-unused = trueOr toggle it per invocation:
robotcode analyze code --collect-unused
robotcode analyze code --no-collect-unusedFull Control over the Analysis Cache
A new robotcode analyze cache command group gives you visibility into what's cached and lets you manage it when needed:
robotcode analyze cache path # where is the cache stored?
robotcode analyze cache info # cache statistics, per-section breakdown
robotcode analyze cache list # list cached entries (supports glob filtering with -p)
robotcode analyze cache clear # remove cached entries by section
robotcode analyze cache prune # wipe the entire cacheAll output respects --format (text/json/toml) and --no-color, so it plays nicely with scripts and CI.
You can also point the cache to a custom directory via the ROBOTCODE_CACHE_DIR environment variable. The VS Code extension automatically sets this in the integrated terminal, so your CLI commands and the language server always share the same cache without any manual setup.
Bug Fixes
- Fixed cache validation for libraries imported via relative paths — no longer triggers unnecessary full rebuilds on warm start.
- Variable names with trailing
=are now stripped correctly by the resource builder (#546). - RobotCode no longer overrides the
sourcefield on AST blocks when Robot Framework itself already sets it (#588). - Fixed a race condition when accessing workspace language settings in multi-workspace setups.
Under the Hood
A lot of internal work went into this release to prepare for future features:
Workspace-wide reference index (ProjectIndex) — RobotCode now maintains an incrementally updated inverse index across your entire workspace. When a file changes, only its references are updated instead of scanning everything. This covers keywords, variables, namespace entries, keyword tags, testcase tags, and metadata. This is the foundation for upcoming features like unused import detection, import dependency visualization, and call hierarchy — stay tuned.
Namespace refactoring — The old monolithic
Namespaceclass has been split into a clean data container (NamespaceDTO) built by a dedicatedNamespaceBuilder, with separate modules for import resolution, AST analysis, variable scoping, and scope trees. This makes the codebase more maintainable and easier to extend.RF_VERSIONconstant — All ~134 scatteredget_robot_version()call sites have been replaced with a single module-level constant. All dead code for Robot Framework < 5.0 (which is no longer supported) has been removed.JSON file watching —
.jsonfiles are now included in the watched file extensions, so changes to JSON-based configuration are picked up automatically.Deprecated Robocop options removed — Legacy robocop configuration options that were deprecated in earlier releases have been cleaned up.
Thank You
Thanks to everyone who reported issues, contributed ideas, and tested pre-release builds. Your feedback drives every release.
For the full list of changes, see the Changelog.