Skip to content

Conversation

@snowfrogdev
Copy link
Owner

@snowfrogdev snowfrogdev commented Dec 31, 2025

Summary

This PR adds comprehensive editor tooling support for Bobbin:

Language Server Protocol (LSP)

  • New binary providing IDE features
  • Error diagnostics with labels, notes, and suggestions
  • Autocomplete for variables, keywords, and boolean literals
  • Context-aware completions inside interpolations

VS Code Extension

  • Full syntax highlighting for files
  • Real-time error diagnostics
  • Autocomplete support
  • Marketplace-ready with publisher metadata and release workflow

Godot Editor Improvements

  • Syntax highlighting for files in the script editor
  • ASCII-formatted error diagnostics in output
  • Autocomplete support (variables, keywords, literals)
  • Fixed color bleeding between syntax tokens

Infrastructure

  • New crate extracted from runtime
  • GitHub Actions workflow for VS Code extension releases
  • Specialized code review agents for CI

Implement proper script validation in the Godot editor that uses
bobbin-syntax to validate scripts and report errors with accurate
line and column information.

Add get_reserved_words() implementation to support basic keyword
highlighting via Godot's Standard syntax highlighter.

Feature-gate validation behind editor-tooling to exclude from
release builds.

Note: EditorSyntaxHighlighter with custom highlighting is currently
broken in gdext due to virtual methods like _get_name() not being
dispatched to Rust implementations. See gdext issue (to be filed).
For now, basic keyword highlighting is available via the Standard
highlighter which uses get_reserved_words().
Move language components from runtime crate into specialized crates:
- Scanner, Parser, AST, Token → bobbin-syntax crate
- Diagnostics module → diagnostic handling in bobbin-syntax
- Resolver remains in runtime for semantic analysis
- Compiler and VM updated to use external dependencies

This separation allows syntax components to be used independently for
tooling (LSP, editor extensions) without pulling in the full runtime.

Update Cargo.toml files and build configuration to reflect new
workspace structure. CONTRIBUTING.md updated with new crate locations.
Add three new components for editor tooling and language support:

1. **bobbin-syntax crate** (syntax/)
   - Extracted scanner, parser, AST, token, and diagnostic modules
   - Provides language analysis without runtime dependency
   - Public API for tooling integration
   - Includes fuzzy error recovery and line/column tracking

2. **LSP server** (lsp/)
   - Implements Language Server Protocol for any LSP-compatible editor
   - Provides diagnostics and error reporting via bobbin-syntax
   - Standalone binary: cargo install --path lsp

3. **VS Code extension** (editors/vscode/)
   - TypeScript extension for Visual Studio Code
   - Syntax highlighting (TextMate grammar)
   - Diagnostic integration via LSP server
   - Language configuration for .bobbin files

These enable IDE support for Bobbin narrative scripts across
multiple editors without tight coupling to the runtime.
Add BobbinSyntaxHighlighter with color-coded tokenization for keywords, strings, numbers, comments, variables, and interpolations. Register via BobbinEditorPlugin for automatic editor integration.

Replaces previous workaround that relied on get_reserved_words() for basic highlighting.
Add error deduplication to avoid duplicate messages in Output panel. Implement
better error ranges (start/end positions) and ASCII-formatted error rendering
using AriadneRenderer. Add error highlighting in syntax highlighting and
implement reload_scripts method.
Enhance LSP diagnostic messages to include diagnostic notes and suggestions
inline. Add ASCII-formatted error rendering to LSP Output channel for better
error visualization.
Update documentation, CI workflows, project configuration, and code comments
to reflect the upgrade to Godot 4.5. This includes:
- Documentation (CLAUDE.md, README.md)
- CI workflow download URLs and executable names (build-and-test.yml)
- Project configuration (project.godot features)
- Code comments (lib.rs)
Add color reset logic after each highlighted token to ensure Godot's color persistence doesn't cause colors to bleed into subsequent unhighlighted text. Move default_color definition before the tokenization loop for consistency.
Add autocomplete functionality to the Bobbin LSP server with context-aware
suggestions for variables and keywords.

Key changes:

Syntax Analysis (symbol table as single source of truth):
- Add VariableKind enum and VariableDeclaration struct to track declarations
- Enhance SymbolTable to include all declarations found during resolution
- Modify Resolver.analyze() to return declarations even when errors occur
- Add unified analyze() function returning both diagnostics and declarations
- Implement backwards-compatible validate() as wrapper around analyze()

Position Utilities:
- Add LineIndex.offset() method to convert LSP line/column to byte offset
- Support both UTF-8 and UTF-16 position encoding

LSP Completion Handler:
- Register completion provider with '{' as trigger character
- Implement completion handler that extracts declarations from source
- Add context detection: show only variables inside {}, everything outside
- Add helper functions: is_inside_interpolation(), build_completion_items()
- Deduplicate variables by name and sort: variables → keywords → literals

Architecture follows established patterns where the symbol table serves as
the single source of truth for both compilation and IDE features, avoiding
code duplication and enabling future IDE features (hover, go-to-definition).

Tests: All existing tests pass; syntax analysis and LSP build successfully.
Add autocomplete functionality to the Godot editor's script editor for Bobbin files. The implementation:

- Reuses bobbin_syntax::analyze() to extract variable declarations
- Detects interpolation context via brace counting to show appropriate completions
- Strips incomplete interpolations before analysis to capture declarations when cursor is inside {}
- Suggests variables in all contexts (with kind, font_color, and other required fields)
- Suggests keywords (save, temp, set, extern) only outside interpolations
- Suggests boolean literals (true, false) only outside interpolations
- Deduplicates variables by name to avoid duplicates in completion list

All completion items include required Godot fields: display, insert_text, kind, font_color, icon, default_value, and location.
Documents the class-design-reviewer agent's purpose, review methodology,
seven class design rules, and output format specifications.
Add comprehensive marketplace support and automated release pipeline:

Marketplace Metadata:
- Update package.json with publisher (snowfrog-studio), repository, license, icon
- Add keywords for improved discoverability
- Configure gallery banner styling

Documentation & Assets:
- Rewrite README.md for end-user audience (vs development focus)
- Add CHANGELOG.md with release notes template
- Add LICENSE.md (custom Bobbin license)
- Create extension icon (128x128px)
- Add .vscodeignore to exclude dev files from package

Extension Features:
- Update extension.ts bundled LSP binary path resolution
- Support platform-specific binary naming (win32-x64, darwin-x64/arm64, linux-x64/arm64)
- Fallback chain: user config → bundled → cargo install → PATH

Release Infrastructure:
- Add GitHub Actions workflow to build LSP for all platforms
- Automate VSIX packaging and publishing to VS Code Marketplace
- Support both tag-based releases and manual workflow dispatch
- Include dry-run mode for testing before publishing

Binary Distribution:
- Create bin/ directory structure for bundled LSP binaries
- Platform binaries built by CI and placed in editors/vscode/bin/
…alysis

Replace the generic code-quality-reviewer with six specialized agents, each
focused on specific aspects of code quality. This provides more targeted,
expert analysis and clearer guidance on Clean Code principles.

New agents:
- code-comments-reviewer: Code comments and documentation issues
- conditional-logic-reviewer: Conditional logic and branching issues
- coupling-reviewer: Dependencies and coupling anti-patterns
- data-state-reviewer: Data and state management issues
- legacy-code-reviewer: Refactoring opportunities in legacy code
- test-quality-reviewer: Test design and testing best practices

Also remove the VSCode extension CHANGELOG as it's handled separately
in the extension build process.
Add shared keyword and literal constants, eliminate global state, refactor
large methods, add comprehensive tests, and improve code organization across
syntax, LSP, Godot bindings, and VS Code extension.

Changes:
- Add KEYWORDS and BOOLEAN_LITERALS constants to syntax crate
- Re-export and use constants across runtime, LSP, and Godot bindings
- Eliminate global static state in Godot bindings (LAST_REPORTED_ERRORS)
- Extract syntax_colors and completion_kinds modules in Godot bindings
- Refactor get_line_syntax_highlighting monster method (~95 → ~50 lines)
- Extract HotReloadState struct from BobbinRuntime
- Add comprehensive unit tests to syntax, lsp, and convert modules
- Flatten nested Result handling in analyze() function
- Implement platform detection lookup table in VS Code extension
- Run cargo fmt on all Rust crates

All changes maintain full backward compatibility and improve code clarity,
testability, and maintainability.
- Extract 7 helper functions from validate() and complete_code() methods
  * build_completion_item() - Eliminates 3 duplicated patterns
  * strip_incomplete_interpolation() - Handles incomplete interpolations
  * is_in_interpolation() - Detects cursor position in interpolations
  * build_error_dict() - Converts diagnostics to Godot format
  * format_error_message() - Formats errors for logging
  * should_output_errors() - Implements error deduplication
- Add 13 unit tests for pure helper functions
- Fix BobbinLanguage init constructor using #[class(init)]
- Fix borrow of moved path value in from_file_with_host()
- Fix mutable/immutable borrow conflict in start_hot_reload()
- Move BobbinSyntaxHighlighter helpers to separate impl block
- Make LastErrorState unconditional to avoid gdext cfg complexity

Results:
- validate() reduced from 120+ to 40 lines
- complete_code() reduced from 100+ to 30 lines
- Both release and debug builds now pass
@snowfrogdev snowfrogdev merged commit 124b023 into main Dec 31, 2025
12 checks passed
@snowfrogdev snowfrogdev deleted the lsp branch December 31, 2025 16:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants