Unnamed repository; edit this file 'description' to name the repository.
feat(languages): add `gitlab-ci` language specialized from `yaml` (#14396)
| -rw-r--r-- | book/src/generated/lang-support.md | 1 | ||||
| -rw-r--r-- | languages.toml | 11 | ||||
| -rw-r--r-- | runtime/queries/gitlab-ci/highlights.scm | 89 | ||||
| -rw-r--r-- | runtime/queries/gitlab-ci/indents.scm | 1 | ||||
| -rw-r--r-- | runtime/queries/gitlab-ci/injections.scm | 51 | ||||
| -rw-r--r-- | runtime/queries/gitlab-ci/rainbows.scm | 1 | ||||
| -rw-r--r-- | runtime/queries/gitlab-ci/tags.scm | 17 | ||||
| -rw-r--r-- | runtime/queries/gitlab-ci/textobjects.scm | 1 | ||||
| -rw-r--r-- | runtime/queries/yaml/injections.scm | 9 |
9 files changed, 176 insertions, 5 deletions
diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index c8511ccf..0fdf738d 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -86,6 +86,7 @@ | git-ignore | ✓ | | | | | | | git-notes | ✓ | | | | | | | git-rebase | ✓ | | | | | | +| gitlab-ci | ✓ | ✓ | ✓ | ✓ | ✓ | `yaml-language-server`, `gitlab-ci-ls` | | gjs | ✓ | ✓ | ✓ | ✓ | | `typescript-language-server`, `vscode-eslint-language-server`, `ember-language-server` | | gleam | ✓ | ✓ | | | ✓ | `gleam` | | glimmer | ✓ | | | | | `ember-language-server` | diff --git a/languages.toml b/languages.toml index 175afc81..49048918 100644 --- a/languages.toml +++ b/languages.toml @@ -50,6 +50,7 @@ forc = { command = "forc", args = ["lsp"] } forth-lsp = { command = "forth-lsp" } fortls = { command = "fortls", args = ["--lowercase_intrinsics"] } fsharp-ls = { command = "fsautocomplete", config = { AutomaticWorkspaceInit = true } } +gitlab-ci-ls = { command = "gitlab-ci-ls" } gleam = { command = "gleam", args = ["lsp"] } glsl_analyzer = { command = "glsl_analyzer" } graphql-language-service = { command = "graphql-lsp", args = ["server", "-m", "stream"] } @@ -4775,3 +4776,13 @@ comment-token = "#" block-comment-tokens = { start = "/*", end = "*/" } indent = { tab-width = 2, unit = " " } language-servers = ["docker-language-server"] + +[[language]] +name = "gitlab-ci" +scope = "source.gitlab-ci" +injection-regex = "^gitlab-ci$" +file-types = [{ glob = ".gitlab-ci.yml" }] +grammar = "yaml" +indent = { tab-width = 2, unit = " " } +language-servers = ["yaml-language-server", "gitlab-ci-ls"] +comment-token = "#" diff --git a/runtime/queries/gitlab-ci/highlights.scm b/runtime/queries/gitlab-ci/highlights.scm new file mode 100644 index 00000000..1891c000 --- /dev/null +++ b/runtime/queries/gitlab-ci/highlights.scm @@ -0,0 +1,89 @@ +(boolean_scalar) @constant.builtin.boolean +(null_scalar) @constant.builtin +(double_quote_scalar) @string +(single_quote_scalar) @string +(block_scalar) @string +(string_scalar) @string +(escape_sequence) @constant.character.escape +(integer_scalar) @constant.numeric.integer +(float_scalar) @constant.numeric.float +(comment) @comment +(anchor_name) @type +(alias_name) @type +(tag) @type +(yaml_directive) @keyword + +(block_mapping_pair + key: (flow_node [(double_quote_scalar) (single_quote_scalar)] @variable.other.member)) +(block_mapping_pair + key: (flow_node (plain_scalar (string_scalar) @variable.other.member))) + +(flow_mapping + (_ key: (flow_node [(double_quote_scalar) (single_quote_scalar)] @variable.other.member))) +(flow_mapping + (_ key: (flow_node (plain_scalar (string_scalar) @variable.other.member)))) + +[ +"," +"-" +":" +">" +"?" +"|" +] @punctuation.delimiter + +[ +"[" +"]" +"{" +"}" +] @punctuation.bracket + +["*" "&" "---" "..."] @punctuation.special + + +; Highlight the toplevel keys differently as keywords +(block_mapping_pair + key: (flow_node (plain_scalar (string_scalar) @keyword (#any-of? @keyword "variables" "stages" "default" "include" "workflow"))) ) + +; Highlight the builtin stages differently +; <https://docs.gitlab.com/ci/yaml/#stages> +(block_mapping_pair + key: (flow_node + (plain_scalar + (string_scalar) @variable.other.member (#eq? @variable.other.member "stage"))) + value: (flow_node + (plain_scalar + (string_scalar) @constant.builtin (#any-of? @constant.builtin ".pre" "build" "test" "deploy" ".post")))) +; e.g. +; ``` +; stages: +; - build +; - test +; ``` +(block_mapping_pair + key: (flow_node + (plain_scalar + (string_scalar) @keyword (#eq? @keyword "stages"))) + value: (block_node + (block_sequence + (block_sequence_item + (flow_node + (plain_scalar + (string_scalar) @constant.builtin (#any-of? @constant.builtin ".pre" "build" "test" "deploy" ".post"))))))) + + +; Highlight defined variable names as @variable +; Matches on: +; ``` +; variables: +; <variable>: ... +; ``` +(block_mapping_pair + key: (flow_node + (plain_scalar + (string_scalar) @keyword (#eq? @keyword "variables"))) + value: (block_node + (block_mapping + (block_mapping_pair + key: (flow_node) @variable)+))) diff --git a/runtime/queries/gitlab-ci/indents.scm b/runtime/queries/gitlab-ci/indents.scm new file mode 100644 index 00000000..4ba254e8 --- /dev/null +++ b/runtime/queries/gitlab-ci/indents.scm @@ -0,0 +1 @@ +; inherits: yaml diff --git a/runtime/queries/gitlab-ci/injections.scm b/runtime/queries/gitlab-ci/injections.scm new file mode 100644 index 00000000..bb62c18d --- /dev/null +++ b/runtime/queries/gitlab-ci/injections.scm @@ -0,0 +1,51 @@ +((comment) @injection.content + (#set! injection.language "comment")) + +(block_mapping_pair + key: (flow_node) @_run (#any-of? @_run "script" "before_script" "after_script" "pre_get_sources_script" "command" "entrypoint") + value: (flow_node + (plain_scalar + (string_scalar) @injection.content) + (#set! injection.language "bash"))) + +(block_mapping_pair + key: (flow_node) @_run (#any-of? @_run "script" "before_script" "after_script" "pre_get_sources_script" "command" "entrypoint") + value: (block_node + (block_scalar) @injection.content + (#set! injection.language "bash"))) + +(block_mapping_pair + key: (flow_node) @_run (#any-of? @_run "script" "before_script" "after_script" "pre_get_sources_script" "command" "entrypoint") + value: (block_node + (block_sequence + (block_sequence_item + (flow_node + (plain_scalar + (string_scalar) @injection.content)) + (#set! injection.language "bash"))))) + +(block_mapping_pair + key: (flow_node) @_run (#any-of? @_run "script" "before_script" "after_script" "pre_get_sources_script" "command" "entrypoint") + value: (block_node + (block_sequence + (block_sequence_item + (block_node + (block_scalar) @injection.content + (#set! injection.language "bash")))))) + +; e.g. +; ``` +; job1: +; services: +; entrypoint: ["/usr/local/bin/docker-entrypoint.sh", "-c", 'max_connections=100'] +; ``` +(block_mapping_pair + key: (flow_node) @_run (#any-of? @_run "command" "entrypoint") + value: (flow_node + (flow_sequence + (flow_node + [ + (double_quote_scalar) + (single_quote_scalar) + ] @injection.content))) + (#set! injection.language "bash")) diff --git a/runtime/queries/gitlab-ci/rainbows.scm b/runtime/queries/gitlab-ci/rainbows.scm new file mode 100644 index 00000000..4ba254e8 --- /dev/null +++ b/runtime/queries/gitlab-ci/rainbows.scm @@ -0,0 +1 @@ +; inherits: yaml diff --git a/runtime/queries/gitlab-ci/tags.scm b/runtime/queries/gitlab-ci/tags.scm new file mode 100644 index 00000000..6313a075 --- /dev/null +++ b/runtime/queries/gitlab-ci/tags.scm @@ -0,0 +1,17 @@ +; select jobs +(block_mapping + (block_mapping_pair + value: (block_node + (block_mapping + (block_mapping_pair + key: (flow_node) @_key (#eq? @_key "stage"))))) @definition.struct) + +; select defined variables under `variables:` +(block_mapping + (block_mapping_pair + key: (flow_node) @_key (#eq? @_key "variables") + value: (block_node + (block_mapping + (block_mapping_pair + key: (flow_node) @name + value: (_) @definition.constant))))) diff --git a/runtime/queries/gitlab-ci/textobjects.scm b/runtime/queries/gitlab-ci/textobjects.scm new file mode 100644 index 00000000..4ba254e8 --- /dev/null +++ b/runtime/queries/gitlab-ci/textobjects.scm @@ -0,0 +1 @@ +; inherits: yaml diff --git a/runtime/queries/yaml/injections.scm b/runtime/queries/yaml/injections.scm index a16a945a..e0e1094b 100644 --- a/runtime/queries/yaml/injections.scm +++ b/runtime/queries/yaml/injections.scm @@ -21,23 +21,22 @@ ; Modified for Helix from https://github.com/nvim-treesitter/nvim-treesitter/blob/master/queries/yaml/injections.scm ;; GitHub actions: run -;; Gitlab CI: scripts, before_script, after_script ;; Buildkite: command, commands (block_mapping_pair - key: (flow_node) @_run (#any-of? @_run "run" "script" "before_script" "after_script" "command" "commands") + key: (flow_node) @_run (#any-of? @_run "run" "command" "commands") value: (flow_node (plain_scalar (string_scalar) @injection.content) (#set! injection.language "bash"))) (block_mapping_pair - key: (flow_node) @_run (#any-of? @_run "run" "script" "before_script" "after_script" "command" "commands") + key: (flow_node) @_run (#any-of? @_run "run" "command" "commands") value: (block_node (block_scalar) @injection.content (#set! injection.language "bash"))) (block_mapping_pair - key: (flow_node) @_run (#any-of? @_run "run" "script" "before_script" "after_script" "command" "commands") + key: (flow_node) @_run (#any-of? @_run "run" "command" "commands") value: (block_node (block_sequence (block_sequence_item @@ -47,7 +46,7 @@ (#set! injection.language "bash"))))) (block_mapping_pair - key: (flow_node) @_run (#any-of? @_run "run" "script" "before_script" "after_script" "command" "commands") + key: (flow_node) @_run (#any-of? @_run "run" "command" "commands") value: (block_node (block_sequence (block_sequence_item |