Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 20 additions & 22 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ typstyle-core = { version = "0.14.4", default-features = false }
# LSP
crossbeam-channel = "0.5.15"
dapts = "0.0.6"
lsp-types = { version = "=0.95.0", features = ["proposed"] }
lsp-types = { package = "gen-lsp-types", version = "0.9.0", features = ["url"] }

# CLI
clap = { version = "4.5", features = ["derive", "env", "unicode"] }
Expand Down
5 changes: 3 additions & 2 deletions crates/sync-lsp/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use std::sync::atomic::AtomicU32;
use std::sync::{Arc, Weak};

use futures::future::MaybeDone;
use lsp_types::{LspNotificationMethod, LspRequestMethod};
use parking_lot::Mutex;
use serde::Serialize;
use serde_json::{Value as JsonValue, from_value};
Expand Down Expand Up @@ -634,8 +635,8 @@ type RawHandler<S, T> = fn(srv: &mut S, args: T) -> ScheduleResult;
type BoxPureHandler<S, T> = Box<dyn Fn(&mut S, T) -> LspResult<()>>;
type BoxHandler<S, T> = Box<dyn Fn(&mut S, T) -> SchedulableResponse<JsonValue>>;
type ExecuteCmdMap<S> = HashMap<&'static str, BoxHandler<S, Vec<JsonValue>>>;
type RegularCmdMap<S> = HashMap<&'static str, BoxHandler<S, JsonValue>>;
type NotifyCmdMap<S> = HashMap<&'static str, BoxPureHandler<S, JsonValue>>;
type RegularCmdMap<S> = HashMap<LspRequestMethod<'static>, BoxHandler<S, JsonValue>>;
type NotifyCmdMap<S> = HashMap<LspNotificationMethod<'static>, BoxPureHandler<S, JsonValue>>;
type ResourceMap<S> = HashMap<ImmutPath, BoxHandler<S, Vec<JsonValue>>>;
type MayInitBoxHandler<A, S, T> =
Box<dyn for<'a> Fn(ServiceState<'a, A, S>, &LspClient, T) -> anyhow::Result<()>>;
Expand Down
11 changes: 6 additions & 5 deletions crates/sync-lsp/src/server/dap_srv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ where
mut self,
handler: RawHandler<Args::S, JsonValue>,
) -> Self {
self.req_handlers.insert(R::COMMAND, Box::new(handler));
self.req_handlers
.insert(R::COMMAND.into(), Box::new(handler));
self
}

Expand All @@ -54,7 +55,7 @@ where
handler: fn(&mut Args::S, R::Arguments) -> ScheduleResult,
) -> Self {
self.req_handlers.insert(
R::COMMAND,
R::COMMAND.into(),
Box::new(move |s, req| handler(s, from_json(req)?)),
);
self
Expand All @@ -66,7 +67,7 @@ where
handler: AsyncHandler<Args::S, R::Arguments, R::Response>,
) -> Self {
self.req_handlers.insert(
R::COMMAND,
R::COMMAND.into(),
Box::new(move |s, req| erased_response(handler(s, from_json(req)?))),
);
self
Expand Down Expand Up @@ -222,7 +223,7 @@ where

let is_disconnect = method == dapts::request::Disconnect::COMMAND;

let Some(handler) = self.requests.get(method) else {
let Some(handler) = self.requests.get(&method.into()) else {
log::warn!("unhandled dap request: {method}");
break 'serve_req just_result(Err(method_not_found()));
};
Expand Down Expand Up @@ -251,7 +252,7 @@ where
event,
body,
}: dap::Event| {
let Some(handler) = self.notifications.get(event.as_str()) else {
let Some(handler) = self.notifications.get(&event.as_str().into()) else {
log::warn!("unhandled event: {event}");
return Ok(());
};
Expand Down
34 changes: 17 additions & 17 deletions crates/sync-lsp/src/server/lsp_srv.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use lsp_types::{notification::Notification as Notif, request::Request as Req, *};
use lsp_types::{Notification as Notif, Request as Req, *};

use super::*;

Expand Down Expand Up @@ -27,7 +27,7 @@ impl LspClient {
) {
let mut req_queue = self.req_queue.lock();
let request = req_queue.outgoing.register(
R::METHOD.to_owned(),
R::METHOD.to_string(),
params,
Box::new(|s, resp| handler(s, resp.try_into().unwrap())),
);
Expand All @@ -42,7 +42,7 @@ impl LspClient {

/// Sends a typed notification to the client.
pub fn send_notification<N: Notif>(&self, params: &N::Params) {
self.send_notification_(lsp::Notification::new(N::METHOD.to_owned(), params));
self.send_notification_(lsp::Notification::new(N::METHOD.to_string(), params));
}

/// Sends an untyped notification to the client.
Expand Down Expand Up @@ -199,7 +199,7 @@ where
// }

while let Ok(msg) = inbox.recv() {
const EXIT_METHOD: &str = notification::Exit::METHOD;
const EXIT_METHOD: LspNotificationMethod = ExitNotification::METHOD;
let loop_start = tinymist_std::time::now();
match msg {
Evt(event) => {
Expand Down Expand Up @@ -228,7 +228,7 @@ where
self.client.handle.spawn(fut);
}
Msg(LspMessage::Notification(not)) => {
let is_exit = not.method == EXIT_METHOD;
let is_exit = not.method == EXIT_METHOD.as_str();
let track_id = self
.next_not_id
.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
Expand Down Expand Up @@ -294,8 +294,8 @@ where
/// Registers and handles a request. This should only be called once per
/// incoming request.
pub fn on_lsp_request(&mut self, method: &str, params: JsonValue) -> ScheduleResult {
match (&mut self.state, method) {
(State::Uninitialized(args), request::Initialize::METHOD) => {
match (&mut self.state, LspRequestMethod::from(method)) {
(State::Uninitialized(args), InitializeRequest::METHOD) => {
// todo: what will happen if the request cannot be deserialized?
let params = serde_json::from_value::<Args::I>(params);
match params {
Expand All @@ -311,15 +311,15 @@ where
(State::Uninitialized(..) | State::Initializing(..), _) => {
just_result(Err(not_initialized()))
}
(_, request::Initialize::METHOD) => {
(_, InitializeRequest::METHOD) => {
just_result(Err(invalid_request("server is already initialized")))
}
// todo: generalize this
(State::Ready(..), request::ExecuteCommand::METHOD) => self.on_execute_command(params),
(State::Ready(..), ExecuteCommandRequest::METHOD) => self.on_execute_command(params),
(State::Ready(s), method) => 'serve_req: {
let is_shutdown = method == request::Shutdown::METHOD;
let is_shutdown = method == ShutdownRequest::METHOD;

let Some(handler) = self.requests.get(method) else {
let Some(handler) = self.requests.get(&method) else {
log::warn!("unhandled lsp request: {method}");
break 'serve_req just_result(Err(method_not_found()));
};
Expand Down Expand Up @@ -351,29 +351,29 @@ where

// todo: generalize this
if command == "tinymist.getResources" {
self.get_resources(arguments)
self.get_resources(arguments.unwrap_or_default())
} else {
let Some(handler) = self.commands.get(command.as_str()) else {
log::error!("asked to execute unknown command: {command}");
return Err(method_not_found());
};
handler(s, arguments)
handler(s, arguments.unwrap_or_default())
}
}

/// Handles an incoming notification.
pub fn on_notification(&mut self, method: &str, params: JsonValue) -> LspResult<()> {
let handle = |s, method: &str, params: JsonValue| {
let Some(handler) = self.notifications.get(method) else {
let Some(handler) = self.notifications.get(&method.into()) else {
log::warn!("unhandled notification: {method}");
Comment thread
ribru17 marked this conversation as resolved.
return Ok(());
};

handler(s, params)
};

match (&mut self.state, method) {
(state, notification::Initialized::METHOD) => {
match (&mut self.state, LspNotificationMethod::from(method)) {
(state, InitializedNotification::METHOD) => {
let mut s = State::ShuttingDown;
std::mem::swap(state, &mut s);
match s {
Expand All @@ -394,7 +394,7 @@ where
};
handle(s, method, params)
}
(State::Ready(state), method) => handle(state, method, params),
(State::Ready(state), method) => handle(state, method.as_str(), params),
// todo: whether it is safe to ignore notifications
(State::Uninitialized(..) | State::Initializing(..), method) => {
log::warn!("server is not ready yet, while received notification {method}");
Expand Down
2 changes: 1 addition & 1 deletion crates/tinymist-query/src/analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub use typst_shim::syntax::VirtualPathExt;
use std::sync::Arc;

use ecow::eco_format;
use lsp_types::Url;
use lsp_types::Uri as Url;
use tinymist_project::LspComputeGraph;
use tinymist_std::error::WithContextUntyped;
use tinymist_std::{Result, bail};
Expand Down
Loading