| Crates.io | ricecoder-lsp |
| lib.rs | ricecoder-lsp |
| version | 0.1.71 |
| created_at | 2025-12-09 19:07:46.151742+00 |
| updated_at | 2025-12-09 19:07:46.151742+00 |
| description | Language Server Protocol integration for RiceCoder |
| homepage | https://github.com/moabualruz/ricecoder |
| repository | https://github.com/moabualruz/ricecoder |
| max_upload_size | |
| id | 1976042 |
| size | 496,088 |
Language Server Protocol (LSP) integration for RiceCoder, providing semantic code analysis, diagnostics, code actions, and hover information across multiple programming languages.
The ricecoder-lsp crate implements a Language Server Protocol server that enables semantic understanding of code. It provides:
┌─────────────────────────────────────────────────────────────┐
│ LSP Client (IDE) │
└────────────────────────┬────────────────────────────────────┘
│ LSP Protocol (JSON-RPC)
│
┌────────────────────────▼────────────────────────────────────┐
│ LSP Server (ricecoder-lsp) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ LSP Protocol Handler │ │
│ │ - Initialize/Shutdown │ │
│ │ - Document Synchronization │ │
│ │ - Request Routing │ │
│ └──────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Semantic Analysis Engine │ │
│ │ ┌────────────────┐ ┌────────────────┐ │ │
│ │ │ AST Parser │ │ Symbol Index │ │ │
│ │ │ - Rust │ │ - Lookup │ │ │
│ │ │ - TypeScript │ │ - References │ │ │
│ │ │ - Python │ │ - Definitions │ │ │
│ │ └────────────────┘ └────────────────┘ │ │
│ └──────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Diagnostics & Code Actions │ │
│ │ - Issue Detection │ │
│ │ - Fix Suggestions │ │
│ │ - Code Transformations │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
The main entry point for LSP functionality is the LspServer struct:
use ricecoder_lsp::LspServer;
// Create a new LSP server
let mut server = LspServer::new();
// Run the server (handles stdio communication)
server.run().await?;
Key Methods:
new(): Create a new LSP server instancerun(): Start the server and handle client requestsstate(): Get the current server state (Initializing, Running, Shutdown)Server Capabilities:
The SemanticAnalyzer trait provides language-agnostic semantic analysis:
use ricecoder_lsp::semantic::{SemanticAnalyzer, RustAnalyzer};
use ricecoder_lsp::types::Language;
// Create a Rust analyzer
let analyzer = RustAnalyzer::new();
// Analyze code
let semantic_info = analyzer.analyze(code)?;
// Extract symbols
let symbols = analyzer.extract_symbols(code)?;
// Get hover information
let hover = analyzer.get_hover_info(code, position)?;
Supported Analyzers:
RustAnalyzer: Rust code analysisTypeScriptAnalyzer: TypeScript code analysisPythonAnalyzer: Python code analysisFallbackAnalyzer: Fallback for unknown languagesKey Methods:
analyze(code: &str): Analyze code and extract semantic informationextract_symbols(code: &str): Extract all symbols from codeget_hover_info(code: &str, position: Position): Get hover information at a positionlanguage(): Get the supported languageThe DiagnosticsEngine trait generates diagnostics for code issues:
use ricecoder_lsp::diagnostics::{DiagnosticsEngine, DefaultDiagnosticsEngine};
use ricecoder_lsp::types::Language;
// Create a diagnostics engine
let engine = DefaultDiagnosticsEngine::new();
// Generate diagnostics
let diagnostics = engine.generate_diagnostics(code, Language::Rust)?;
// Generate diagnostics for a specific range
let range_diagnostics = engine.generate_diagnostics_for_range(
code,
Language::Rust,
range,
)?;
Key Methods:
generate_diagnostics(code: &str, language: Language): Generate all diagnosticsgenerate_diagnostics_for_range(code: &str, language: Language, range: Range): Generate diagnostics for a specific rangeDiagnostic Severity Levels:
Error: Critical issues that prevent compilationWarning: Potential issues that should be addressedHint: Style suggestions and improvementsThe CodeActionsEngine trait suggests fixes for identified issues:
use ricecoder_lsp::code_actions::{CodeActionsEngine, DefaultCodeActionsEngine};
// Create a code actions engine
let engine = DefaultCodeActionsEngine::new();
// Get code actions for a diagnostic
let actions = engine.code_actions_for_diagnostic(diagnostic)?;
// Apply a code action
let fixed_code = engine.apply_code_action(code, action)?;
Key Methods:
code_actions_for_diagnostic(diagnostic: &Diagnostic): Get applicable code actionsapply_code_action(code: &str, action: &CodeAction): Apply a code action to codeThe HoverProvider trait provides hover information:
use ricecoder_lsp::hover::HoverProvider;
use ricecoder_lsp::types::Position;
// Create a hover provider
let provider = HoverProvider::new();
// Get hover information
let hover = provider.hover_at(code, position)?;
Key Methods:
hover_at(code: &str, position: Position): Get hover information at a positionuse ricecoder_lsp::semantic::{SemanticAnalyzer, RustAnalyzer};
let code = r#"
fn hello(name: &str) {
println!("Hello, {}", name);
}
"#;
let analyzer = RustAnalyzer::new();
let semantic_info = analyzer.analyze(code)?;
println!("Symbols: {:?}", semantic_info.symbols);
println!("Imports: {:?}", semantic_info.imports);
use ricecoder_lsp::diagnostics::DefaultDiagnosticsEngine;
use ricecoder_lsp::types::Language;
let code = r#"
fn unused_function() {
let unused_var = 42;
}
"#;
let engine = DefaultDiagnosticsEngine::new();
let diagnostics = engine.generate_diagnostics(code, Language::Rust)?;
for diagnostic in diagnostics {
println!("{}: {}", diagnostic.severity, diagnostic.message);
}
use ricecoder_lsp::hover::HoverProvider;
use ricecoder_lsp::types::Position;
let code = r#"
let x: i32 = 42;
"#;
let provider = HoverProvider::new();
let hover = provider.hover_at(code, Position { line: 0, character: 4 })?;
if let Some(info) = hover {
println!("Type: {}", info.contents);
}
use ricecoder_lsp::code_actions::DefaultCodeActionsEngine;
use ricecoder_lsp::diagnostics::DefaultDiagnosticsEngine;
use ricecoder_lsp::types::Language;
let code = r#"
use std::collections::HashMap;
fn main() {
println!("Hello");
}
"#;
let diagnostics_engine = DefaultDiagnosticsEngine::new();
let diagnostics = diagnostics_engine.generate_diagnostics(code, Language::Rust)?;
let actions_engine = DefaultCodeActionsEngine::new();
for diagnostic in diagnostics {
let actions = actions_engine.code_actions_for_diagnostic(&diagnostic)?;
for action in actions {
let fixed = actions_engine.apply_code_action(code, &action)?;
println!("Fixed code:\n{}", fixed);
}
}
The LSP server can be configured via environment variables:
RICECODER_LSP_LOG_LEVEL: Set logging level (trace, debug, info, warn, error)RICECODER_LSP_CACHE_SIZE: Set cache size in MB (default: 100)RICECODER_LSP_TIMEOUT_MS: Set analysis timeout in milliseconds (default: 5000)The LSP server is optimized for performance:
All operations return explicit error types:
use ricecoder_lsp::semantic::SemanticError;
match analyzer.analyze(code) {
Ok(info) => println!("Analysis successful"),
Err(SemanticError::ParseError(msg)) => eprintln!("Parse error: {}", msg),
Err(SemanticError::UnsupportedLanguage(lang)) => eprintln!("Unsupported: {:?}", lang),
Err(e) => eprintln!("Error: {}", e),
}
The crate includes comprehensive tests:
Run tests with:
cargo test --lib
cargo test --test '*'
cargo test --test '*properties*'
Solution: Check cache hit rates and increase cache size if needed.
RICECODER_LSP_CACHE_SIZE=200 cargo run
Solution: The crate gracefully degrades for unsupported languages. Check logs for details.
RICECODER_LSP_LOG_LEVEL=debug cargo run
Solution: Ensure the language is correctly detected. Check language-specific rules.
let language = Language::from_extension(path);
println!("Detected language: {:?}", language);
When adding new features:
src/semantic/src/diagnostics/src/code_actions/tests/.kiro/specs/ricecoder-lsp/requirements.md.kiro/specs/ricecoder-lsp/design.md.kiro/specs/ricecoder-lsp/tasks.mdPart of the RiceCoder project. See LICENSE for details.