Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
654 changes: 574 additions & 80 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ crate-type = ["cdylib"]
path = "src/lib.rs"

[dependencies]
zed_extension_api = "0.0.6"
zed_extension_api = "0.7.0"
34 changes: 23 additions & 11 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,39 @@
# Cucumber/Gherkin support for Zed

_WIP_ Zed extension to add support for Cucumber/Gherkin.
Zed extension adding Cucumber/Gherkin syntax highlighting and LSP support.

## Features
## Prerequisites

Install the language server globally with npm:

```bash
npm install -g @cucumber/language-server
```

- Gherkin Tree-Sitter Grammar (via [thlcodes/tree-sitter-gherkin](https://github.com/thlcodes/tree-sitter-gherkin)), including
> **Note:** `npm` is required (not bun/yarn/pnpm). The language server resolves tree-sitter WASM files via nested `node_modules` paths that only npm's global install layout provides.

## Features

- highlights
- injections (for `docstring`)
- outline
- Gherkin Tree-Sitter Grammar (via [alistairstead/tree-sitter-gherkin](https://github.com/alistairstead/tree-sitter-gherkin), fork of [binhtddev/tree-sitter-gherkin](https://github.com/binhtddev/tree-sitter-gherkin))
- Syntax highlighting with semantic step coloring (Given/When/Then)
- Injections (docstring language detection)
- Outline navigation
- Full Gherkin spec: Feature, Scenario, Scenario Outline, Background, Examples, Rules, tags, data tables, docstrings
- i18n keyword support

- LSP (via @cucumber/languageserver)
- looks for global executable `cucumber-language-server` first, installs/uses latest package `@cucumber/language-server` otherwise
- supports configuration via project setting, e.g.
- LSP (via `@cucumber/language-server`)
- Autocompletion for step definitions
- Go-to-definition for steps
- Configuration via `.zed/settings.json`:
```json
{
"lsp": {
"cucumber": {
"settings": {
"glue": ["src/**/*.ts"]
"features": ["features/**/*.feature"],
"glue": ["steps/**/*.ts"]
}
}
}
}
```
- **Hint**: currently `@cucumber/language-server` uses a `node-tree-sitter` version that does not support Node 19/20
8 changes: 4 additions & 4 deletions extension.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
id = "cucumber"
name = "Cucumber/Gherkin support"
version = "0.0.2"
version = "0.0.3"
schema_version = 1
authors = ["Thomas Liebeskind <thomas.liebeskind@gmail.com>"]
authors = ["Thomas Liebeskind <thomas.liebeskind@gmail.com>", "Alistair Stead <alistair@kodehort.com>"]
description = "Zed Cucumber Support"
repository = "https://github.com/thlcodes/zed-extension-cucumber"

Expand All @@ -11,5 +11,5 @@ name = "Cucumber LSP"
language = "Gherkin"

[grammars.gherkin]
repository = "https://github.com/thlcodes/tree-sitter-gherkin"
commit = "133e9b270e80ecb8875bbe2f0625fcb276ea5ddb"
repository = "https://github.com/alistairstead/tree-sitter-gherkin"
commit = "ce7dca2734edc690479bb7639fe494668cf7399a"
2 changes: 2 additions & 0 deletions languages/gherkin/brackets.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
(doc_string
("\"\"\"" @open "\"\"\"" @close))
94 changes: 82 additions & 12 deletions languages/gherkin/highlights.scm
Original file line number Diff line number Diff line change
@@ -1,23 +1,93 @@
[
(section_keyword)
(step_keywords)
(background_kw)
(examples_kw)
(feature_kw)
(rule_kw)
(scenario_kw)
(scenario_outline_kw)
] @keyword

; (title) @string
(given_group
[
(given_step
(given_line
(given_kw) @keyword.import))
(asterisk_step
(asterisk_line
"* " @keyword.import))
(and_step
(and_line
(and_kw) @keyword.import))
(but_step
(but_line
(but_kw) @keyword.import))
])

; (step_definition) @string
(table_header_name) @attribute
(when_group
[
(when_step
(when_line
(when_kw) @function))
(asterisk_step
(asterisk_line
"* " @function))
(and_step
(and_line
(and_kw) @function))
(but_step
(but_line
(but_kw) @function))
])

(comment) @comment
(then_group
[
(then_step
(then_line
(then_kw) @type))
(asterisk_step
(asterisk_line
"* " @type))
(and_step
(and_line
(and_kw) @type))
(but_step
(but_line
(but_kw) @type))
])

(quoted_string) @string
(step_param) @variable.parameter

(number) @number
(step_quoted_string) @type

(reference) @constant
(step_context) @string

(tag) @label
(tag) @type

(table_cell) @constant
(table_head_row
(table_col
(table_cell) @markup.heading))

(docstring) @text
(data_table
(table_row
(table_col
(table_cell) @string)))

(description) @comment.doc

":" @punctuation.delimiter

"|" @punctuation.special

(doc_string) @string.documentation
(doc_string_content) @string
(media_type) @type

"language" @property

(language_name) @string
(invalid_language_name) @comment.error

[
(comment)
(language)
] @comment
10 changes: 9 additions & 1 deletion languages/gherkin/indents.scm
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
[
(section)
(scenario_definition)
(background)
(rule)
(examples_definition)
(given_group)
(when_group)
(then_group)
(data_table)
(doc_string)
] @indent
9 changes: 3 additions & 6 deletions languages/gherkin/injections.scm
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
(docstring
(docstring_start
(docstring_lang) @language
)
(docstring_content) @content
)
(doc_string
(media_type) @language
(doc_string_content) @content)
45 changes: 27 additions & 18 deletions languages/gherkin/outline.scm
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
(feature
(section_keyword) @context
(title) @name) @item
(feature_header
(feature_line
(feature_kw) @context
(context) @name))) @item

(section
(section_keyword) @context
(title)? @name) @item
(scenario_definition
(scenario
(scenario_line
(scenario_kw) @context
(context) @name))) @item

(step
(step_keywords) @context
(step_definition) @name
) @item
(scenario_definition
(scenario
(scenario_outline_line
(scenario_outline_kw) @context
(context) @name))) @item

(docstring
(docstring_start
(docstring_lang) @name
)
) @item
(background
(background_line
(background_kw) @context)) @item

(tag) @name @item
(rule
(rule_header
(rule_line
(rule_kw) @context
(context) @name))) @item

(table
(table_header) @name
) @item
(examples_definition
(examples
(examples_line
(examples_kw) @context
(context) @name))) @item
6 changes: 6 additions & 0 deletions languages/gherkin/redactions.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
(step_quoted_string) @redact
(data_table
(table_row
(table_col
(table_cell) @redact)))
(doc_string_content) @redact
23 changes: 23 additions & 0 deletions languages/gherkin/runnables.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
; Run entire feature
(feature
(feature_header
(feature_line
(feature_kw) @run
(context) @feature_name))
(#set! tag cucumber-feature))

; Run individual scenario
(scenario_definition
(scenario
(scenario_line
(scenario_kw) @run
(context) @scenario_name))
(#set! tag cucumber-scenario))

; Run scenario outline
(scenario_definition
(scenario
(scenario_outline_line
(scenario_outline_kw) @run
(context) @scenario_name))
(#set! tag cucumber-scenario))
17 changes: 17 additions & 0 deletions languages/gherkin/textobjects.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
; Feature as class
(feature) @class.around

; Rule as class
(rule) @class.around

; Scenario as function
(scenario_definition) @function.around

; Background as function
(background) @function.around

; Examples as function
(examples_definition) @function.around

; Comments
(comment) @comment.around
Loading