# Tree-sitter grammar and Zed extension for Cylc ! 🥳

**URL:** <https://cylc.discourse.group/t/tree-sitter-grammar-and-zed-extension-for-cylc/1023>\
**Category:** Cylc Development\
**Created:** [September 23, 2024, 2:53pm UTC](https://cylc.discourse.group/t/tree-sitter-grammar-and-zed-extension-for-cylc/1023 "2024-09-23T14:53:08Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![elliotfontaine](https://yyz2.discourse-cdn.com/free1/user_avatar/cylc.discourse.group/elliotfontaine/32/380_2.png) [@elliotfontaine](https://cylc.discourse.group/u/elliotfontaine)\
**Post date:** [September 23, 2024, 2:53pm UTC](https://cylc.discourse.group/t/tree-sitter-grammar-and-zed-extension-for-cylc/1023/1 "2024-09-23T14:53:08Z")

</div>

# Tree-sitter grammar for Cylc

> **[GitHub - elliotfontaine/tree-sitter-cylc: Tree-Sitter grammar for Cylc's workflow...](https://github.com/elliotfontaine/tree-sitter-cylc)**
>
> Tree-Sitter grammar for Cylc's workflow configuration files.

Here’s a Tree-sitter grammar for workflow configuration files (`.cylc` or `suite.rc`).

Because [Tree-sitter](https://tree-sitter.github.io/tree-sitter/) builds a complete concrete syntax tree, it enables IDE-side features typically reserved for language servers, such as a hierarchical file outline, external language injection for specific code sections (e.g. BASH for scripts), and more.

# Zed Editor Extension for Cylc

> **[GitHub - elliotfontaine/zed-cylc: Zed support for Cylc workflow files](https://github.com/elliotfontaine/zed-cylc)**
>
> Zed support for Cylc workflow files

Additionally, I’ve developed a Zed Editor extension based on this grammar to showcase its capabilities. It’s currently the only way to enable syntax highlighting in Zed, as the editor does not support TextMate grammars. Here are some of its key features:

| | **Description** |
| --- | --- |
| 🌈 **Syntax Highlighting** | Provides comprehensive highlighting for `.cylc` and `suite.rc` files. |
| 📜 **Hierarchical Outline** | Displays a collapsible, structured view of your Cylc configuration file, making it easy to navigate large workflows. |
| ⌨ **Auto-Indentation** | Automatically adjusts indentation as you write, ensuring your workflow configuration is consistently formatted. |
| 📂 **Code Folding** | Collapse or expand sections of your Cylc files for easier management of large blocks of code. |
| 🖥 **BASH Language Injection** | Embedded Shell syntax inside `script` settings and the `[[environment]]` section, for easier validation of your tasks scripts. |

 ![demo](https://global.discourse-cdn.com/free1/uploads/cylc1/original/1X/43a8ce2209a9e5f8b25ede63542e4f126b51a610.jpeg)

# IDEs which use Tree-sitter for language support

- [Zed](https://zed.dev/) - Done ✅
- [Neovim](https://neovim.io/)
- [Helix](https://helix-editor.com/)
- [Lapce](https://lapce.dev/)
- [Pulsar](https://pulsar-edit.dev/) - Atom is dead, long live Pulsar !
- [GNU Emacs (≥ 29.1)](https://www.gnu.org/software/emacs/)

# Development

The repositories are currently hosted under my personal GitHub account, not the Cylc organization. The projects are licensed under MIT, not GPLv3. Feel free to reach out if you would prefer a license or repo ownership change.

While the current grammar is suitable for daily use, certain edge cases will be difficult to address without deeper refactoring. Specifically, everything related to string parsing is, in my opinion, _RegEx spaghetti_.  
I began writing a parser for **ISO 8601 datetimes, durations, and Cylc recurrences** , but quickly abandoned it. It’s almost a grammar **in and of itself**. I decided to release the grammar before completing the full implementation.

This means the “API” (the generated concrete syntax trees) is still subject to change, and these changes should probably occur before developing other IDE extensions.

---

<div class="post-metadata">

**Author:** ![oliver.sanders](https://yyz2.discourse-cdn.com/free1/user_avatar/cylc.discourse.group/oliver.sanders/32/110_2.png) [@oliver.sanders](https://cylc.discourse.group/u/oliver.sanders)\
**Post date:** [September 23, 2024, 3:56pm UTC](https://cylc.discourse.group/t/tree-sitter-grammar-and-zed-extension-for-cylc/1023/2 "2024-09-23T15:56:55Z")

</div>

This looks great (especially the Zed screenshot), thanks so much for taking the initiative and sharing this!

I haven’t tried it out yet but will try to get it working with neovim when I get the chance.

> I began writing a parser for **ISO 8601 datetimes, durations, and Cylc recurrences** , but quickly abandoned it. It’s almost a grammar **in and of itself**

That matches my experience of writing the Pygments lexer!

> The projects are licensed under MIT, not GPLv3

That’s no problem. The cylc-flow code is GPL, however, many of the smaller repos (including the TextMate grammar) are BSD licensed to make them more easily usable as plugins.

If you haven’t bumped into them on your travels, we have some [reference files](https://github.com/cylc/cylc-textmate-grammar/tree/master/reference-files) to assist with writing lexers that aim the cover the Cylc syntax.

---

<div class="post-metadata">

**Author:** ![elliotfontaine](https://yyz2.discourse-cdn.com/free1/user_avatar/cylc.discourse.group/elliotfontaine/32/380_2.png) [@elliotfontaine](https://cylc.discourse.group/u/elliotfontaine)\
**Post date:** [September 23, 2024, 4:39pm UTC](https://cylc.discourse.group/t/tree-sitter-grammar-and-zed-extension-for-cylc/1023/3 "2024-09-23T16:39:40Z")

</div>

> If you haven’t bumped into them on your travels, we have some [reference files](https://github.com/cylc/cylc-textmate-grammar/tree/master/reference-files) to assist with writing lexers that aim the cover the Cylc syntax.

Thanks for pointing that out! I came across the `tests/` directory in the repo but didn’t think to check the `reference-files/` folder (much more useful for manual testing!)

I wrote a few tests during development, using Tree-sitter’s own testing suite, but they no longer pass due to changes in the produced API (e.g. node names). I’ll rewrite them based on these files.

> ````auto
> # SYNTAX: 2.4
> # text inside <> should be highlighted
> # optionally suite / task could be highlighted
> [[graph]]
> R1 = """
> poller<other.suite::foo> => foo
> foo & poller<other.suite::task_bar> => baz
> 
> poller<other-suite::foo:fail> => bar
> poller<other.suite::foo>:start => bar
> 
> <oops suite::foo> => bar```
> """
> 
> ````

Is this `other-suite::foo` syntax still in use? I’ve never come across it, and I don’t believe the Tree-sitter grammar currently supports it.

---

<div class="post-metadata">

**Author:** ![hilary.j.oliver](https://yyz2.discourse-cdn.com/free1/user_avatar/cylc.discourse.group/hilary.j.oliver/32/4_2.png) [@hilary.j.oliver](https://cylc.discourse.group/u/hilary.j.oliver)\
**Post date:** [September 23, 2024, 8:21pm UTC](https://cylc.discourse.group/t/tree-sitter-grammar-and-zed-extension-for-cylc/1023/4 "2024-09-23T20:21:40Z")

</div>

Thankyou @elliotfontaine - that is really awesome. I’ve been using Zed lately (and neovim) and had vaguely considered attempting this myself. But only vaguely!

> [@elliotfontaine](#):
>
> Is this `other-suite::foo` syntax still in use? I’ve never come across it, and I don’t believe the Tree-sitter grammar currently supports it.

That syntax automatically creates a task definition with task scripting that uses the `cylc workflow-state` command to poll for a task to achieve a state in other workflow. We don’t recommend using it anymore, but unfortunately I did find a few cases (at my site) where it’s still in use. It’s pretty rare though. I wouldn’t bust a gut to support it in in the grammar.
