use crate::utils;
pub fn initialize(
connection: lsp_server::Connection,
) -> anyhow::Result<(lsp_server::Connection, lsp_types::InitializeParams)> {
let (initialize_id, initialize_params_json) = connection.initialize_start()?;
let initialize_params: lsp_types::InitializeParams =
serde_json::from_value(initialize_params_json).map_err(|error| {
anyhow::format_err!("Failed to deserialize initialize parameters: {error}")
})?;
let initialize_result = serde_json::to_value(lsp_types::InitializeResult {
capabilities: server_capabilities(&initialize_params.capabilities),
server_info: Some(lsp_types::ServerInfo {
name: "ink-analyzer".to_owned(),
version: Some(env!("CARGO_PKG_VERSION").to_owned()),
}),
offset_encoding: None,
})
.map_err(|error| anyhow::format_err!("Failed to serialize initialize result: {error}"))?;
connection.initialize_finish(initialize_id, initialize_result)?;
Ok((connection, initialize_params))
}
pub fn server_capabilities(
client_capabilities: &lsp_types::ClientCapabilities,
) -> lsp_types::ServerCapabilities {
lsp_types::ServerCapabilities {
position_encoding: Some(utils::position_encoding(client_capabilities)),
text_document_sync: Some(lsp_types::TextDocumentSyncCapability::Options(
lsp_types::TextDocumentSyncOptions {
open_close: Some(true),
change: Some(lsp_types::TextDocumentSyncKind::FULL),
will_save: None,
will_save_wait_until: None,
save: Some(lsp_types::SaveOptions::default().into()),
},
)),
hover_provider: Some(lsp_types::HoverProviderCapability::Simple(true)),
completion_provider: Some(lsp_types::CompletionOptions {
resolve_provider: None,
trigger_characters: Some(vec![
"[".to_owned(),
"(".to_owned(),
",".to_owned(),
":".to_owned(),
]),
all_commit_characters: None,
work_done_progress_options: Default::default(),
completion_item: Default::default(),
}),
code_action_provider: Some(
utils::code_actions_kinds(client_capabilities)
.map(|code_action_kinds| {
lsp_types::CodeActionProviderCapability::Options(lsp_types::CodeActionOptions {
code_action_kinds: Some(code_action_kinds),
work_done_progress_options: Default::default(),
resolve_provider: None,
})
})
.unwrap_or_else(|| lsp_types::CodeActionProviderCapability::Simple(true)),
),
inlay_hint_provider: Some(lsp_types::OneOf::Right(
lsp_types::InlayHintServerCapabilities::Options(lsp_types::InlayHintOptions {
work_done_progress_options: Default::default(),
resolve_provider: None,
}),
)),
signature_help_provider: Some(lsp_types::SignatureHelpOptions {
trigger_characters: Some(vec!["(".to_owned(), ",".to_owned()]),
retrigger_characters: None,
work_done_progress_options: Default::default(),
}),
execute_command_provider: Some(lsp_types::ExecuteCommandOptions {
commands: vec!["createProject".to_owned()],
work_done_progress_options: Default::default(),
}),
..Default::default()
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::thread;
#[test]
fn initialize_works() {
let (server_connection, client_connection) = lsp_server::Connection::memory();
thread::spawn(|| initialize(server_connection));
use lsp_types::request::Request;
let init_req_id = lsp_server::RequestId::from(1);
let init_req = lsp_server::Request {
id: init_req_id.clone(),
method: lsp_types::request::Initialize::METHOD.to_owned(),
params: serde_json::to_value(lsp_types::InitializeParams::default()).unwrap(),
};
client_connection.sender.send(init_req.into()).unwrap();
let message = client_connection.receiver.recv().unwrap();
let init_result_resp = match message {
lsp_server::Message::Response(it) => Some(it),
_ => None,
}
.unwrap();
assert_eq!(init_result_resp.id, init_req_id);
let init_result: lsp_types::InitializeResult =
serde_json::from_value(init_result_resp.result.unwrap()).unwrap();
assert_eq!(init_result.server_info.unwrap().name, "ink-analyzer");
}
#[test]
fn server_capabilities_works() {
let server_capabilities = server_capabilities(&Default::default());
assert_eq!(
server_capabilities.position_encoding,
Some(lsp_types::PositionEncodingKind::UTF16)
);
assert_eq!(
server_capabilities.code_action_provider,
Some(lsp_types::CodeActionProviderCapability::Simple(true))
);
}
}