Initial commit

This commit is contained in:
dkanus 2025-07-30 19:46:37 +07:00
commit 4b9d6a6adb
13 changed files with 2308 additions and 0 deletions

12
rottlsp/Cargo.toml Normal file
View file

@ -0,0 +1,12 @@
[package]
name = "rottlsp"
version = "0.1.0"
edition = "2024"
[dependencies]
rottlib = { version = "0", path = "../rottlib" }
tokio = { version = "1", features = ["full"] }
tower-lsp = "0.20"
[lints]
workspace = true

84
rottlsp/src/main.rs Normal file
View file

@ -0,0 +1,84 @@
use tower_lsp::lsp_types;
/// A Language Server implementation for Rott.
///
/// Implements the [`tower_lsp::LanguageServer`] trait to handle LSP requests
/// (e.g. initialization, text synchronization, open notifications)
/// asynchronously.
struct RottLanguageServer {
/// Client handle for sending notifications and requests to the editor.
client: tower_lsp::Client,
}
#[tower_lsp::async_trait]
impl tower_lsp::LanguageServer for RottLanguageServer {
// Inform the client of our server capabilities during initialization.
async fn initialize(
&self,
_: lsp_types::InitializeParams,
) -> tower_lsp::jsonrpc::Result<lsp_types::InitializeResult> {
Ok(lsp_types::InitializeResult {
capabilities: lsp_types::ServerCapabilities {
// We can synchronize the text of files, which means we request
// to receive full updates whenever a file is opened or changed.
// `lsp_types::TextDocumentSyncKind::FULL` means we require full text
// every time.
text_document_sync: Some(lsp_types::TextDocumentSyncCapability::Kind(
lsp_types::TextDocumentSyncKind::FULL,
)),
..Default::default()
},
..Default::default()
})
}
// On file open, tokenize the new document and log any lexing errors.
async fn did_open(&self, params: lsp_types::DidOpenTextDocumentParams) {
// Measure lexing performance to track parser responsiveness.
let start_time = std::time::Instant::now();
let has_errors =
rottlib::lexer::TokenizedFile::from_source(&params.text_document.text).had_errors();
let elapsed_time = start_time.elapsed();
self.client
.log_message(
lsp_types::MessageType::INFO,
format!(
"Tokenized {} in {:?}",
params.text_document.uri.path(),
elapsed_time
),
)
.await;
if has_errors {
self.client
.log_message(
lsp_types::MessageType::INFO,
format!(
"There was an error while tokenizing {}",
params.text_document.uri.path(),
),
)
.await;
}
}
// Handle shutdown signal.
async fn shutdown(&self) -> tower_lsp::jsonrpc::Result<()> {
// No cleanup required on shutdown; simply acknowledge the request.
Ok(())
}
}
#[tokio::main]
async fn main() {
// We are using standard input and output for communicating with an editor,
// so we need to avoid methods or macros that write or read using them,
// e.g. `println!`.
let (stdin, stdout) = (tokio::io::stdin(), tokio::io::stdout());
let (service, socket) = tower_lsp::LspService::new(|client| RottLanguageServer { client });
tower_lsp::Server::new(stdin, stdout, socket)
.serve(service)
.await;
}