Commit Graph

11 Commits

Author SHA1 Message Date
d7db53a482 feat(bicep): implement signatureHelp, foldingRange, workspace/symbol locally
All checks were successful
Build and Deploy iLSP / test (push) Successful in 22s
Build and Deploy iLSP / build-and-deploy (push) Successful in 1m26s
Bicep.LangServer 0.46.1 (latest release) does not implement these three LSP
features, so iLSP now answers them itself directly in the proxy instead of
forwarding to the underlying LS:

- textDocument/signatureHelp: curated database of ~50 commonly used Bicep
  built-in functions (resourceId, guid, concat, take, format, ...) with a
  simple bracket-depth call-context detector (ilsp/bicep_lsp/bicep_functions.py,
  ilsp/bicep_lsp/local_features.py:compute_signature_help).
- textDocument/foldingRange: stack-based bracket matcher over {}/[]/() plus
  contiguous // comment-block folding (compute_folding_ranges).
- workspace/symbol: best-effort search over documents currently open in the
  editor session (iLSP has no full-workspace index, only what's been opened),
  matching top-level resource/module/var/param/output/func/type declarations
  (compute_workspace_symbols).

The proxy now advertises these in the initialize response capabilities
(signatureHelpProvider, foldingRangeProvider, workspaceSymbolProvider) so
editors actually send the requests, and intercepts them in _client_to_ls
before they'd otherwise be silently dropped/errored by the real Bicep LS.
A send lock (_LockedConn) prevents interleaved frames now that both
_client_to_ls and _ls_to_client can write responses to the client socket.

13 new unit tests in tests/test_local_features.py. Closes the last 3 gaps
found in the full LSP capability audit.
2026-08-14 17:54:34 +02:00
dcdf22dac3 fix(bicep): stop corrupting hover/definition/references/symbols/formatting/codeAction with completion injections
All checks were successful
Build and Deploy iLSP / test (push) Successful in 21s
Build and Deploy iLSP / build-and-deploy (push) Successful in 1m32s
_ls_to_client called _inject_completions() on EVERY response with an id+result,
not just textDocument/completion responses. pop_context() defaulted to
{'type': 'unknown'} for any untracked id, which _inject_completions treats as
'inject module-name completions' — so list-shaped LS responses for
definition/references/documentSymbol/formatting/codeAction were silently
replaced or prefixed with the Bicep module catalog list instead of returning
real Bicep LangServer results.

Found via a full LSP-capability audit against production: definition,
references, documentSymbol, formatting and codeAction all incorrectly
returned module-completion items instead of real results.

Fix: pop_context() now returns None when the response id wasn't recorded as
a pending completion request, and _ls_to_client only calls
_inject_completions() when a real completion context was found — every other
response now passes through untouched.
2026-08-14 17:44:11 +02:00
Henrik Jess Nielsen
578f88a0e8 fix(bicep): support multi-line array completion for roles and other enums
All checks were successful
Build and Deploy iLSP / test (push) Successful in 22s
Build and Deploy iLSP / build-and-deploy (push) Successful in 1m35s
Adds support for autocomplete in multi-line array syntax like:

    roles: [
      'KEY_VAULT_  ← cursor triggers completion here
    ]

Previously only worked on same line as opening bracket:
    roles: ['KEY_VAULT_  ← only this worked

Changes:
- Walk backwards up to 10 lines to find array opening (e.g. "roles: [")
- Detect if cursor is inside array based on indentation and quotes
- Stop lookback if closing bracket found (not in array anymore)
- Add test case for nested multi-line array completion
- Improve lsp_bridge.py error handling with traceback logging
- Add lsp_bridge_debug.sh wrapper for easier IntelliJ debugging
- Update EDITOR_SETUP.md with correct IntelliJ LSP4IJ config

Fixes autocomplete for deeply nested structures like:
    assignments: [{ roles: ['APP_CONFIGURATION_...'] }]

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-19 13:51:17 +02:00
Henrik Jess Nielsen
aa37c259ad Roles
All checks were successful
Build and Deploy iLSP / test (push) Successful in 23s
Build and Deploy iLSP / build-and-deploy (push) Successful in 3m13s
2026-05-19 10:28:22 +02:00
Henrik Jess Nielsen
02c09f1d18 fix(bicep): always suppress LS noise in version/param/param_value contexts
All checks were successful
Build and Deploy iLSP / test (push) Successful in 22s
Build and Deploy iLSP / build-and-deploy (push) Successful in 1m31s
Previously the 'if lru_items:' guard meant that when our catalog returned
an empty list (e.g. a param with no allowed enum values), the Bicep LS
completions (Bicep keywords, schema types) would leak through unchanged.

Now the replace is unconditional for version/param/param_value contexts.
The Bicep LS has no knowledge of our private ACR registry so its output
in these positions is always noise — suppress it even when we have nothing
better to show.
2026-05-11 11:37:50 +02:00
Henrik Jess Nielsen
445ccb5769 fix(bicep): detect param context when module ref has empty version
All checks were successful
Build and Deploy iLSP / test (push) Successful in 21s
Build and Deploy iLSP / build-and-deploy (push) Successful in 1m24s
The lookback regex used ([^']+) requiring one or more version chars,
so 'br/modules:modules/keyvault:' (no version yet) silently fell through
to the unknown context and injected all module names instead of params.

Change + to * to allow empty version string. The param_completion_items
fallback already handles empty version by picking the closest schema.
2026-05-11 11:20:54 +02:00
Henrik Jess Nielsen
e7471e5dfd fix(bicep): replace LS completions entirely for version/param/param_value contexts
All checks were successful
Build and Deploy iLSP / test (push) Successful in 22s
Build and Deploy iLSP / build-and-deploy (push) Successful in 1m24s
For specific LRU contexts (version, param, param_value), the Bicep LS was
appending its own random/irrelevant completions alongside the LRU catalog
items. The LS has no knowledge of the private ACR registry, so its suggestions
in these positions are noise.

Now the LS items are discarded entirely for these three contexts. LS items
are still kept (below LRU items) for module_path and unknown contexts.
2026-05-11 11:08:47 +02:00
Henrik Jess Nielsen
b93aa84737 feat: param_value context — enum/allowed completions for principalType, environmentType etc.
All checks were successful
Build and Deploy iLSP / test (push) Successful in 20s
Build and Deploy iLSP / build-and-deploy (push) Successful in 1m20s
- Add _KNOWN_ENUMS dict (principalType, principalObjectType, environmentType fallbacks)
- Add param_value_completion_items() to BicepModuleCatalog
- Detect 'param_value' context in _detect_context() (cursor after 'param: ' inside params block)
- Wire param_value into _inject_completions()
- 9 new unit tests (context detection, catalog allowed, known enum fallback, injection)
- Fix modules.py edit regression (param_completion_items was orphaned)
- All 35 tests pass
2026-05-10 15:30:31 +02:00
Henrik Jess Nielsen
27947e4f7f feat: context-aware Bicep completions (version + param injection)
Some checks failed
Build and Deploy iLSP / test (push) Failing after 27s
Build and Deploy iLSP / build-and-deploy (push) Has been skipped
- ProxySession tracks open documents per TCP connection
- _detect_context() identifies version, param, and module_path contexts
- version context: autocomplete versions for 'br/modules:NAME:' cursor positions
- param context: autocomplete params for specific module+version (with version fallback)
- modules.py: added get_module_by_name(), version_completion_items(), param_completion_items()
- 28/28 tests passing
2026-05-10 15:04:11 +02:00
Henrik Jess Nielsen
6385e159ff fix: replace asyncio subprocess proxy with thread-based Popen proxy
Some checks failed
Build and Deploy iLSP / test (push) Failing after 12s
Build and Deploy iLSP / build-and-deploy (push) Has been skipped
asyncio subprocess PIPE unreliable for long-lived stdio bridging. Use Popen + threads instead. Also fix smoke_test.sh stdin handling.
2026-05-10 13:02:52 +02:00
Henrik Jess Nielsen
d8536468ab feat: initial iLSP project scaffolding
Some checks failed
CI / deploy (push) Has been cancelled
CI / build-and-push (push) Has been cancelled
- Python LSP (pylsp + pylsp_i80 plugin): i80 pypi package completions
- Bicep LSP (asyncio TCP proxy → Bicep.LangServer.dll): LRU module injection
- Health HTTP endpoint (:2089) for Consul/Nomad checks
- Startup catalog fetch from pypi-server.i80.dk + DevOpsMCP (no volume needed)
- Multi-stage Dockerfile: downloads Bicep LS at build time, dotnet-runtime-8.0 + python3.12
- Nomad job: static TCP ports 2087/2088, health check on 2089
- Gitea Actions CI: build + push + deploy pipeline
- Editor configs: Helix / nvim / LSP4IJ / VS Code
2026-05-10 12:23:05 +02:00