redhat-developer / redhat-developer/yaml-language-server

Required keys with enum are skipped by multi-required completion unless typed manually

Open
#1,134 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
1.5k
Forks
352
Avg merge
2d 7h
Merged PRs (30d)
11

Description

Title

Required keys with enum are skipped by multi-required completion


Description

When an object has multiple required properties and one of them has an enum constraint, pressing completion (Ctrl+Space) to insert all missing required keys skips the enum-constrained key.

The key must be added individually before enum value suggestions appear.
This breaks the “insert all required keys” flow.


Minimal schema to reproduce

type: object
required: [mode, name, version]
properties:
  mode:
    type: string
    enum: ["auto", "manual"]
    # optional:
    # default: "auto"
  name:
    type: string
  version:
    type: string

Steps to reproduce

  1. Create an empty YAML object.
  2. Trigger completion (Ctrl+Space) inside it.
  3. Accept the suggestion that inserts all missing required keys.

Expected behavior

  • All three required keys (mode, name, version) are inserted.
  • For mode:
    • If default exists and default ∈ enum, insert mode: <default>.
    • Otherwise insert mode: with an empty value so enum suggestions can appear.

Actual behavior

  • Only name and version are inserted.
  • mode (with enum) is skipped and must be added manually.

Root cause (analysis)

In src/languageservice/services/yamlCompletion.ts, the path that builds the multi-required snippet effectively excludes properties with enum because there’s no default/value to insert.

That early exit prevents such keys from being included in the “insert all required” snippet.


Proposed fix

When building the multi-required insertion:

  1. Always include enum-constrained properties.
  2. If default exists and is a member of enum, insert key: <default>.
  3. Else insert key: (empty placeholder) so enum value completions can appear.

Draft patch

diff --git a/src/languageservice/services/yamlCompletion.ts b/src/languageservice/services/yamlCompletion.ts
index 0000000..1111111 100644
--- a/src/languageservice/services/yamlCompletion.ts
+++ b/src/languageservice/services/yamlCompletion.ts
@@ -1,6 +1,29 @@
 // ... existing imports
+import { JSONSchema } from '../jsonSchemaTypes'; // adjust import if needed
+
+function defaultInsertForProperty(propName: string, schema: JSONSchema | undefined): string {
+  if (!schema) {
+    return `${propName}: `;
+  }
+  const hasEnum = Array.isArray(schema.enum) && schema.enum.length > 0;
+  const hasDefault = Object.prototype.hasOwnProperty.call(schema, 'default');
+  if (hasEnum) {
+    if (hasDefault && (schema.enum as unknown[]).includes((schema as any).default)) {
+      return `${propName}: ${String((schema as any).default)}`;
+    }
+    return `${propName}: `;
+  }
+  if (hasDefault) {
+    return `${propName}: ${String((schema as any).default)}`;
+  }
+  return `${propName}: `;
+}
 
 // inside the function that creates the "insert all required" snippet,
 // look for the loop over missing required properties and adjust it:
 
-// before (conceptually):
-// if (propSchema.enum) { /* skip from multi-insert */ } else { add to snippet with default/empty }
+// after:
+// always include the property; if enum + default∈enum -> use default, else empty value

Test plan

  • Unit tests: Add a schema with multiple required props including one with enum.
    • Case A: with defaultenum → inserted with default.
    • Case B: with no default or invalid default → inserted with empty value.
  • Manual test: With the schema above, trigger completion in an empty object.
    • Expected: mode, name, and version all inserted; mode uses default if valid, else empty.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/languageservice/services/yamlCompletion.ts and trace the loop that builds the multi-required insertion snippet, especially how enum-constrained properties are handled. Add unit coverage for valid enum defaults and missing or invalid defaults, then verify completion inserts mode, name, and version as described in the issue.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.