diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ac7924..4e4fefb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to the Docker Language Server will be documented in this fil - Compose - textDocument/completion - prevent errors if an empty JSON object is the content of the YAML file ([#330](https://github.com/docker/docker-language-server/issues/330)) + - check character offset before processing to prevent errors ([#333](https://github.com/docker/docker-language-server/issues/333)) ## [0.12.0] - 2025-06-12 diff --git a/internal/compose/completion.go b/internal/compose/completion.go index a92605c..49bbb1c 100644 --- a/internal/compose/completion.go +++ b/internal/compose/completion.go @@ -442,8 +442,9 @@ func buildTargetCompletionItems(params *protocol.CompletionParams, manager *docu } else if prefix, ok := path[3].Value.(*ast.StringNode); ok { if int(params.Position.Line) == path[3].Value.GetToken().Position.Line-1 { offset := int(params.Position.Character) - path[3].Value.GetToken().Position.Column + 1 - // offset can be greater than the length if there's just empty whitespace after the string value - if offset <= len(prefix.Value) { + // offset can be greater than the length if there's just empty whitespace after the string value, + // must be non-negative, if negative it suggests the cursor is in the whitespace before the attribute's value + if offset >= 0 && offset <= len(prefix.Value) { return createBuildStageItems(params, manager, dockerfilePath, prefix.Value[0:offset], prefixLength), true } } diff --git a/internal/compose/completion_test.go b/internal/compose/completion_test.go index 1aaf8e1..4af99d2 100644 --- a/internal/compose/completion_test.go +++ b/internal/compose/completion_test.go @@ -4269,6 +4269,20 @@ services: } }, }, + { + name: "target attribute finds nothing", + dockerfileContent: "FROM scratch", + content: ` +services: + postgres: + build: + target: base`, + line: 4, + character: 14, + list: func() *protocol.CompletionList { + return nil + }, + }, } composeFileURI := fmt.Sprintf("file:///%v", strings.TrimPrefix(filepath.ToSlash(filepath.Join(os.TempDir(), "compose.yaml")), "/"))