Skip to content

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

@kodi0309

Description

@kodi0309

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions