Loading…
Building a ShopifyQL Code Editor
2023-10-18
- Source
- Shopify
- Published
- Added to Yomu
Summary
ShopifyQL Notebooks, released in October 2022, is a first-party app that lets merchants analyze shop data. To give its guided code-editing experience, Shopify used CodeMirror, which did not natively support ShopifyQL. Because ShopifyQL’s grammar is defined in ANTLR and generates Go and TypeScript code, while the language server follows Microsoft’s Language Server Protocol (LSP), the existing client and server language infrastructure was retained. A custom adapter passes queries to the language server, converts its incremental five-integer token descriptors into CodeMirror-compatible offsets, and reshapes them into a buffer of Lezer nodes for parse-tree construction. The resulting integration supports syntax highlighting, code completion, linting, and hover tooltips through CodeMirror plugins, while using its internal parse tree to inform editing behavior.
Context
CodeMirror did not have support for ShopifyQL, while ShopifyQL’s grammar and language server had already been built with ANTLR and LSP for use across client and server targets. Rewriting the grammar as a Lezer grammar would have discarded that existing implementation.
Approach / What changed
A custom adapter connects the ShopifyQL language server to CodeMirror and Lezer. It converts the language server’s incremental ANTLR token offsets into CodeMirror document offsets, transforms tokens into Lezer node types, builds a parse tree, and connects validation, completion, and hover responses to CodeMirror plugins.
Takeaways
- ShopifyQL uses an ANTLR grammar to generate code for Go and TypeScript, with a TypeScript language server that conforms to LSP.
- The adapter’s TokenIterator tracks line lengths and incremental positions to convert ANTLR-style offsets into CodeMirror offsets relative to the document.
- CodeMirror plugins expose the language server’s validation, completion, and hover functionality, while the Lezer parse tree enables syntax highlighting and editor behavior.