Unnamed repository; edit this file 'description' to name the repository.
feat(languages): add `gitlab-ci` language specialized from `yaml` (#14396)
Kristoffer Plagborg Bak Sørensen 6 months ago
parent 7103826 · commit 97293c9
-rw-r--r--book/src/generated/lang-support.md1
-rw-r--r--languages.toml11
-rw-r--r--runtime/queries/gitlab-ci/highlights.scm89
-rw-r--r--runtime/queries/gitlab-ci/indents.scm1
-rw-r--r--runtime/queries/gitlab-ci/injections.scm51
-rw-r--r--runtime/queries/gitlab-ci/rainbows.scm1
-rw-r--r--runtime/queries/gitlab-ci/tags.scm17
-rw-r--r--runtime/queries/gitlab-ci/textobjects.scm1
-rw-r--r--runtime/queries/yaml/injections.scm9
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