# Wasot VSCode Extension & LSP Developer Guide

Complete guide for developing and using the Wasot language support in VS Code.

## Quick Start

```bash
# 1. Build and install the LSP server
cd /path/to/wasot
cargo install --path .

# 2. Build the VSCode extension
cd vscode-wasot
npm install
vsce package

# 3. Install the extension
code --install-extension wasot-0.0.1.vsix

# 4. Reload VSCode
# Ctrl+Shift+P → "Developer: Reload Window"
```

## Wasot Syntax Overview

Wasot is an event-driven markup language. Key syntax elements:

### Blocks (Meta-lines)

```wasot
.paragraph                      # Block at level 1
..nested                        # Nested block at level 2 (more dots = deeper)
...deeply-nested                # Level 3

.# Heading                      # Heading (self-closing)
.## Sub Heading                 # Sub-heading

./                              # Explicit block close
.hr:                            # Void element (trailing colon)
```

### IDs

```wasot
.section :my-id                 # Block with ID
.paragraph :intro-section       # IDs start with colon at end of line
```

### Arguments

```wasot
.block arg1 "arg 2" key=value   # Positional and keyword arguments
.div .. class="container"       # Arguments after .. separator
.button .. primary large        # Multiple positional args
."quoted type" text here        # Quoted block type (for spaces)
```

### Links

```wasot
((link text :target-id))        # Link to local ID
((docs :readme.section))        # Link to external document
((https://example.com))         # URL link
((display text|https://url))    # URL with display text
```

## LSP Features

The `wasot-lsp` server provides:

| Feature | Description | Trigger |
|---------|-------------|---------|
| **Go-to-definition** | Jump to ID definitions | Ctrl+Click or F12 |
| **Hover** | Show target info | Mouse hover |
| **Document links** | Clickable links | Auto-highlighted |
| **Semantic highlighting** | Syntax coloring via parser | Automatic |
| **Autocomplete** | ID suggestions in links | Type `:` inside `(( ))` |
| **Auto-generate IDs** | Add missing IDs on save | Save file |

### Semantic Token Types

The LSP provides these semantic tokens for syntax highlighting:

| Token Type | Element | Default Color |
|------------|---------|---------------|
| `namespace` | Dots (nesting level) | Gray |
| `class` | Block type name | Bold |
| `decorator` | IDs (`:my-id`) | Purple |
| `parameter` | Kwarg keys | Orange |
| `operator` | Equals sign | - |
| `string` | Quoted values | - |
| `variable` | Unquoted args | - |
| `keyword` | Special markers (`#`, `/`) | Pink |
| `comment` | Inline text separator (`..`) | Gray |

## Development Workflow

### Prerequisites

- Rust 1.70+
- Node.js 16+
- VS Code
- `vsce` (`npm install -g @vscode/vsce`)

### Build Commands

```bash
# Build LSP server
cargo build --release

# Install LSP to PATH
cargo install --path .

# Build VSCode extension
cd vscode-wasot
npm install
vsce package

# Install extension
code --install-extension wasot-0.0.1.vsix --force
```

### Development Cycle

1. **Make LSP changes** in `src/lsp/server.rs` or `src/lsp/document.rs`
2. **Rebuild and install**: `cargo install --path . --force`
3. **Reload VSCode**: Ctrl+Shift+P → "Developer: Reload Window"

For extension-only changes (no LSP):
1. Edit files in `vscode-wasot/`
2. Run `vsce package`
3. Run `code --install-extension wasot-0.0.1.vsix --force`
4. Reload VSCode

### Debug with Extension Development Host

```bash
cd vscode-wasot
npm install
# Press F5 in VSCode to launch Extension Development Host
```

### Testing Semantic Tokens

```bash
cd vscode-wasot
python3 get_tokens.py test/syntax-demo.wasot
```

## Project Structure

```
wasot/
├── src/
│   ├── lsp/
│   │   ├── mod.rs              # Module exports
│   │   ├── server.rs           # LSP server (handlers)
│   │   └── document.rs         # Document indexing, link tracking
│   ├── bin/
│   │   └── wasot_lsp.rs        # LSP binary entry point
│   ├── parsers/wasot/
│   │   ├── parser.rs           # Meta-line parser
│   │   └── arguments.rs        # Argument parser
│   └── consumers/
│       └── wasot_reconstructor.rs  # Pretty printer
│
└── vscode-wasot/
    ├── package.json            # Extension manifest
    ├── extension.js            # Extension entry point
    ├── language-configuration.json
    ├── syntaxes/
    │   └── wasot.tmLanguage.json   # TextMate grammar
    ├── test/
    │   └── syntax-demo.wasot   # Test file
    └── get_tokens.py           # Token debugging tool
```

## LSP Implementation Details

### Key Files

**`src/lsp/server.rs`** - Main LSP handlers:
- `initialize` - Capabilities (sync, hover, links, completion, semantic tokens)
- `did_open/change/close` - Document sync
- `will_save_wait_until` - Auto-generate IDs on save
- `goto_definition` - Navigate to link targets
- `hover` - Show link/ID information
- `document_link` / `document_link_resolve` - Clickable links
- `completion` - ID autocomplete in links
- `semantic_tokens_full` - Syntax highlighting

**`src/lsp/document.rs`** - Document indexing:
- `DocumentIndex` - Tracks IDs and links
- `IndexedId` - ID definition with position
- `IndexedLink` - Link with target type and position
- `LinkTargetType` - LocalId, ExternalId, Uri, Footnote

### Adding a New LSP Feature

1. Add capability in `initialize()`:
```rust
capabilities: ServerCapabilities {
    my_feature_provider: Some(...),
    ...
}
```

2. Implement the handler:
```rust
async fn my_feature(&self, params: MyFeatureParams) -> Result<...> {
    // Implementation
}
```

3. Rebuild and test

## Extension Configuration

### package.json Key Sections

```json
{
  "main": "./extension.js",           // Entry point
  "activationEvents": ["onLanguage:wasot"],
  "contributes": {
    "languages": [...],               // File associations
    "grammars": [...],                // TextMate grammar
    "semanticTokenScopes": [...],     // LSP token → TextMate scope mapping
    "configurationDefaults": {...}    // Editor settings
  }
}
```

### Semantic Token Mapping

Maps LSP semantic tokens to TextMate scopes for theming:

```json
"semanticTokenScopes": [{
  "language": "wasot",
  "scopes": {
    "namespace": ["punctuation.definition.block.wasot"],
    "class": ["entity.name.tag.wasot"],
    "decorator": ["entity.name.label.wasot"],
    ...
  }
}]
```

## Troubleshooting

### LSP Not Starting

```bash
# Check if binary is in PATH
which wasot-lsp

# Test LSP manually
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' | wasot-lsp
```

### Check LSP Output

In VSCode: View → Output → select "Wasot Language Server"

### Semantic Highlighting Not Working

1. Ensure `editor.semanticHighlighting.enabled` is `true`
2. Reload VSCode after installing extension
3. Check for errors in Output panel

### Links Not Resolving

- Ensure target ID exists with `:id` syntax
- For external docs, file must exist in workspace (e.g., `readme.wasot`)

## CLI Commands

The `wasot` CLI includes LSP and related commands:

```bash
# Start LSP server (used by extension)
wasot-lsp

# Pretty print with auto-generated IDs
wasot tools pretty file.wasot

# Convert to other formats
wasot xml-listener file.wasot --pretty
wasot to-jsonl file.wasot -o out.jsonl
```

## Testing

```bash
# Run all tests
cargo test

# Run LSP-specific tests
cargo test lsp::

# Run fast tests only
cargo test -- --skip ignored
```

## Pre-commit Checklist

Always run before committing:

```bash
./scripts/dev/pre-commit.sh
```

This runs formatting, linting, and tests.
