Changelog
v0.1.26
Features
- File operation behaviors are configurable via:
fileOperations.templateOnCreatefileOperations.updateImportsOnRenamefileOperations.updateImportsOnDelete
- Default file-operation settings are enabled.
- Template/scaffolding naming standardized to
templateOnCreate.
Fixes
- Improve file creation scaffolding flow to avoid missing scaffold content on new files.
- Fix duplicate/incorrect scaffold insertion timing during create-file lifecycle.
- Improve auto-import completion behavior for top-level symbols and import edit attachment.
Benchmarks
- Added/updated benchmark coverage for file-operation lifecycle flows (
willCreateFiles,willRenameFiles,willDeleteFiles) and auto-import scenarios.
v0.1.25
Performance
- Replace clone-then-strip with build-filtered-map in
walk_and_extract()(#132)build_filtered_decl()/build_filtered_contract()iterate borrowed node fields and only clone fields that pass the STRIP_FIELDS filter, skipping heavy subtrees (body,modifiers,value,overrides, etc.)- Eliminates 234 MB of transient allocations (629→395 MB total, -37%)
- RSS: 310 MB → 254 MB (down from 394 MB pre-optimization)
- Pre-size HashMaps with
with_capacity()incache_ids(),extract_decl_nodes(),build_completion_cache(),build_hint_index(),build_constructor_index()(#132) - Remove dead
goto_references()andgoto_references_with_index()functions (#132) - Gate
SolcOutput/SourceEntrybehind#[cfg(test)](#132)
Fixes
- Fix cross-file references contamination: use
nameLocationinstead ofsrcinresolve_target_location()so "Find All References" onIPoolManager managerreturns references tomanager, not to theIPoolManagerinterface (#131) - Fix non-deterministic hover on inherited contracts:
byte_to_id()now prefers nodes withreferencedDeclarationwhen two nodes share the same span length (#131)
Memory
| State | RSS | vs v0.1.24 |
|---|---|---|
| v0.1.24 baseline | 230 MB | — |
| Before optimization | 394 MB | +164 MB |
| v0.1.25 | 254 MB | +24 MB |
DHAT profiling (poolmanager-t-full.json, 95 files):
| Metric | v0.1.24 | v0.1.25 | Delta |
|---|---|---|---|
| Total allocated | 629 MB | 395 MB | -37% |
| Peak (t-gmax) | 277 MB | 243 MB | -12% |
| Retained (t-end) | 60 MB | 60 MB | unchanged |
Tests
- 458 total tests, 0 warnings
Benchmarks
Updated for Shop.sol (all competitors), Pool.sol (v0.1.25 vs v0.1.24), and PoolManager.t.sol (v0.1.25 vs v0.1.24).
v0.1.24
Features
- Project-wide source indexing for cross-file references (#115, #119)
- Semantic tokens range and delta support
- LSP settings configuration (#112)
- Benchmark configs with server registry and didChange snapshots (#121)
Performance
textDocument/documentLinkreturns only import links, not every identifier (#122)- Drop optimizer and conditionally exclude gasEstimates from solc input (#117)
Fixes
- Handle
{value: ...}/{gas: ...}modifier calls in inlay hints and signature help (#125, #116) - Correct signatureHelp cursor positions to inside function call parens
- Remap all tests from forge to solc fixture (#123)
- CI: checkout submodules so fixture-based tests can find v4-core
Tests
- 466 total tests, 0 warnings
Benchmark (v4-core Pool.sol)
| Method | p95 |
|---|---|
| initialize | 12.9ms |
| completion | 0.4ms |
| hover | 23.1ms |
| definition | 11.1ms |
| references | 19.4ms |
| rename | 21.2ms |
| inlayHint | 2.8ms |
| signatureHelp | 11.7ms |
| semanticTokens/full | 3.7ms |
Scorecard: 15/18 wins vs solc, nomicfoundation, juanfranblanco, qiuxiang
v0.1.23
Features
textDocument/signatureHelp— shows function signature and active parameter while typing (#110)- Opt-in gas estimates via
@custom:lsp-enable gas-estimatesNatSpec tag (#109)
v0.1.22
Improvements
- Use
svm-rsas a library for solc version management (#106, #105)svm::installed_versions()for discovering installed solc versionssvm::version_binary()for resolving solc binary pathssvm::install()for auto-installing missing versions (async, native)- No longer shells out to the
svmCLI or manually walks the filesystem
v0.1.21
Features
- Auto-detect solc version from
pragma solidityand resolve matching binary (#93, #95)- Parses pragma constraints: exact (
0.8.26), caret (^0.8.0), gte (>=0.8.0), range (>=0.6.2 <0.9.0) - Scans svm-rs and solc-select install directories for matching versions
- Auto-installs missing versions via
svm-rslibrary - Cross-platform support (macOS, Linux, Windows)
- Cached version list (scanned once per session)
- Parses pragma constraints: exact (
- Solc version resolution respects both pragma and foundry.toml (#103)
- Exact pragmas (
=0.7.6) always honoured — foundry.toml cannot override - Wildcard pragmas (
^0.8.0) use foundry.toml version if it satisfies the constraint - No pragma falls back to foundry.toml, then system solc
- Exact pragmas (
- Foundry config support for compiler settings (#103)
- Reads
via_ir,optimizer,optimizer_runs,evm_versionfromfoundry.toml - Passes settings to solc standard JSON (
viaIR,optimizer,evmVersion) - Reads
ignored_error_codesto suppress matching diagnostics - Fixes "Stack too deep" errors for projects requiring
via_ir(e.g. EkuboProtocol/evm-contracts)
- Reads
- Callsite parameter documentation on hover (#103)
- Hovering over arguments in function/event calls shows
@paramdoc from the called definition - Uses tree-sitter on the live buffer to find enclosing call and argument index
- Resolves via
HintIndex(exact offset or(name, arg_count)fallback) for param name anddecl_id - Looks up
@paramdoc fromDocIndexor raw NatSpec with@inheritdocresolution
- Hovering over arguments in function/event calls shows
- Gas estimates in hover, inlay hints, and code lens (#91, #94)
GasIndexbuilt from solc contract output (creation + external/internal costs)- Hover shows gas cost for functions and deploy cost for contracts
- Fire icon (🔥) with formatted numbers (e.g.
125,432)
- Use solc directly for AST + diagnostics, 11x faster on large projects (#90)
- Use solc userdoc/devdoc for hover documentation (#99)
DocIndexbuilt from solc contract output at cache time with pre-resolved@inheritdoc- Hover on parameters and return values shows
@param/@returndocs from parent function - Works at both declaration site and any usage inside the function body
- Structured rendering: notice,
@devdetails, params table, returns table - Typed selectors:
FuncSelector,EventSelector,Selectorenum,MethodIdnewtype - Replaces raw
Stringselectors throughout gas, hover, completion, and inlay hints
Refactor
- Gas inlay hints use tree-sitter positions from the live buffer (#96)
- Fixes hints drifting to wrong positions during editing
- Function gas hints support opening/closing brace placement (
FN_GAS_HINT_POSITIONconstant) - Contract deploy hints show
codeDepositCostwhentotalCostis infinite - Libraries and interfaces now show deploy cost hints
- Remove code lens — gas info is covered by inlay hints and hover (#96)
Fixes
- Improve natspec tag formatting in hover (#98)
@devnow renders with a bold**@dev**header above italic content@custom:tags and other unknown@tags render with bold label and italic content
- Bound
foundry.tomlsearch at git repo root (#89) - Hover works when file has compilation errors (#92)
Tests
- 423 total tests, 0 warnings
v0.1.20
Features
- Tree-sitter enhanced goto definition (#66, #79)
- Inlay hints v2 — tree-sitter positions + AST semantics (#61, #81)
- Respect
foundry.tomllint ignore andlint_on_buildconfig (#84, #87) - Introduce
NodeId/FileIdnewtypes and sharedSourceLocparser (#86)
Fixes
- Goto definition returns wrong result after unsaved edits (#83)
- Bound
foundry.tomlsearch at git repo root (#89)
v0.1.19
Refactor
- Rewrite
textDocument/documentSymbolandworkspace/symbolto use tree-sitter instead of Forge AST (#77, #78)- Symbols no longer depend on
forge build— works on any Solidity file immediately documentSymbolreads from text_cache with disk fallbackworkspace/symbolscans open files only
- Symbols no longer depend on
- Clean up semantic tokens to avoid overriding tree-sitter highlights (#78)
- Remove modifiers, builtin types, pragmas, variables, and member expressions from LSP tokens
- Prevents
@lsp.typemod.*priority 126-127 from overriding tree-sitter colors
Performance
textDocument/documentSymbol3.2x faster (3.24ms → 1.02ms)workspace/symbol6.4x faster (6.08ms → 0.95ms)
Features
- Add
textDocument/semanticTokens/fullvia tree-sitter (#75, #76)
Notes
Symbol kinds
The documentSymbol response returns hierarchical symbols with the following kind mappings:
| Solidity construct | LSP SymbolKind |
|---|---|
contract | CLASS |
interface | INTERFACE |
library | NAMESPACE |
function | FUNCTION |
constructor | CONSTRUCTOR |
fallback / receive | FUNCTION |
state variable | FIELD |
event | EVENT |
error | EVENT |
modifier | METHOD |
struct | STRUCT |
struct member | FIELD |
enum | ENUM |
enum value | ENUM_MEMBER |
using ... for | PROPERTY |
type ... is ... | TYPE_PARAMETER |
pragma | STRING |
import | MODULE |
Functions include a detail string with parameters and return types (e.g. (address to, uint256 amount) returns (bool)).
Contracts, structs, and enums are returned as parent symbols with their members nested as children. Top-level declarations (pragma, import, free functions, free structs/enums) appear at root level.
Semantic tokens and tree-sitter coexistence
LSP semantic tokens in Neovim have higher priority (125-127) than tree-sitter highlights (100). When both emit tokens for the same range, LSP wins. This causes problems when @lsp.typemod.* groups fall back to the generic @lsp highlight with undesirable colors.
The approach taken here: only emit semantic tokens where the LSP adds value that tree-sitter cannot provide. Let tree-sitter handle syntax it already highlights well (builtins, variables, member access, pragmas, modifiers). The LSP focuses on declaration identifiers, parameters, type references, and call targets where semantic knowledge matters.
v0.1.18
Features
- Context-sensitive
type(X).completions (#70)- Typing
type(ContractName).now showscreationCode,runtimeCode,name,interfaceId - Typing
type(IntegerType).showsmin,max
- Typing
Fixes
- Skip using-for completions on contract/library/interface names (#71, #72)
Lock.no longer returns Pool and SafeCast library functions fromusing Pool for *andusing SafeCast for *- Using-for completions now only appear when completing on a value of a matching type, not on a contract/library/interface name
- Fix SIMD chunk selection skipping past target column in
position_to_byte_offset(#73, #74)- The SIMD-accelerated position calculation introduced in #68 could pick a chunk boundary past the target column on long lines, returning the wrong byte offset
- Go-to-definition on
AlreadyUnlockedin PoolManager.sol resolved torevertWithin CustomRevert.sol instead of the correcterror AlreadyUnlocked()in IPoolManager.sol
Performance
- SIMD-accelerated position calculation via
lintspec-coreTextIndex (#68)position_to_byte_offsetandbyte_offset_to_positionnow use a single SIMD pass over 128-byte chunks instead of a full linear scan- Short linear walk (at most 128 bytes) from the nearest chunk to the exact position
Refactor
- Rewrite position conversion to use
lintspec-corecompute_indicesandTextIndex(#64, #68) - Simplify conversion functions, use builtin traits and constructors
- Improved identifier validation for Solidity keywords
v0.1.17
Fixes
- Simplify diagnostic path matching to fix silent drop (#63)
v0.1.16
Features
- Scope-aware completion with inheritance resolution (#57)
- Completions are now filtered by the current scope (contract, function, block)
- Inherited members from parent contracts are resolved and included
- Replaces the previous
fast/fullcompletion mode split with a single unified engine
Fixes
- Use relative path to filter out diagnostics (#55)
- Build diagnostic filtering now correctly matches files using relative paths
- Fixes cases where diagnostics from dependency files were incorrectly included
Deprecations
--completion-modeflag is deprecated (#59)- The
fast/fullsplit is no longer needed — scope-aware completions are always active
- The
New Contributors
- @libkakashi — chore: add Zed editor setup section in docs (#60)
Other
- Refactor build module: simplify diagnostic filtering, extract path comparison helper
- Add Zed editor setup section in docs (#60)
- 272 total tests, 0 warnings
v0.1.15
Fixes
- AST cache now updates when build has warnings but no errors (#41)
- The
build_succeededcheck useddiagnostics.is_empty()which blocked cache updates for files with unused variables or other warnings - Changed to only block on
DiagnosticSeverity::ERROR, so warnings pass through
- The
- Cross-file rename reads from in-memory editor buffers instead of disk (#50)
rename_symbolacceptstext_buffersparameter reflecting unsaved editor state- No more disk writes behind the editor's back
- Full
WorkspaceEditreturned to client for all files (#50)- Previously split edits between client (current file) and server-side
fs::write(other files) - Now the complete edit set is returned to the client
- Previously split edits between client (current file) and server-side
nameLocationsindex fallback in references (#50)- Nodes without
nameLocationsarray now correctly fall through tonameLocationorsrc
- Nodes without
- Stale AST range correction during rename (#50)
find_identifier_on_linescans the current line to correct shifted column positions after unsaved edits
- All LSP handlers read source from
text_cacheinstead ofstd::fs::read(#50) - Respect
includeDeclarationintextDocument/references(#49) - Use cached AST for
workspace/symbolinstead of rebuilding (#46) - Clear caches on
did_closeto free memory (#45) - Encoding-aware UTF-16 position conversion (#39)
- Remove document version when publishing diagnostics (#40)
- Pass
--ignore-eip-3860and--ignored-error-codes 5574to forge build (#11)
Features
- Announce full version string in LSP
initializeresponse (#51)- e.g.
0.1.15+commit.abc1234.macos.aarch64
- e.g.
Tests
- 10 new regression tests for bugs fixed in #41 and #50
tests/build.rs: warning-only builds succeed, error builds fail, empty diagnostics succeedtests/rename.rs: nameLocations fallback, text_buffers usage, cross-file WorkspaceEdit, stale AST correction, identifier extraction
- Solidity fixture files in
example/for rename tests (A.sol, B.sol, C.sol, Counter.sol) - 186 total tests, 0 warnings
New Contributors
- @beeb — fix: remove document version when publishing diagnostics (#40), filed issues #32, #33, #34, #35, #36, #37, #38, #41
Other
rustfmt.tomlandcargo fmtacross codebase (#42)- Benchmark config updated with all implemented LSP methods
v0.1.14
Fixes
textDocument/definitionandtextDocument/declarationnow return proper range width instead of zero-width ranges (#30)goto_bytes()returns(file_path, byte_offset, length)— extracts the length field fromnameLocationorsrcgoto_declaration()computesendfrombyte_offset + length, so editors correctly highlight the target symbol- Previously
start == endin the returnedLocation, making it impossible for the editor to highlight the target
Tests
- 4 new goto range-length tests:
Hooks(len 5),Pool(len 4),SafeCast(len 8), Yul external reference (nonzero) - 168 total tests, 0 warnings
v0.1.13
Features
textDocument/documentLink— every reference in a file is a clickable link- Import paths link to the imported file (resolves
absolutePathfrom AST) - All nodes with
referencedDeclarationlink to their definition viaid_to_location - Uses pre-indexed
CachedBuild.nodes— no extra AST traversal at request time
Fixes
--versionnow shows commit hash when installed from crates.io (reads.cargo_vcs_info.jsonas fallback)
Tests
- 11 document link tests (CI-safe, real fixture data from
pool-manager-ast.json) - 164 total tests, 0 warnings
v0.1.12
Features
- Cross-file "Find All References" — scans all cached AST builds to find usages across files that don't share a build scope
- Cross-file "Rename" — renames symbols across all cached builds, not just the current file's dependency tree
CachedBuildstruct — pre-computescache_ids()once per cache insert instead of N+1 times per request
Performance
cache_ids()no longer called at request time — all node indexing happens on file saveget_or_fetch_build()deduplicates cache-miss logic across goto, references, rename, hover, and document symbol handlers
Tests
- 12 new cross-file reference tests (CI-safe, hardcoded AST values from fixture)
- 153 total tests, 0 warnings
v0.1.11
Features
--version/-Vflag with full build metadata: version, commit hash, OS, architecture- GPG-signed release checksums for binary verification
CONTRIBUTING.mdwith project structure and development workflow
Improvements
- Remove redundant timestamp from tracing log output
- Add
build.rsto embed git commit hash at compile time - Add
public-key.ascfor release signature verification - Updated README with CLI usage examples, all flags, and verification instructions
v0.1.10
Features
textDocument/hover— show Solidity signatures, NatSpec documentation, and selectors on hover- Signature generation for functions, contracts, structs, enums, errors, events, modifiers, variables, UDVTs
- NatSpec formatting:
@notice,@param,@return,@devrendered as structured markdown - Display
functionSelector,errorSelector,eventSelectorfrom AST in hover output @inheritdocresolution viafunctionSelectormatching between implementation and parent interface — correctly handles overloaded functions- 25 hover tests against Uniswap v4 PoolManager AST
v0.1.8
Features
- Full completion engine with chain resolution, using-for directives, and type casts (~1400 lines, 86 tests)
--completion-modeflag:fast(default) pre-built completions,fullper-request scope filtering- Dot-completion for structs, contracts, libraries, magic globals (
msg,block,tx,abi,type) - Chain completions through function return types, mappings, type casts
using-fordirective support (e.g.PoolKey.toId(),BalanceDelta.amount0())- Method identifier completions with 4-byte selectors and full signatures
- Keyword, global function, ether/time unit completions
Performance
- Arc-based zero-copy AST cache — eliminates 7MB+ deep clones per handler request
- Non-blocking completion cache — returns static completions immediately while cache builds in background
document_symbolusesast_cacheinstead of shelling out toforge aston every request- Removed blocking
log_messagefrom completion handler to fix cancel+re-trigger lag
Yul
- Yul
externalReferencessupport for goto-definition and find-references
v0.1.7
- Yul externalReferences support for goto-definition and find-references
- Completion engine with chain resolution, using-for, and type casts
v0.1.6
- Fix rename in tests
- Fix: ignore bytecode size warnings for all sol files
- Enable goto definition for import statement strings
- Handle ImportDirective nodes in goto definition
- Add absolute_path field to NodeInfo struct
v0.1.4
- Fix: only update AST cache when build succeeds
- Fix: preserve AST cache on file changes to keep go-to-definition working during errors