Skip to content

Integrate LUMOS Language Server (LSP) with VSCode extension #1

@rz1989s

Description

@rz1989s

Goal

Integrate the newly published lumos-lsp Language Server Protocol implementation into the vscode-lumos extension to provide advanced IDE features.


Background

The core LUMOS repository has implemented a full LSP server (lumos-lsp) with:

  • ✅ Real-time diagnostics (syntax errors, undefined types)
  • ✅ Auto-completion (Solana types, primitives, attributes)
  • ✅ Hover information (type definitions, documentation)
  • ✅ 13 comprehensive tests (100% passing)

Repository: https://github.com/getlumos/lumos
Issue: getlumos/lumos#45 (completed)
Commit: f4e30c8


Current State

vscode-lumos extension:

  • ✅ File association (.lumos recognized)
  • ✅ Syntax highlighting (TextMate grammar)
  • ✅ Basic IntelliSense
  • ✅ Code snippets
  • ❌ LSP integration (not implemented)

Implementation Tasks

1. Add LSP Client Dependencies

Update package.json:

{
  "dependencies": {
    "vscode-languageclient": "^9.0.0"
  }
}

2. Implement Language Client

Create src/lspClient.ts:

import * as vscode from 'vscode';
import {
  LanguageClient,
  LanguageClientOptions,
  ServerOptions,
} from 'vscode-languageclient/node';

let client: LanguageClient | undefined;

export async function activateLSP(context: vscode.ExtensionContext) {
  // Ensure LSP server is installed
  const lspPath = await ensureLSPServer();
  
  if (!lspPath) {
    vscode.window.showErrorMessage(
      'LUMOS Language Server not found. Please install: cargo install lumos-lsp'
    );
    return;
  }

  // Configure server options
  const serverOptions: ServerOptions = {
    command: lspPath,
    args: []
  };

  // Configure client options
  const clientOptions: LanguageClientOptions = {
    documentSelector: [{ scheme: 'file', language: 'lumos' }],
    synchronize: {
      fileEvents: vscode.workspace.createFileSystemWatcher('**/*.lumos')
    }
  };

  // Create and start client
  client = new LanguageClient(
    'lumos',
    'LUMOS Language Server',
    serverOptions,
    clientOptions
  );

  await client.start();
  context.subscriptions.push(client);
}

export function deactivateLSP(): Thenable<void> | undefined {
  return client?.stop();
}

3. Implement Auto-Install (Seamless UX)

IMPORTANT: Include auto-install for best user experience:

async function ensureLSPServer(): Promise<string | undefined> {
  // Check if already installed
  let lspPath = await findLSPInPath();
  
  if (lspPath) {
    return lspPath;
  }

  // Check user preference
  const config = vscode.workspace.getConfiguration('lumos');
  const autoInstall = config.get('lsp.autoInstall', true);

  if (!autoInstall) {
    return undefined;
  }

  // Prompt user to install
  const choice = await vscode.window.showInformationMessage(
    'LUMOS Language Server not found. Install now?',
    'Install',
    'Manual Install',
    'Cancel'
  );

  if (choice === 'Install') {
    return await installLSPServer();
  } else if (choice === 'Manual Install') {
    vscode.env.openExternal(
      vscode.Uri.parse('https://crates.io/crates/lumos-lsp')
    );
  }

  return undefined;
}

async function installLSPServer(): Promise<string | undefined> {
  return await vscode.window.withProgress({
    location: vscode.ProgressLocation.Notification,
    title: 'Installing LUMOS Language Server...',
    cancellable: false
  }, async (progress) => {
    const { exec } = require('child_process');
    const { promisify } = require('util');
    const execAsync = promisify(exec);

    progress.report({ message: 'Running cargo install lumos-lsp...' });
    
    try {
      await execAsync('cargo install lumos-lsp');
      vscode.window.showInformationMessage('✅ LUMOS LSP installed successfully!');
      return await findLSPInPath();
    } catch (error: any) {
      vscode.window.showErrorMessage(
        `Failed to install LUMOS LSP: ${error.message}\n\nInstall manually: cargo install lumos-lsp`
      );
      return undefined;
    }
  });
}

async function findLSPInPath(): Promise<string | undefined> {
  const { exec } = require('child_process');
  const { promisify } = require('util');
  const execAsync = promisify(exec);

  try {
    const { stdout } = await execAsync(
      process.platform === 'win32' ? 'where lumos-lsp' : 'which lumos-lsp'
    );
    return stdout.trim();
  } catch {
    return undefined;
  }
}

4. Update Extension Activation

Modify src/extension.ts:

import * as vscode from 'vscode';
import { activateLSP, deactivateLSP } from './lspClient';

export async function activate(context: vscode.ExtensionContext) {
  console.log('LUMOS extension is now active');

  // Activate LSP
  await activateLSP(context);

  // Keep existing features (snippets, etc.)
  // ...
}

export function deactivate(): Thenable<void> | undefined {
  return deactivateLSP();
}

5. Add Configuration Settings

Add to package.json contributions:

{
  "contributes": {
    "configuration": {
      "title": "LUMOS",
      "properties": {
        "lumos.lsp.path": {
          "type": "string",
          "default": "lumos-lsp",
          "description": "Path to LUMOS Language Server binary"
        },
        "lumos.lsp.autoInstall": {
          "type": "boolean",
          "default": true,
          "description": "Automatically install LUMOS Language Server if not found"
        },
        "lumos.lsp.trace.server": {
          "type": "string",
          "enum": ["off", "messages", "verbose"],
          "default": "off",
          "description": "Traces the communication between VS Code and the language server"
        }
      }
    }
  }
}

Testing Checklist

  • LSP client activates on .lumos file open
  • Diagnostics appear for syntax errors
  • Auto-completion triggers on typing
  • Hover shows type information
  • Auto-install works on fresh install
  • Manual path configuration works
  • Works on Windows, macOS, Linux
  • Extension deactivates cleanly

Documentation Updates

Update README.md

Add LSP features section:

## Features

### 🚀 Language Server Protocol (LSP)

Powered by `lumos-lsp`, the extension provides:

- **Real-time Diagnostics** - Instant feedback on syntax errors and undefined types
- **Intelligent Auto-completion** - Context-aware suggestions for:
  - Solana types (PublicKey, Signature, Keypair)
  - Primitives (u8-u128, i8-i128, bool, String)
  - Complex types (Vec<T>, Option<T>)
  - Attributes (#[solana], #[account], #[key], #[max], #[deprecated])
  - Keywords (struct, enum)
- **Hover Documentation** - Type information and docs on hover
- **Future:** Go to definition, find references, rename symbol

### 📝 Additional Features

- Syntax highlighting via TextMate grammar
- Code snippets for common patterns
- Commands for generate, validate, format

## Installation

### Quick Start

1. Install the extension from VSCode Marketplace
2. Open a `.lumos` file
3. Extension will automatically prompt to install Language Server
4. Click "Install" and you're ready!

### Manual Installation

If you prefer to install the language server manually:

```bash
cargo install lumos-lsp

Then install the extension from the marketplace.

Configuration

  • lumos.lsp.path - Custom path to lumos-lsp binary (default: "lumos-lsp")
  • lumos.lsp.autoInstall - Auto-install LSP server if not found (default: true)
  • lumos.lsp.trace.server - Debug LSP communication (default: "off")

### Update CHANGELOG.md

```markdown
## [Unreleased]

### Added

- **Language Server Protocol Integration**
  - Real-time diagnostics for syntax and type errors
  - Intelligent auto-completion with 30+ completion items
  - Hover documentation for all types
  - Automatic LSP server installation on first use
  - Configuration options for LSP path and auto-install

### Changed

- Improved extension activation with LSP support
- Enhanced error messages and user feedback
- Better handling of missing dependencies

### Dependencies

- Added `vscode-languageclient@^9.0.0` for LSP support

Dependencies

Requires:

Blocks:

  • Improved IDE experience for VSCode users
  • Reduced extension maintenance (LSP handles features)

Success Criteria

  • LSP client successfully connects to lumos-lsp
  • All LSP features work (diagnostics, completion, hover)
  • Auto-install provides seamless one-click setup
  • Configuration settings work correctly
  • Documentation updated with LSP features
  • Extension published to VSCode Marketplace
  • Zero regressions in existing features

Priority: High
Estimated Effort: 4-6 hours
Depends On: getlumos/lumos#74 (publish lumos-lsp to crates.io)
Type: Enhancement (LSP integration + auto-install included)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions