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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions