fix(deps): update dependencies and fix all compilation errors

Updated dependencies to latest versions causing breaking changes:
- logos: 0.14 -> 0.16
- lalrpop: 0.21 -> 0.23
- thiserror: 1.0 -> 2.0
- petgraph: 0.6 -> 0.8
- notify: 6.0 -> 8
- toml: 0.8 -> 1.0.2
- tree-sitter (grammar): 0.20 -> 0.26

Fixed compilation issues:
1. logos 0.16: Added allow_greedy for unbounded repetitions in lexer
2. lalrpop 0.23: Changed from process_current_dir() to process()
3. tree-sitter 0.26: Updated bindings to use &Language reference

Also fixed Zed extension:
- Removed local highlights.scm override that had diverged from source
- Added regression test to prevent future divergence
This commit is contained in:
2026-02-16 23:49:29 +00:00
parent 1951be030e
commit 37793cea0d
8 changed files with 364 additions and 536 deletions

639
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -20,18 +20,18 @@ name = "storybook-lsp"
path = "src/bin/storybook-lsp.rs"
[dependencies]
logos = "0.14"
lalrpop-util = "0.21"
logos = "0.16"
lalrpop-util = "0.23"
miette = { version = "7.0", features = ["fancy"] }
thiserror = "1.0"
thiserror = "2.0"
strsim = "0.11" # Fuzzy matching for "did you mean?" suggestions
indexmap = "2.0" # Order-preserving maps
petgraph = "0.6" # Cycle detection
petgraph = "0.8" # Cycle detection
# Phase 3: Public API + CLI
anyhow = "1.0" # Error handling
clap = { version = "4.5", features = ["derive"] }
notify = "6.0" # Filesystem watching
toml = "0.8" # storybook.toml parsing
notify = "8" # Filesystem watching
toml = "1.0.2" # storybook.toml parsing
walkdir = "2.4" # Directory traversal
serde = { version = "1.0", features = ["derive"] }
# LSP Server dependencies
@@ -41,7 +41,7 @@ serde_json = "1.0"
env_logger = "0.11"
[build-dependencies]
lalrpop = "0.21"
lalrpop = "0.23"
[dev-dependencies]
proptest = "1.4"

View File

@@ -2,6 +2,6 @@ fn main() {
lalrpop::Configuration::new()
.use_cargo_dir_conventions()
.emit_rerun_directives(true)
.process_current_dir()
.process()
.unwrap();
}

View File

@@ -5,8 +5,9 @@ use logos::Logos;
/// Token types for the Storybook language
#[derive(Logos, Debug, Clone, PartialEq)]
#[logos(skip r"[ \t\n\f]+")] // Skip whitespace
#[logos(skip r"//[^\n]*")] // Skip line comments
#[logos(skip r"/\*([^*]|\*[^/])*\*/")] // Skip block comments
#[allow(clippy::duplicated_attributes)]
#[logos(skip(r"//[^\n]*", allow_greedy = true))] // Skip line comments
#[logos(skip(r"/\*([^*]|\*[^/])*\*/", allow_greedy = true))] // Skip block comments
pub enum Token {
// Keywords
#[token("use")]

View File

@@ -329,6 +329,56 @@ concept_comparison SkillLevel {
// Zed Extension Build Tests
// ============================================================================
#[test]
fn test_zed_highlights_query_not_overridden() {
// This test ensures the Zed extension doesn't have a local highlights.scm
// that overrides the grammar's version. Local overrides create a maintenance
// burden and can easily diverge from the source of truth.
//
// The preferred approach is to let Zed use the fetched grammar's queries.
// If a local override is needed (for Zed-specific customizations), this test
// will fail and remind us to keep them in sync.
let grammar_highlights = tree_sitter_dir().join("queries").join("highlights.scm");
let zed_highlights = zed_extension_dir()
.join("languages")
.join("storybook")
.join("highlights.scm");
// Verify grammar version exists
assert!(
grammar_highlights.exists(),
"Grammar highlights.scm not found at {:?}",
grammar_highlights
);
// If Zed has a local override, it MUST match the grammar version exactly
if zed_highlights.exists() {
let grammar_content = std::fs::read_to_string(&grammar_highlights)
.expect("Failed to read grammar highlights");
let zed_content =
std::fs::read_to_string(&zed_highlights).expect("Failed to read zed highlights");
assert_eq!(
grammar_content,
zed_content,
"\n\nZed extension has a local highlights.scm that differs from the grammar version.\n\
This causes the query to fail validation against the fetched grammar.\n\
\n\
To fix:\n\
1. Delete zed-storybook/languages/storybook/highlights.scm (preferred)\n\
2. Or sync it: cp tree-sitter-storybook/queries/highlights.scm zed-storybook/languages/storybook/\n\
\n\
Grammar version: {:?}\n\
Zed version: {:?}\n",
grammar_highlights,
zed_highlights
);
}
// If no local override exists, the test passes - Zed will use the fetched
// grammar's version
}
#[test]
#[ignore] // Only run with --ignored flag as this is slow
fn test_zed_extension_builds() {

View File

@@ -21,7 +21,7 @@ include = [
path = "bindings/rust/lib.rs"
[dependencies]
tree-sitter = "~0.20"
tree-sitter = "~0.26"
[build-dependencies]
cc = "1.0"

View File

@@ -6,7 +6,8 @@
//! ```
//! let code = "";
//! let mut parser = tree_sitter::Parser::new();
//! parser.set_language(tree_sitter_storybook::language()).expect("Error loading storybook grammar");
//! let language = tree_sitter_storybook::language();
//! parser.set_language(&language).expect("Error loading storybook grammar");
//! let tree = parser.parse(code, None).unwrap();
//! ```
//!
@@ -45,8 +46,9 @@ mod tests {
#[test]
fn test_can_load_grammar() {
let mut parser = tree_sitter::Parser::new();
let language = super::language();
parser
.set_language(super::language())
.set_language(&language)
.expect("Error loading storybook language");
}
}

View File

@@ -1,182 +0,0 @@
; Highlights query for Storybook DSL
; Maps grammar nodes to standard highlight groups
; Comments
(line_comment) @comment.line
(block_comment) @comment.block
; Keywords - Declaration keywords
[
"character"
"template"
"life_arc"
"schedule"
"behavior"
"institution"
"relationship"
"location"
"species"
"enum"
"state"
"concept"
"sub_concept"
"concept_comparison"
] @keyword.declaration
; Keywords - Control flow and modifiers
[
"and"
"or"
"not"
"on"
"enter"
"strict"
] @keyword.control
; Keywords - Import/module
[
"use"
"include"
"from"
] @keyword.import
; Keywords - Special
[
"as"
"self"
"remove"
"append"
"is"
"any"
] @keyword.special
; Boolean literals
[
"true"
"false"
] @constant.builtin.boolean
; Numbers
(integer) @constant.numeric.integer
(float) @constant.numeric.float
(time) @constant.numeric.time
(duration) @constant.numeric.duration
; Strings
(string) @string
; Identifiers in different contexts
(character name: (identifier) @type.character)
(template name: (identifier) @type.template)
(life_arc name: (identifier) @type.life_arc)
(schedule name: (identifier) @type.schedule)
(behavior name: (identifier) @type.behavior)
(institution name: (identifier) @type.institution)
(relationship name: (identifier) @type.relationship)
(location name: (identifier) @type.location)
(species name: (identifier) @type.species)
(enum_declaration name: (identifier) @type.enum)
(arc_state name: (identifier) @type.state)
(concept_declaration name: (identifier) @type.concept)
(sub_concept parent: (identifier) @type.concept)
(sub_concept name: (identifier) @type.sub_concept)
(concept_comparison name: (identifier) @type.concept_comparison)
(variant_pattern name: (identifier) @type.variant)
(template species: (identifier) @type.builtin)
; Field names
(field name: (dotted_path) @property)
(sub_concept_field name: (identifier) @property)
; Species reference
(character species: (identifier) @type.builtin)
; Paths and identifiers
(path) @namespace
(identifier) @variable
; Prose blocks - tag and content
(prose_block tag: (identifier) @tag)
(prose_block marker: (prose_marker) @punctuation.delimiter)
(prose_content) @markup.raw
; Operators
[
">"
">="
"<"
"<="
"->"
"is"
] @operator
; Punctuation
[
"{"
"}"
] @punctuation.bracket
[
"("
")"
] @punctuation.bracket
[
"["
"]"
] @punctuation.bracket
[
":"
"::"
";"
","
"."
".."
"@"
] @punctuation.delimiter
; Behavior tree keywords
[
"choose"
"then"
"if"
"when"
] @keyword.control.behavior
; Decorator keywords
[
"repeat"
"invert"
"retry"
"timeout"
"cooldown"
"succeed_always"
"fail_always"
] @keyword.decorator
; Behavior tree nodes
(selector_node) @function.behavior.selector
(sequence_node) @function.behavior.sequence
(condition_node) @function.behavior.condition
(if_decorator_node) @function.behavior.decorator
(decorator_node) @function.behavior.decorator
(action_node (identifier) @function.action)
; Transitions
(transition "->" @operator.transition)
(transition target: (identifier) @type.state)
; Schedule blocks
(schedule_block activity: (identifier) @function.activity)
; Override operations
(override "@" @keyword.override)
(override_op "remove" @keyword.override)
(override_op "append" @keyword.override)
; Template clause
(template_clause "from" @keyword.import)
; Error handling
(ERROR) @error