Skip to content

Commit ef8177f

Browse files
authored
Merge pull request #407 from docker/compose-fs-code-completion-improvements
Improve code completion for file structures
2 parents 041372c + d2cdd33 commit ef8177f

File tree

3 files changed

+330
-599
lines changed

3 files changed

+330
-599
lines changed

CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ All notable changes to the Docker Language Server will be documented in this fil
1010
- textDocument/completion
1111
- provide local file and folder name suggestions when modifying simple strings
1212
- service volumes ([#376](https://github.com/docker/docker-language-server/issues/376))
13-
- `env_file` of a service ([#403](https://github.com/docker/docker-language-server/issues/403))
14-
- `label_file` of a service ([#403](https://github.com/docker/docker-language-server/issues/403))
13+
- `context` attribute of a `build` object of a service ([#403](https://github.com/docker/docker-language-server/issues/403))
1514
- `dockerfile` attribute of a `build` object of a service ([#403](https://github.com/docker/docker-language-server/issues/403))
1615
- `file` attribute of a `credential_spec` object of a service ([#403](https://github.com/docker/docker-language-server/issues/403))
16+
- `env_file` of a service ([#403](https://github.com/docker/docker-language-server/issues/403))
17+
- `path` attribute of an `env_file` array item of a service ([#403](https://github.com/docker/docker-language-server/issues/403))
1718
- `file` attribute of an `extends` object of a service ([#403](https://github.com/docker/docker-language-server/issues/403))
19+
- `label_file` of a service ([#403](https://github.com/docker/docker-language-server/issues/403))
1820
- `file` attribute of a config ([#403](https://github.com/docker/docker-language-server/issues/403))
1921
- `file` attribute of a secret ([#403](https://github.com/docker/docker-language-server/issues/403))
2022

internal/compose/completion.go

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -396,25 +396,27 @@ func modifyTextEdit(file *ast.File, manager *document.Manager, documentPath docu
396396
}
397397

398398
func folderStructureCompletionItems(documentPath document.DocumentPath, path []*ast.MappingValueNode, prefix string) []protocol.CompletionItem {
399-
folder := directoryForNode(documentPath, path, prefix)
399+
folder, hideFiles := directoryForNode(documentPath, path, prefix)
400400
if folder != "" {
401401
items := []protocol.CompletionItem{}
402402
entries, _ := os.ReadDir(folder)
403403
for _, entry := range entries {
404-
item := protocol.CompletionItem{Label: entry.Name()}
405404
if entry.IsDir() {
405+
item := protocol.CompletionItem{Label: entry.Name()}
406406
item.Kind = types.CreateCompletionItemKindPointer(protocol.CompletionItemKindFolder)
407-
} else {
407+
items = append(items, item)
408+
} else if !hideFiles {
409+
item := protocol.CompletionItem{Label: entry.Name()}
408410
item.Kind = types.CreateCompletionItemKindPointer(protocol.CompletionItemKindFile)
411+
items = append(items, item)
409412
}
410-
items = append(items, item)
411413
}
412414
return items
413415
}
414416
return nil
415417
}
416418

417-
func directoryForNode(documentPath document.DocumentPath, path []*ast.MappingValueNode, prefix string) string {
419+
func directoryForNode(documentPath document.DocumentPath, path []*ast.MappingValueNode, prefix string) (folder string, hideFiles bool) {
418420
if len(path) == 3 {
419421
switch path[0].Key.GetToken().Value {
420422
case "services":
@@ -426,63 +428,72 @@ func directoryForNode(documentPath document.DocumentPath, path []*ast.MappingVal
426428
// - ...
427429
switch path[2].Key.GetToken().Value {
428430
case "env_file":
429-
return directoryForPrefix(documentPath, prefix, documentPath.Folder, false)
431+
return directoryForPrefix(documentPath, prefix, documentPath.Folder, false), false
430432
case "label_file":
431-
return directoryForPrefix(documentPath, prefix, documentPath.Folder, false)
433+
return directoryForPrefix(documentPath, prefix, documentPath.Folder, false), false
432434
case "volumes":
433-
return directoryForPrefix(documentPath, prefix, "", true)
435+
return directoryForPrefix(documentPath, prefix, "", true), false
434436
}
435437
case "configs":
436438
// configs:
437439
// configA:
438440
// file: ...
439441
if path[2].Key.GetToken().Value == "file" {
440-
return directoryForPrefix(documentPath, prefix, documentPath.Folder, false)
442+
return directoryForPrefix(documentPath, prefix, documentPath.Folder, false), false
441443
}
442444
case "secrets":
443445
// secrets:
444446
// secretA:
445447
// file: ...
446448
if path[2].Key.GetToken().Value == "file" {
447-
return directoryForPrefix(documentPath, prefix, documentPath.Folder, false)
449+
return directoryForPrefix(documentPath, prefix, documentPath.Folder, false), false
448450
}
449451
}
450452
} else if len(path) == 4 && path[0].Key.GetToken().Value == "services" {
451453
// services:
452454
// serviceA:
453455
// build:
456+
// context: ... (folders only)
454457
// dockerfile: ...
455458
// credential_spec:
456459
// file: ...
460+
// env_file:
461+
// - path: ...
457462
// extends:
458463
// file: ...
459464
// volumes:
460465
// - type: bind
461466
// source: ...
462-
if path[2].Key.GetToken().Value == "build" && path[3].Key.GetToken().Value == "dockerfile" {
463-
return directoryForPrefix(documentPath, prefix, documentPath.Folder, false)
464-
}
465-
if (path[2].Key.GetToken().Value == "extends" || path[2].Key.GetToken().Value == "credential_spec") && path[3].Key.GetToken().Value == "file" {
466-
return directoryForPrefix(documentPath, prefix, documentPath.Folder, false)
467-
}
468-
if path[2].Key.GetToken().Value == "volumes" && path[3].Key.GetToken().Value == "source" {
467+
if path[2].Key.GetToken().Value == "build" {
468+
if path[3].Key.GetToken().Value == "context" {
469+
return directoryForPrefix(documentPath, prefix, documentPath.Folder, false), true
470+
} else if path[3].Key.GetToken().Value == "dockerfile" {
471+
return directoryForPrefix(documentPath, prefix, documentPath.Folder, false), false
472+
}
473+
} else if (path[2].Key.GetToken().Value == "extends" || path[2].Key.GetToken().Value == "credential_spec") && path[3].Key.GetToken().Value == "file" {
474+
return directoryForPrefix(documentPath, prefix, documentPath.Folder, false), false
475+
} else if path[2].Key.GetToken().Value == "env_file" && path[3].Key.GetToken().Value == "path" {
476+
if _, ok := path[2].Value.(*ast.SequenceNode); ok {
477+
return directoryForPrefix(documentPath, prefix, documentPath.Folder, false), false
478+
}
479+
} else if path[2].Key.GetToken().Value == "volumes" && path[3].Key.GetToken().Value == "source" {
469480
if volumes, ok := path[2].Value.(*ast.SequenceNode); ok {
470481
for _, node := range volumes.Values {
471482
if volume, ok := node.(*ast.MappingNode); ok {
472483
if slices.Contains(volume.Values, path[3]) {
473484
for _, property := range volume.Values {
474485
if property.Key.GetToken().Value == "type" && property.Value.GetToken().Value == "bind" {
475-
return directoryForPrefix(documentPath, prefix, documentPath.Folder, true)
486+
return directoryForPrefix(documentPath, prefix, documentPath.Folder, true), false
476487
}
477488
}
478-
return ""
489+
return "", false
479490
}
480491
}
481492
}
482493
}
483494
}
484495
}
485-
return ""
496+
return "", false
486497
}
487498

488499
func directoryForPrefix(documentPath document.DocumentPath, prefix, defaultValue string, prefixRequired bool) string {

0 commit comments

Comments
 (0)