Skip to content

Commit df5aa76

Browse files
committed
Include required properties automatically in Compose code completions
If an object has a required attribute, then we should automatically include that attribute in the completion item to make it easier for users to write Compose files. Signed-off-by: Remy Suen <[email protected]>
1 parent 673bf68 commit df5aa76

File tree

2 files changed

+1258
-935
lines changed

2 files changed

+1258
-935
lines changed

internal/compose/completion.go

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ func Completion(ctx context.Context, params *protocol.CompletionParams, doc docu
138138
End: params.Position,
139139
},
140140
},
141-
InsertTextMode: types.CreateInsertTextModePointer(protocol.InsertTextModeAsIs),
141+
InsertTextMode: types.CreateInsertTextModePointer(protocol.InsertTextModeAsIs),
142+
InsertTextFormat: types.CreateInsertTextFormatPointer(protocol.InsertTextFormatSnippet),
142143
}
143144

144145
if schema.Enum != nil {
@@ -167,7 +168,6 @@ func Completion(ctx context.Context, params *protocol.CompletionParams, doc docu
167168
End: params.Position,
168169
},
169170
}
170-
item.InsertTextFormat = types.CreateInsertTextFormatPointer(protocol.InsertTextFormatSnippet)
171171
}
172172
items = append(items, item)
173173
}
@@ -363,10 +363,56 @@ func extractDetail(schema *jsonschema.Schema) *string {
363363
return types.CreateStringPointer(strings.Join(schemaTypes, " or "))
364364
}
365365

366+
func requiredFieldsText(spacing string, schema *jsonschema.Schema, schemaTypes []string) []string {
367+
if len(schemaTypes) == 1 {
368+
if slices.Contains(schemaTypes, "array") {
369+
if schema.Ref != nil {
370+
schema = schema.Ref
371+
}
372+
if itemSchema, ok := schema.Items.(*jsonschema.Schema); ok {
373+
if itemSchema.Ref != nil {
374+
itemSchema = itemSchema.Ref
375+
}
376+
if itemSchema.Types != nil {
377+
if slices.Contains(itemSchema.Types.ToStrings(), "object") {
378+
requiredTexts := []string{}
379+
for _, r := range itemSchema.Required {
380+
requiredTexts = append(requiredTexts, insertText(fmt.Sprintf("%v ", spacing), r, itemSchema.Properties[r]))
381+
}
382+
return requiredTexts
383+
}
384+
}
385+
}
386+
}
387+
}
388+
return nil
389+
}
390+
366391
func insertText(spacing, attributeName string, schema *jsonschema.Schema) string {
367392
schemaTypes := referencedTypes(schema)
368393
if slices.Contains(schemaTypes, "array") {
369394
if len(schemaTypes) == 1 {
395+
required := requiredFieldsText(spacing, schema, schemaTypes)
396+
if len(required) > 0 {
397+
slices.Sort(required)
398+
sb := strings.Builder{}
399+
sb.WriteString(attributeName)
400+
sb.WriteString(":")
401+
for i, requiredAttribute := range required {
402+
sb.WriteString("\n")
403+
sb.WriteString(spacing)
404+
if i == 0 {
405+
sb.WriteString("- ")
406+
} else {
407+
sb.WriteString(" ")
408+
}
409+
sb.WriteString(requiredAttribute)
410+
if len(required) != 1 {
411+
sb.WriteString(fmt.Sprintf("${%v}", i+1))
412+
}
413+
}
414+
return sb.String()
415+
}
370416
return fmt.Sprintf("%v:\n%v- ", attributeName, spacing)
371417
} else if len(schemaTypes) == 2 && slices.Contains(schemaTypes, "object") {
372418
return fmt.Sprintf("%v:\n%v", attributeName, spacing)

0 commit comments

Comments
 (0)