From f2cc1f5e292f6ea51bdededd76dc2f334b99b6cf Mon Sep 17 00:00:00 2001 From: eth0net Date: Mon, 10 Aug 2026 15:43:18 +0100 Subject: [PATCH 1/5] fix: send `dockercompose` as the Docker Compose language id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Docker Language Server decides whether a document gets Compose support by its LSP language id, and the id it looks for is `dockercompose`: DockerComposeLanguage LanguageIdentifier = "dockercompose" Every Compose feature in the server is gated on that value, so the hyphenated `docker-compose` we were sending would have produced no Compose behaviour at all. Verified against v0.20.1 over stdio — with `dockercompose` a compose file returns hover, document symbols and completion; with `docker-compose` or `yaml` it returns nothing. This had no effect until now, since nothing defined a `Docker Compose` language for the mapping to apply to. Co-Authored-By: Claude Opus 5 (1M context) --- extension.toml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/extension.toml b/extension.toml index e39466c..e2eeb4c 100644 --- a/extension.toml +++ b/extension.toml @@ -1,6 +1,6 @@ id = "dockerfile" name = "Dockerfile" -description = "Dockerfile support." +description = "Dockerfile and Docker Compose support." version = "0.2.1" schema_version = 1 authors = ["d1y ", "joshmeads "] @@ -17,11 +17,17 @@ languages = ["Dockerfile", "Docker Compose"] [language_servers.docker-language-server.language_ids] "Dockerfile" = "dockerfile" -"Docker Compose" = "docker-compose" +"Docker Compose" = "dockercompose" [grammars.dockerfile] repository = "https://github.com/camdencheek/tree-sitter-dockerfile" commit = "868e44ce378deb68aac902a9db68ff82d2299dd0" +# Registered as `yaml` rather than `docker-compose` so the id is snake_case and +# matches the `tree_sitter_yaml` symbol the parser exports. +[grammars.yaml] +repository = "https://github.com/zed-industries/tree-sitter-yaml" +commit = "baff0b51c64ef6a1fb1f8390f3ad6015b83ec13a" + [debug_adapters.buildx-dockerfile] schema_path = "./debug_adapter_schemas/buildx-dockerfile.json" From 7484a7a16ca2f7b95cd82a6a9623bdf530e0eaaf Mon Sep 17 00:00:00 2001 From: eth0net Date: Mon, 10 Aug 2026 15:43:18 +0100 Subject: [PATCH 2/5] feat: add the Docker Compose language MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moves the Docker Compose language definition in from eth0net/zed-docker-compose, so Compose support lives alongside the Docker Language Server that already ships here rather than duplicating it in a separate extension. Compose files get their own language rather than extending YAML, which keeps the server off plain YAML files and gives services runnables — each entry under `services:` can be started from the gutter via docker compose, docker-compose, podman compose or podman-compose. The grammar is registered as `yaml` rather than `docker-compose` because grammar ids must be snake_case and must match the symbol the parser exports, which for tree-sitter-yaml is `tree_sitter_yaml`. Highlight queries are copied from Zed's own YAML queries, since queries can't be shared between languages. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 14 ++++++- languages/docker-compose/brackets.scm | 3 ++ languages/docker-compose/config.toml | 27 +++++++++++++ languages/docker-compose/highlights.scm | 51 +++++++++++++++++++++++++ languages/docker-compose/outline.scm | 1 + languages/docker-compose/redactions.scm | 1 + languages/docker-compose/runnables.scm | 6 +++ languages/docker-compose/tasks.json | 22 +++++++++++ 8 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 languages/docker-compose/brackets.scm create mode 100644 languages/docker-compose/config.toml create mode 100644 languages/docker-compose/highlights.scm create mode 100644 languages/docker-compose/outline.scm create mode 100644 languages/docker-compose/redactions.scm create mode 100644 languages/docker-compose/runnables.scm create mode 100644 languages/docker-compose/tasks.json diff --git a/README.md b/README.md index 43a730f..2183176 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,17 @@ # Dockerfile Zed Extension -- Tree Sitter: [tree-sitter-dockerfile](https://github.com/camdencheek/tree-sitter-dockerfile) -- Language Server: [dockerfile-language-server](https://github.com/rcjsuen/dockerfile-language-server) +- Tree Sitter: [tree-sitter-dockerfile](https://github.com/camdencheek/tree-sitter-dockerfile), [tree-sitter-yaml](https://github.com/zed-industries/tree-sitter-yaml) +- Language Server: [dockerfile-language-server](https://github.com/rcjsuen/dockerfile-language-server), [docker-language-server](https://github.com/docker/docker-language-server) + +## Docker Compose + +Compose files are given their own `Docker Compose` language, matched on +`compose.yaml`, `compose.yml`, `docker-compose.yaml` and `docker-compose.yml`. +Plain YAML files are unaffected. + +Each entry under `services:` gets a runnable, so a single service can be started +from the gutter. `docker compose`, `docker-compose`, `podman compose` and +`podman-compose` are all offered. ## Configuration diff --git a/languages/docker-compose/brackets.scm b/languages/docker-compose/brackets.scm new file mode 100644 index 0000000..9e8c9cd --- /dev/null +++ b/languages/docker-compose/brackets.scm @@ -0,0 +1,3 @@ +("[" @open "]" @close) +("{" @open "}" @close) +("\"" @open "\"" @close) diff --git a/languages/docker-compose/config.toml b/languages/docker-compose/config.toml new file mode 100644 index 0000000..e7720a1 --- /dev/null +++ b/languages/docker-compose/config.toml @@ -0,0 +1,27 @@ +# Adjusted from https://github.com/zed-industries/zed/blob/f2ab00cec7545ffb7d8d75e4ccab74d5fccccf9b/crates/languages/src/yaml/config.toml +name = "Docker Compose" +grammar = "yaml" +path_suffixes = [ + "docker-compose.yml", + "docker-compose.yaml", + "compose.yaml", + "compose.yml", +] +line_comments = ["# "] +autoclose_before = ",]}" +brackets = [ + { start = "{", end = "}", close = true, newline = true }, + { start = "[", end = "]", close = true, newline = true }, + { start = "\"", end = "\"", close = true, newline = false, not_in = [ + "string", + ] }, + { start = "'", end = "'", close = true, newline = false, not_in = [ + "string", + ] }, +] + +auto_indent_on_paste = false +auto_indent_using_last_non_empty_line = false +increase_indent_pattern = ":\\s*[|>]?\\s*$" +prettier_parser_name = "yaml" +tab_size = 2 diff --git a/languages/docker-compose/highlights.scm b/languages/docker-compose/highlights.scm new file mode 100644 index 0000000..89f8d48 --- /dev/null +++ b/languages/docker-compose/highlights.scm @@ -0,0 +1,51 @@ +; Taken from https://github.com/zed-industries/zed/blob/f2ab00cec7545ffb7d8d75e4ccab74d5fccccf9b/crates/languages/src/yaml/highlights.scm +; as the "Docker Compose" language shares the grammar zed uses for YAML +(boolean_scalar) @boolean +(null_scalar) @constant.builtin + +[ + (double_quote_scalar) + (single_quote_scalar) + (block_scalar) + (string_scalar) +] @string + +(escape_sequence) @string.escape + +[ + (integer_scalar) + (float_scalar) +] @number + +(comment) @comment + +[ + (anchor_name) + (alias_name) + (tag) +] @type + +key: (flow_node (plain_scalar (string_scalar) @property)) + +[ + "," + "-" + ":" + ">" + "?" + "|" +] @punctuation.delimiter + +[ + "[" + "]" + "{" + "}" +] @punctuation.bracket + +[ + "*" + "&" + "---" + "..." +] @punctuation.special diff --git a/languages/docker-compose/outline.scm b/languages/docker-compose/outline.scm new file mode 100644 index 0000000..7ab0078 --- /dev/null +++ b/languages/docker-compose/outline.scm @@ -0,0 +1 @@ +(block_mapping_pair key: (flow_node (plain_scalar (string_scalar) @name))) @item diff --git a/languages/docker-compose/redactions.scm b/languages/docker-compose/redactions.scm new file mode 100644 index 0000000..85fdbd2 --- /dev/null +++ b/languages/docker-compose/redactions.scm @@ -0,0 +1 @@ +(block_mapping_pair value: (flow_node) @redact) diff --git a/languages/docker-compose/runnables.scm b/languages/docker-compose/runnables.scm new file mode 100644 index 0000000..2886686 --- /dev/null +++ b/languages/docker-compose/runnables.scm @@ -0,0 +1,6 @@ +(document (block_node (block_mapping (block_mapping_pair + key: _ @_services + value: (block_node (block_mapping (block_mapping_pair + key: _ @service @run))) + (#eq? @_services "services") + (#set! tag docker-compose-service))))) diff --git a/languages/docker-compose/tasks.json b/languages/docker-compose/tasks.json new file mode 100644 index 0000000..c1584f8 --- /dev/null +++ b/languages/docker-compose/tasks.json @@ -0,0 +1,22 @@ +[ + { + "label": "docker-compose run", + "command": "docker-compose -f $ZED_FILE run $ZED_CUSTOM_service", + "tags": ["docker-compose-service"] + }, + { + "label": "docker compose run", + "command": "docker compose -f $ZED_FILE run $ZED_CUSTOM_service", + "tags": ["docker-compose-service"] + }, + { + "label": "podman-compose run", + "command": "podman-compose -f $ZED_FILE run $ZED_CUSTOM_service", + "tags": ["docker-compose-service"] + }, + { + "label": "podman compose run", + "command": "podman compose -f $ZED_FILE run $ZED_CUSTOM_service", + "tags": ["docker-compose-service"] + } +] From a259b507ebd90afcd44c025baace5096f0868d6b Mon Sep 17 00:00:00 2001 From: eth0net Date: Mon, 10 Aug 2026 16:27:32 +0100 Subject: [PATCH 3/5] fix: bring the Compose queries in line with Zed's YAML MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The queries carried over were derived from Zed's YAML language as it stood in early 2024 and had drifted, in ways that matter: - brackets.scm was missing the single-quote pair, so `'` auto-closed per config.toml but never highlighted as a matched pair - overrides.scm was absent entirely, which is what defines the `string` override that the `not_in = ["string"]` clauses on the quote brackets refer to — without it those clauses have nothing to match and quotes auto-close inside strings - increase_indent_pattern predates Zed's fix for comments and for the first element of an array of objects - outline.scm now also captures the value as @context, giving outline entries their value rather than just the key Also corrects the README: the service runnables invoke `compose run`, which starts a one-off container, not `compose up `. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 7 ++++--- languages/docker-compose/brackets.scm | 16 +++++++++++++--- languages/docker-compose/config.toml | 7 +++++-- languages/docker-compose/outline.scm | 8 +++++++- languages/docker-compose/overrides.scm | 6 ++++++ languages/docker-compose/redactions.scm | 3 ++- 6 files changed, 37 insertions(+), 10 deletions(-) create mode 100644 languages/docker-compose/overrides.scm diff --git a/README.md b/README.md index 2183176..fb48e92 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,10 @@ Compose files are given their own `Docker Compose` language, matched on `compose.yaml`, `compose.yml`, `docker-compose.yaml` and `docker-compose.yml`. Plain YAML files are unaffected. -Each entry under `services:` gets a runnable, so a single service can be started -from the gutter. `docker compose`, `docker-compose`, `podman compose` and -`podman-compose` are all offered. +Each entry under `services:` gets a runnable, so a single service can be run from +the gutter via `compose run` — which starts a one-off container for that service +rather than bringing the service up. `docker compose`, `docker-compose`, +`podman compose` and `podman-compose` are all offered. ## Configuration diff --git a/languages/docker-compose/brackets.scm b/languages/docker-compose/brackets.scm index 9e8c9cd..edeb53a 100644 --- a/languages/docker-compose/brackets.scm +++ b/languages/docker-compose/brackets.scm @@ -1,3 +1,13 @@ -("[" @open "]" @close) -("{" @open "}" @close) -("\"" @open "\"" @close) +("[" @open + "]" @close) + +("{" @open + "}" @close) + +(("\"" @open + "\"" @close) + (#set! rainbow.exclude)) + +(("'" @open + "'" @close) + (#set! rainbow.exclude)) diff --git a/languages/docker-compose/config.toml b/languages/docker-compose/config.toml index e7720a1..ed48298 100644 --- a/languages/docker-compose/config.toml +++ b/languages/docker-compose/config.toml @@ -1,4 +1,5 @@ -# Adjusted from https://github.com/zed-industries/zed/blob/f2ab00cec7545ffb7d8d75e4ccab74d5fccccf9b/crates/languages/src/yaml/config.toml +# Adjusted from Zed's own YAML config, crates/grammars/src/yaml/config.toml, +# since this language shares the grammar Zed uses for YAML. name = "Docker Compose" grammar = "yaml" path_suffixes = [ @@ -22,6 +23,8 @@ brackets = [ auto_indent_on_paste = false auto_indent_using_last_non_empty_line = false -increase_indent_pattern = ":\\s*[|>]?\\s*$" +# 1st block matches basic elements followed by ':', e.g. 'test: ' +# 2nd block matches the first element of an array when it's an object +increase_indent_pattern = "(:?^[^#]*:\\s*[|>]?\\s*$)|(:?^\\s*-[^#]*:\\s*(:?#+.*)$)" prettier_parser_name = "yaml" tab_size = 2 diff --git a/languages/docker-compose/outline.scm b/languages/docker-compose/outline.scm index 7ab0078..a41447b 100644 --- a/languages/docker-compose/outline.scm +++ b/languages/docker-compose/outline.scm @@ -1 +1,7 @@ -(block_mapping_pair key: (flow_node (plain_scalar (string_scalar) @name))) @item +(block_mapping_pair + key: (flow_node + (plain_scalar + (string_scalar) @name)) + value: (flow_node + (plain_scalar + (string_scalar) @context))?) @item diff --git a/languages/docker-compose/overrides.scm b/languages/docker-compose/overrides.scm new file mode 100644 index 0000000..99c991e --- /dev/null +++ b/languages/docker-compose/overrides.scm @@ -0,0 +1,6 @@ +(comment) @comment.inclusive + +[ + (single_quote_scalar) + (double_quote_scalar) +] @string diff --git a/languages/docker-compose/redactions.scm b/languages/docker-compose/redactions.scm index 85fdbd2..56c7415 100644 --- a/languages/docker-compose/redactions.scm +++ b/languages/docker-compose/redactions.scm @@ -1 +1,2 @@ -(block_mapping_pair value: (flow_node) @redact) +(block_mapping_pair + value: (flow_node) @redact) From edc48e4510258b5dc7a776b5fd2e4f9279796f57 Mon Sep 17 00:00:00 2001 From: eth0net Date: Mon, 10 Aug 2026 16:38:11 +0100 Subject: [PATCH 4/5] feat: add up and down runnables for compose services Only `run` was offered, which starts a one-off container. `up` and `down` are what you reach for to actually bring a service up and tear it back down. All four tools accept a positional service name for both: `docker compose` and the v2 `docker-compose` standalone per `[SERVICE...]` in the CLI reference, and podman-compose per its own argparse, which registers positional services for `["build", "up", "down", "start", "stop", "restart"]`. `up` is left attached rather than passing -d, so logs land in the task terminal, matching how `run` behaves. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 15 ++++++++--- languages/docker-compose/tasks.json | 40 +++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index fb48e92..46a3aa6 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,17 @@ Compose files are given their own `Docker Compose` language, matched on `compose.yaml`, `compose.yml`, `docker-compose.yaml` and `docker-compose.yml`. Plain YAML files are unaffected. -Each entry under `services:` gets a runnable, so a single service can be run from -the gutter via `compose run` — which starts a one-off container for that service -rather than bringing the service up. `docker compose`, `docker-compose`, -`podman compose` and `podman-compose` are all offered. +Each entry under `services:` gets runnables, so a single service can be brought +up, run and taken down from the gutter: + +| Task | Effect | +| --- | --- | +| `up` | starts the service and its dependencies, attached so logs appear in the terminal | +| `run` | starts a one-off container for the service | +| `down` | stops and removes the service's containers | + +Each is offered for `docker compose`, `docker-compose`, `podman compose` and +`podman-compose`. ## Configuration diff --git a/languages/docker-compose/tasks.json b/languages/docker-compose/tasks.json index c1584f8..688d813 100644 --- a/languages/docker-compose/tasks.json +++ b/languages/docker-compose/tasks.json @@ -1,22 +1,62 @@ [ + { + "label": "docker-compose up", + "command": "docker-compose -f $ZED_FILE up $ZED_CUSTOM_service", + "tags": ["docker-compose-service"] + }, { "label": "docker-compose run", "command": "docker-compose -f $ZED_FILE run $ZED_CUSTOM_service", "tags": ["docker-compose-service"] }, + { + "label": "docker-compose down", + "command": "docker-compose -f $ZED_FILE down $ZED_CUSTOM_service", + "tags": ["docker-compose-service"] + }, + { + "label": "docker compose up", + "command": "docker compose -f $ZED_FILE up $ZED_CUSTOM_service", + "tags": ["docker-compose-service"] + }, { "label": "docker compose run", "command": "docker compose -f $ZED_FILE run $ZED_CUSTOM_service", "tags": ["docker-compose-service"] }, + { + "label": "docker compose down", + "command": "docker compose -f $ZED_FILE down $ZED_CUSTOM_service", + "tags": ["docker-compose-service"] + }, + { + "label": "podman-compose up", + "command": "podman-compose -f $ZED_FILE up $ZED_CUSTOM_service", + "tags": ["docker-compose-service"] + }, { "label": "podman-compose run", "command": "podman-compose -f $ZED_FILE run $ZED_CUSTOM_service", "tags": ["docker-compose-service"] }, + { + "label": "podman-compose down", + "command": "podman-compose -f $ZED_FILE down $ZED_CUSTOM_service", + "tags": ["docker-compose-service"] + }, + { + "label": "podman compose up", + "command": "podman compose -f $ZED_FILE up $ZED_CUSTOM_service", + "tags": ["docker-compose-service"] + }, { "label": "podman compose run", "command": "podman compose -f $ZED_FILE run $ZED_CUSTOM_service", "tags": ["docker-compose-service"] + }, + { + "label": "podman compose down", + "command": "podman compose -f $ZED_FILE down $ZED_CUSTOM_service", + "tags": ["docker-compose-service"] } ] From f8d7e934404b9d130118a3c404d8cf187225201a Mon Sep 17 00:00:00 2001 From: MrSubidubi Date: Fri, 21 Aug 2026 13:50:58 +0200 Subject: [PATCH 5/5] fmt --- languages/docker-compose/highlights.scm | 5 ++++- languages/docker-compose/runnables.scm | 17 +++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/languages/docker-compose/highlights.scm b/languages/docker-compose/highlights.scm index 89f8d48..246e241 100644 --- a/languages/docker-compose/highlights.scm +++ b/languages/docker-compose/highlights.scm @@ -1,6 +1,7 @@ ; Taken from https://github.com/zed-industries/zed/blob/f2ab00cec7545ffb7d8d75e4ccab74d5fccccf9b/crates/languages/src/yaml/highlights.scm ; as the "Docker Compose" language shares the grammar zed uses for YAML (boolean_scalar) @boolean + (null_scalar) @constant.builtin [ @@ -25,7 +26,9 @@ (tag) ] @type -key: (flow_node (plain_scalar (string_scalar) @property)) +key: (flow_node + (plain_scalar + (string_scalar) @property)) [ "," diff --git a/languages/docker-compose/runnables.scm b/languages/docker-compose/runnables.scm index 2886686..177404e 100644 --- a/languages/docker-compose/runnables.scm +++ b/languages/docker-compose/runnables.scm @@ -1,6 +1,11 @@ -(document (block_node (block_mapping (block_mapping_pair - key: _ @_services - value: (block_node (block_mapping (block_mapping_pair - key: _ @service @run))) - (#eq? @_services "services") - (#set! tag docker-compose-service))))) +(document + (block_node + (block_mapping + (block_mapping_pair + key: _ @_services + value: (block_node + (block_mapping + (block_mapping_pair + key: _ @service @run))) + (#eq? @_services "services") + (#set! tag docker-compose-service)))))