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.
This commit is contained in:
Henrik Jess Nielsen
2026-05-11 11:08:47 +02:00
parent 3b7c29d1e6
commit e7471e5dfd
2 changed files with 22 additions and 13 deletions

View File

@@ -202,14 +202,24 @@ def _inject_completions(msg: dict[str, Any], context: dict | None = None) -> byt
lru_items = BicepModuleCatalog.as_completion_items() lru_items = BicepModuleCatalog.as_completion_items()
if lru_items: if lru_items:
for item in items: if ctx_type in ("version", "param", "param_value"):
st = item.get("sortText", item.get("label", "")) # Replace LS completions entirely — the Bicep LS doesn't know about
item["sortText"] = f"1_az_{st}" # the private registry, so its suggestions here are noise/random.
if isinstance(result, list): if isinstance(result, list):
msg["result"] = lru_items + items msg["result"] = lru_items
else:
result["items"] = lru_items
result["isIncomplete"] = False
else: else:
result["items"] = lru_items + items # module_path / unknown: keep LS completions below ours
result["isIncomplete"] = True for item in items:
st = item.get("sortText", item.get("label", ""))
item["sortText"] = f"1_az_{st}"
if isinstance(result, list):
msg["result"] = lru_items + items
else:
result["items"] = lru_items + items
result["isIncomplete"] = True
return json.dumps(msg).encode() return json.dumps(msg).encode()

View File

@@ -102,9 +102,9 @@ def test_version_completions_injected_on_version_context():
assert "1.1.x" in labels assert "1.1.x" in labels
assert "2.0.x" in labels assert "2.0.x" in labels
assert "latest" in labels assert "latest" in labels
# LRU versions come first # LS items are replaced entirely — private registry versions only
assert items[0]["sortText"].startswith("0_lru_ver_") assert all(i["sortText"].startswith("0_lru_ver_") for i in items)
assert items[-1]["sortText"].startswith("1_az_") assert not any(i["label"] == "az-builtin" for i in items)
def test_version_items_include_param_detail(): def test_version_items_include_param_detail():
@@ -366,9 +366,8 @@ def test_param_value_injected_in_completion_response():
"param": "environmentType", "has_open_quote": False} "param": "environmentType", "has_open_quote": False}
out = json.loads(_inject_completions(msg, ctx)) out = json.loads(_inject_completions(msg, ctx))
labels = [i["label"] for i in out["result"]["items"]] labels = [i["label"] for i in out["result"]["items"]]
# LRU enum values should be first # LRU enum values only — LS completions are replaced entirely
assert labels[:3] == ["DEV", "TEST", "PROD"] assert labels == ["DEV", "TEST", "PROD"]
assert "existing" in labels
def test_detect_unknown_context_outside_module(): def test_detect_unknown_context_outside_module():