ink_lsp_server/
initialize.rs1use crate::utils;
4use crate::utils::{COMMAND_CREATE_PROJECT, COMMAND_EXTRACT_EVENT, COMMAND_MIGRATE_PROJECT};
5
6pub fn initialize(
10 connection: lsp_server::Connection,
11) -> anyhow::Result<(lsp_server::Connection, lsp_types::InitializeParams)> {
12 let (initialize_id, initialize_params_json) = connection.initialize_start()?;
14 let initialize_params: lsp_types::InitializeParams =
15 serde_json::from_value(initialize_params_json).map_err(|error| {
16 anyhow::format_err!("Failed to deserialize initialize parameters: {error}")
17 })?;
18
19 let initialize_result = serde_json::to_value(lsp_types::InitializeResult {
21 capabilities: server_capabilities(&initialize_params.capabilities),
23 server_info: Some(lsp_types::ServerInfo {
24 name: "ink-analyzer".to_owned(),
25 version: Some(env!("CARGO_PKG_VERSION").to_owned()),
26 }),
27 offset_encoding: None,
28 })
29 .map_err(|error| anyhow::format_err!("Failed to serialize initialize result: {error}"))?;
30
31 connection.initialize_finish(initialize_id, initialize_result)?;
33
34 Ok((connection, initialize_params))
35}
36
37pub fn server_capabilities(
41 client_capabilities: &lsp_types::ClientCapabilities,
42) -> lsp_types::ServerCapabilities {
43 lsp_types::ServerCapabilities {
44 position_encoding: Some(utils::position_encoding(client_capabilities)),
45 text_document_sync: Some(lsp_types::TextDocumentSyncCapability::Options(
46 lsp_types::TextDocumentSyncOptions {
47 open_close: Some(true),
48 change: Some(lsp_types::TextDocumentSyncKind::FULL),
51 will_save: None,
52 will_save_wait_until: None,
53 save: Some(lsp_types::SaveOptions::default().into()),
54 },
55 )),
56 hover_provider: Some(lsp_types::HoverProviderCapability::Simple(true)),
57 completion_provider: Some(lsp_types::CompletionOptions {
58 resolve_provider: None,
59 trigger_characters: Some(vec![
61 "[".to_owned(),
62 "(".to_owned(),
63 ",".to_owned(),
64 ":".to_owned(),
65 ]),
66 all_commit_characters: None,
67 work_done_progress_options: Default::default(),
68 completion_item: Default::default(),
69 }),
70 code_action_provider: Some(
71 utils::code_actions_kinds(client_capabilities)
72 .map(|code_action_kinds| {
73 lsp_types::CodeActionProviderCapability::Options(lsp_types::CodeActionOptions {
74 code_action_kinds: Some(code_action_kinds),
75 work_done_progress_options: Default::default(),
76 resolve_provider: Some(true),
77 })
78 })
79 .unwrap_or_else(|| lsp_types::CodeActionProviderCapability::Simple(true)),
80 ),
81 inlay_hint_provider: Some(lsp_types::OneOf::Right(
82 lsp_types::InlayHintServerCapabilities::Options(lsp_types::InlayHintOptions {
83 work_done_progress_options: Default::default(),
84 resolve_provider: None,
85 }),
86 )),
87 signature_help_provider: Some(lsp_types::SignatureHelpOptions {
88 trigger_characters: Some(vec!["(".to_owned(), ",".to_owned()]),
89 retrigger_characters: None,
90 work_done_progress_options: Default::default(),
91 }),
92 execute_command_provider: Some(lsp_types::ExecuteCommandOptions {
93 commands: vec![
94 COMMAND_CREATE_PROJECT.to_owned(),
95 COMMAND_MIGRATE_PROJECT.to_owned(),
96 COMMAND_EXTRACT_EVENT.to_owned(),
97 ],
98 work_done_progress_options: Default::default(),
99 }),
100 ..Default::default()
101 }
102}
103
104#[cfg(test)]
105mod tests {
106 use super::*;
107 use std::thread;
108
109 #[test]
110 fn initialize_works() {
111 let (server_connection, client_connection) = lsp_server::Connection::memory();
113
114 thread::spawn(|| initialize(server_connection));
116
117 use lsp_types::request::Request;
120 let init_req_id = lsp_server::RequestId::from(1);
121 let init_req = lsp_server::Request {
122 id: init_req_id.clone(),
123 method: lsp_types::request::Initialize::METHOD.to_owned(),
124 params: serde_json::to_value(lsp_types::InitializeParams::default()).unwrap(),
125 };
126 client_connection.sender.send(init_req.into()).unwrap();
128 let message = client_connection.receiver.recv().unwrap();
130 let init_result_resp = match message {
131 lsp_server::Message::Response(it) => Some(it),
132 _ => None,
133 }
134 .unwrap();
135 assert_eq!(init_result_resp.id, init_req_id);
136 let init_result: lsp_types::InitializeResult =
138 serde_json::from_value(init_result_resp.result.unwrap()).unwrap();
139 assert_eq!(init_result.server_info.unwrap().name, "ink-analyzer");
140 }
141
142 #[test]
143 fn server_capabilities_works() {
144 let server_capabilities = server_capabilities(&Default::default());
146
147 assert_eq!(
152 server_capabilities.position_encoding,
153 Some(lsp_types::PositionEncodingKind::UTF16)
154 );
155 assert_eq!(
156 server_capabilities.code_action_provider,
157 Some(lsp_types::CodeActionProviderCapability::Simple(true))
158 );
159 }
160}