Skip to content

Create nemo-lsp language server #62

@geoffjay

Description

@geoffjay

Summary

Create a new nemo-lsp binary crate that implements the Language Server Protocol over stdio using tower-lsp. The server reuses nemo-config for parsing and nemo-registry for schema access, providing autocomplete, hover documentation, diagnostics, and go-to-definition for Nemo XML files.

Context

Authors currently write Nemo XML with no editor assistance beyond basic XML syntax. The existing schema/nemo.xsd provides XML structure validation but cannot encode component-specific property constraints. The LSP bridges this gap by using the live ComponentRegistry and ConfigSchema data.

The LSP reuses existing infrastructure — no new parsing logic needed:

  • nemo-config::XmlParser — parse XML into Value trees
  • nemo-config::ConfigValidator — schema-based validation with error locations
  • nemo-config::ConfigSchema / PropertySchema — property types, defaults, constraints
  • nemo-registry::ComponentRegistry — component list, search, category grouping
  • nemo-config::ConfigResolver — expression evaluation for ${} syntax

Acceptance Criteria

  • New crate at crates/nemo-lsp/ with tower-lsp dependency

  • LSP capabilities implemented:

    Completion — component element names

    • Triggered when typing inside <layout> or as a child element
    • Source: ComponentRegistry.list_components() → XML tag names

    Completion — attribute names

    • Triggered on existing component elements
    • Source: ComponentDescriptor.schema.properties keys
    • Include common attributes from schema/nemo.xsd attribute groups (layout-attrs, border-attrs, decoration-attrs, event-attrs, binding-attrs)

    Completion — enum values

    Hover documentation

    Diagnostics

    Completion — data binding paths

    • <binding source="..."> and bind-* attributes
    • Source: <data> source definitions in current file

    Completion — template references

    • template="..." attribute values
    • Source: <templates> block in current file

    Completion — handler names

    • on-click="...", on-change="...", etc.
    • Source: .rhai file function names from configured script directory

    Go-to-definition

    • template="name" → jump to <template name="name">
    • source="datasource" → jump to <source name="datasource">
  • LSP activated for files containing a <nemo> root element (via workspace/didChangeWatchedFiles or content-based detection)

  • Server starts with reasonable defaults (no config file required for basic operation)

  • Logging to file (not stdout, which is the LSP transport) via tracing

  • Cargo workspace member added to root Cargo.toml

Relevant Files

  • schema/nemo.xsd — existing XML schema with attribute groups
  • crates/nemo-config/src/xml_parser.rs — XML parser
  • crates/nemo-config/src/validator.rsConfigValidator, ValidationResult
  • crates/nemo-config/src/resolver.rsConfigResolver, expression evaluation
  • crates/nemo-config/src/schema.rsConfigSchema, PropertySchema
  • crates/nemo-registry/src/registry.rsComponentRegistry
  • crates/nemo-registry/src/builtins.rs — component registration
  • crates/nemo-registry/src/descriptor.rsComponentDescriptor
  • crates/nemo-config/src/error.rsValidationError
  • Cargo.toml — workspace members

Stack Base

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions