diff options
-rw-r--r-- | crates/ra_lsp_server/src/conv.rs | 86 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main.rs | 2 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop.rs | 26 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 45 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/world.rs | 12 | ||||
-rw-r--r-- | crates/ra_lsp_server/tests/heavy_tests/support.rs | 24 |
6 files changed, 128 insertions, 67 deletions
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index 32e67838e..82c7e757f 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs | |||
@@ -384,27 +384,53 @@ impl TryConvWith for &NavigationTarget { | |||
384 | } | 384 | } |
385 | } | 385 | } |
386 | 386 | ||
387 | pub fn to_location_link( | 387 | impl TryConvWith for (FileId, RangeInfo<NavigationTarget>) { |
388 | target: &RangeInfo<NavigationTarget>, | 388 | type Ctx = WorldSnapshot; |
389 | world: &WorldSnapshot, | 389 | type Output = LocationLink; |
390 | // line index for original range file | 390 | fn try_conv_with(self, world: &WorldSnapshot) -> Result<LocationLink> { |
391 | line_index: &LineIndex, | 391 | let (src_file_id, target) = self; |
392 | ) -> Result<LocationLink> { | 392 | |
393 | let target_uri = target.info.file_id().try_conv_with(world)?; | 393 | let target_uri = target.info.file_id().try_conv_with(world)?; |
394 | let tgt_line_index = world.analysis().file_line_index(target.info.file_id()); | 394 | let src_line_index = world.analysis().file_line_index(src_file_id); |
395 | 395 | let tgt_line_index = world.analysis().file_line_index(target.info.file_id()); | |
396 | let target_range = target.info.full_range().conv_with(&tgt_line_index); | 396 | |
397 | 397 | let target_range = target.info.full_range().conv_with(&tgt_line_index); | |
398 | let target_selection_range = | 398 | |
399 | target.info.focus_range().map(|it| it.conv_with(&tgt_line_index)).unwrap_or(target_range); | 399 | let target_selection_range = target |
400 | .info | ||
401 | .focus_range() | ||
402 | .map(|it| it.conv_with(&tgt_line_index)) | ||
403 | .unwrap_or(target_range); | ||
404 | |||
405 | let res = LocationLink { | ||
406 | origin_selection_range: Some(target.range.conv_with(&src_line_index)), | ||
407 | target_uri, | ||
408 | target_range, | ||
409 | target_selection_range, | ||
410 | }; | ||
411 | Ok(res) | ||
412 | } | ||
413 | } | ||
400 | 414 | ||
401 | let res = LocationLink { | 415 | impl TryConvWith for (FileId, RangeInfo<Vec<NavigationTarget>>) { |
402 | origin_selection_range: Some(target.range.conv_with(line_index)), | 416 | type Ctx = WorldSnapshot; |
403 | target_uri, | 417 | type Output = req::GotoDefinitionResponse; |
404 | target_range, | 418 | fn try_conv_with(self, world: &WorldSnapshot) -> Result<req::GotoTypeDefinitionResponse> { |
405 | target_selection_range, | 419 | let (file_id, RangeInfo { range, info: navs }) = self; |
406 | }; | 420 | let links = navs |
407 | Ok(res) | 421 | .into_iter() |
422 | .map(|nav| (file_id, RangeInfo::new(range, nav))) | ||
423 | .try_conv_with_to_vec(world)?; | ||
424 | if world.options.supports_location_link { | ||
425 | Ok(links.into()) | ||
426 | } else { | ||
427 | let locations: Vec<Location> = links | ||
428 | .into_iter() | ||
429 | .map(|link| Location { uri: link.target_uri, range: link.target_selection_range }) | ||
430 | .collect(); | ||
431 | Ok(locations.into()) | ||
432 | } | ||
433 | } | ||
408 | } | 434 | } |
409 | 435 | ||
410 | pub fn to_location( | 436 | pub fn to_location( |
@@ -452,3 +478,23 @@ where | |||
452 | self.iter.next().map(|item| item.conv_with(self.ctx)) | 478 | self.iter.next().map(|item| item.conv_with(self.ctx)) |
453 | } | 479 | } |
454 | } | 480 | } |
481 | |||
482 | pub trait TryConvWithToVec<'a>: Sized + 'a { | ||
483 | type Ctx; | ||
484 | type Output; | ||
485 | |||
486 | fn try_conv_with_to_vec(self, ctx: &'a Self::Ctx) -> Result<Vec<Self::Output>>; | ||
487 | } | ||
488 | |||
489 | impl<'a, I> TryConvWithToVec<'a> for I | ||
490 | where | ||
491 | I: Iterator + 'a, | ||
492 | I::Item: TryConvWith, | ||
493 | { | ||
494 | type Ctx = <I::Item as TryConvWith>::Ctx; | ||
495 | type Output = <I::Item as TryConvWith>::Output; | ||
496 | |||
497 | fn try_conv_with_to_vec(self, ctx: &'a Self::Ctx) -> Result<Vec<Self::Output>> { | ||
498 | self.map(|it| it.try_conv_with(ctx)).collect() | ||
499 | } | ||
500 | } | ||
diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs index 6aa6dd49f..c1f8243be 100644 --- a/crates/ra_lsp_server/src/main.rs +++ b/crates/ra_lsp_server/src/main.rs | |||
@@ -51,7 +51,7 @@ fn main_inner() -> Result<()> { | |||
51 | .and_then(|v| InitializationOptions::deserialize(v).ok()) | 51 | .and_then(|v| InitializationOptions::deserialize(v).ok()) |
52 | .unwrap_or_default(); | 52 | .unwrap_or_default(); |
53 | 53 | ||
54 | ra_lsp_server::main_loop(workspace_roots, opts, r, s) | 54 | ra_lsp_server::main_loop(workspace_roots, params.capabilities, opts, r, s) |
55 | })?; | 55 | })?; |
56 | log::info!("shutting down IO..."); | 56 | log::info!("shutting down IO..."); |
57 | threads.join()?; | 57 | threads.join()?; |
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index c44fc6603..f7becd8fb 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs | |||
@@ -8,7 +8,7 @@ use crossbeam_channel::{select, unbounded, Receiver, RecvError, Sender}; | |||
8 | use gen_lsp_server::{ | 8 | use gen_lsp_server::{ |
9 | handle_shutdown, ErrorCode, RawMessage, RawNotification, RawRequest, RawResponse, | 9 | handle_shutdown, ErrorCode, RawMessage, RawNotification, RawRequest, RawResponse, |
10 | }; | 10 | }; |
11 | use lsp_types::NumberOrString; | 11 | use lsp_types::{ClientCapabilities, NumberOrString}; |
12 | use ra_ide_api::{Canceled, FileId, LibraryData}; | 12 | use ra_ide_api::{Canceled, FileId, LibraryData}; |
13 | use ra_prof::profile; | 13 | use ra_prof::profile; |
14 | use ra_vfs::VfsTask; | 14 | use ra_vfs::VfsTask; |
@@ -22,7 +22,7 @@ use crate::{ | |||
22 | }, | 22 | }, |
23 | project_model::workspace_loader, | 23 | project_model::workspace_loader, |
24 | req, | 24 | req, |
25 | world::{WorldSnapshot, WorldState}, | 25 | world::{Options, WorldSnapshot, WorldState}, |
26 | InitializationOptions, Result, | 26 | InitializationOptions, Result, |
27 | }; | 27 | }; |
28 | 28 | ||
@@ -51,6 +51,7 @@ impl Error for LspError {} | |||
51 | 51 | ||
52 | pub fn main_loop( | 52 | pub fn main_loop( |
53 | ws_roots: Vec<PathBuf>, | 53 | ws_roots: Vec<PathBuf>, |
54 | client_caps: ClientCapabilities, | ||
54 | options: InitializationOptions, | 55 | options: InitializationOptions, |
55 | msg_receiver: &Receiver<RawMessage>, | 56 | msg_receiver: &Receiver<RawMessage>, |
56 | msg_sender: &Sender<RawMessage>, | 57 | msg_sender: &Sender<RawMessage>, |
@@ -77,7 +78,20 @@ pub fn main_loop( | |||
77 | loaded_workspaces | 78 | loaded_workspaces |
78 | }; | 79 | }; |
79 | 80 | ||
80 | let mut state = WorldState::new(ws_roots, workspaces, options.lru_capacity); | 81 | let mut state = WorldState::new( |
82 | ws_roots, | ||
83 | workspaces, | ||
84 | options.lru_capacity, | ||
85 | Options { | ||
86 | publish_decorations: options.publish_decorations, | ||
87 | show_workspace_loaded: options.show_workspace_loaded, | ||
88 | supports_location_link: client_caps | ||
89 | .text_document | ||
90 | .and_then(|it| it.definition) | ||
91 | .and_then(|it| it.link_support) | ||
92 | .unwrap_or(false), | ||
93 | }, | ||
94 | ); | ||
81 | 95 | ||
82 | let pool = ThreadPool::new(THREADPOOL_SIZE); | 96 | let pool = ThreadPool::new(THREADPOOL_SIZE); |
83 | let (task_sender, task_receiver) = unbounded::<Task>(); | 97 | let (task_sender, task_receiver) = unbounded::<Task>(); |
@@ -85,7 +99,6 @@ pub fn main_loop( | |||
85 | 99 | ||
86 | log::info!("server initialized, serving requests"); | 100 | log::info!("server initialized, serving requests"); |
87 | let main_res = main_loop_inner( | 101 | let main_res = main_loop_inner( |
88 | options, | ||
89 | &pool, | 102 | &pool, |
90 | msg_sender, | 103 | msg_sender, |
91 | msg_receiver, | 104 | msg_receiver, |
@@ -159,7 +172,6 @@ impl fmt::Debug for Event { | |||
159 | } | 172 | } |
160 | 173 | ||
161 | fn main_loop_inner( | 174 | fn main_loop_inner( |
162 | options: InitializationOptions, | ||
163 | pool: &ThreadPool, | 175 | pool: &ThreadPool, |
164 | msg_sender: &Sender<RawMessage>, | 176 | msg_sender: &Sender<RawMessage>, |
165 | msg_receiver: &Receiver<RawMessage>, | 177 | msg_receiver: &Receiver<RawMessage>, |
@@ -258,7 +270,7 @@ fn main_loop_inner( | |||
258 | && in_flight_libraries == 0 | 270 | && in_flight_libraries == 0 |
259 | { | 271 | { |
260 | let n_packages: usize = state.workspaces.iter().map(|it| it.count()).sum(); | 272 | let n_packages: usize = state.workspaces.iter().map(|it| it.count()).sum(); |
261 | if options.show_workspace_loaded { | 273 | if state.options.show_workspace_loaded { |
262 | let msg = format!("workspace loaded, {} rust packages", n_packages); | 274 | let msg = format!("workspace loaded, {} rust packages", n_packages); |
263 | show_message(req::MessageType::Info, msg, msg_sender); | 275 | show_message(req::MessageType::Info, msg, msg_sender); |
264 | } | 276 | } |
@@ -270,7 +282,7 @@ fn main_loop_inner( | |||
270 | update_file_notifications_on_threadpool( | 282 | update_file_notifications_on_threadpool( |
271 | pool, | 283 | pool, |
272 | state.snapshot(), | 284 | state.snapshot(), |
273 | options.publish_decorations, | 285 | state.options.publish_decorations, |
274 | task_sender.clone(), | 286 | task_sender.clone(), |
275 | subs.subscriptions(), | 287 | subs.subscriptions(), |
276 | ) | 288 | ) |
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 62c8cbf71..ab9ed5080 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -9,8 +9,7 @@ use lsp_types::{ | |||
9 | TextDocumentIdentifier, TextEdit, WorkspaceEdit, | 9 | TextDocumentIdentifier, TextEdit, WorkspaceEdit, |
10 | }; | 10 | }; |
11 | use ra_ide_api::{ | 11 | use ra_ide_api::{ |
12 | AssistId, Cancelable, FileId, FilePosition, FileRange, FoldKind, Query, RangeInfo, | 12 | AssistId, Cancelable, FileId, FilePosition, FileRange, FoldKind, Query, RunnableKind, Severity, |
13 | RunnableKind, Severity, | ||
14 | }; | 13 | }; |
15 | use ra_prof::profile; | 14 | use ra_prof::profile; |
16 | use ra_syntax::{AstNode, SyntaxKind, TextRange, TextUnit}; | 15 | use ra_syntax::{AstNode, SyntaxKind, TextRange, TextUnit}; |
@@ -21,7 +20,7 @@ use url_serde::Ser; | |||
21 | 20 | ||
22 | use crate::{ | 21 | use crate::{ |
23 | cargo_target_spec::{runnable_args, CargoTargetSpec}, | 22 | cargo_target_spec::{runnable_args, CargoTargetSpec}, |
24 | conv::{to_location, to_location_link, Conv, ConvWith, MapConvWith, TryConvWith}, | 23 | conv::{to_location, Conv, ConvWith, MapConvWith, TryConvWith, TryConvWithToVec}, |
25 | req::{self, Decoration}, | 24 | req::{self, Decoration}, |
26 | world::WorldSnapshot, | 25 | world::WorldSnapshot, |
27 | LspError, Result, | 26 | LspError, Result, |
@@ -263,19 +262,12 @@ pub fn handle_goto_definition( | |||
263 | params: req::TextDocumentPositionParams, | 262 | params: req::TextDocumentPositionParams, |
264 | ) -> Result<Option<req::GotoDefinitionResponse>> { | 263 | ) -> Result<Option<req::GotoDefinitionResponse>> { |
265 | let position = params.try_conv_with(&world)?; | 264 | let position = params.try_conv_with(&world)?; |
266 | let line_index = world.analysis().file_line_index(position.file_id); | ||
267 | let nav_info = match world.analysis().goto_definition(position)? { | 265 | let nav_info = match world.analysis().goto_definition(position)? { |
268 | None => return Ok(None), | 266 | None => return Ok(None), |
269 | Some(it) => it, | 267 | Some(it) => it, |
270 | }; | 268 | }; |
271 | let nav_range = nav_info.range; | 269 | let res = (position.file_id, nav_info).try_conv_with(&world)?; |
272 | let res = nav_info | 270 | Ok(Some(res)) |
273 | .info | ||
274 | .into_iter() | ||
275 | .map(|nav| RangeInfo::new(nav_range, nav)) | ||
276 | .map(|nav| to_location_link(&nav, &world, &line_index)) | ||
277 | .collect::<Result<Vec<_>>>()?; | ||
278 | Ok(Some(res.into())) | ||
279 | } | 271 | } |
280 | 272 | ||
281 | pub fn handle_goto_implementation( | 273 | pub fn handle_goto_implementation( |
@@ -283,19 +275,12 @@ pub fn handle_goto_implementation( | |||
283 | params: req::TextDocumentPositionParams, | 275 | params: req::TextDocumentPositionParams, |
284 | ) -> Result<Option<req::GotoImplementationResponse>> { | 276 | ) -> Result<Option<req::GotoImplementationResponse>> { |
285 | let position = params.try_conv_with(&world)?; | 277 | let position = params.try_conv_with(&world)?; |
286 | let line_index = world.analysis().file_line_index(position.file_id); | ||
287 | let nav_info = match world.analysis().goto_implementation(position)? { | 278 | let nav_info = match world.analysis().goto_implementation(position)? { |
288 | None => return Ok(None), | 279 | None => return Ok(None), |
289 | Some(it) => it, | 280 | Some(it) => it, |
290 | }; | 281 | }; |
291 | let nav_range = nav_info.range; | 282 | let res = (position.file_id, nav_info).try_conv_with(&world)?; |
292 | let res = nav_info | 283 | Ok(Some(res)) |
293 | .info | ||
294 | .into_iter() | ||
295 | .map(|nav| RangeInfo::new(nav_range, nav)) | ||
296 | .map(|nav| to_location_link(&nav, &world, &line_index)) | ||
297 | .collect::<Result<Vec<_>>>()?; | ||
298 | Ok(Some(res.into())) | ||
299 | } | 284 | } |
300 | 285 | ||
301 | pub fn handle_goto_type_definition( | 286 | pub fn handle_goto_type_definition( |
@@ -303,19 +288,12 @@ pub fn handle_goto_type_definition( | |||
303 | params: req::TextDocumentPositionParams, | 288 | params: req::TextDocumentPositionParams, |
304 | ) -> Result<Option<req::GotoTypeDefinitionResponse>> { | 289 | ) -> Result<Option<req::GotoTypeDefinitionResponse>> { |
305 | let position = params.try_conv_with(&world)?; | 290 | let position = params.try_conv_with(&world)?; |
306 | let line_index = world.analysis().file_line_index(position.file_id); | ||
307 | let nav_info = match world.analysis().goto_type_definition(position)? { | 291 | let nav_info = match world.analysis().goto_type_definition(position)? { |
308 | None => return Ok(None), | 292 | None => return Ok(None), |
309 | Some(it) => it, | 293 | Some(it) => it, |
310 | }; | 294 | }; |
311 | let nav_range = nav_info.range; | 295 | let res = (position.file_id, nav_info).try_conv_with(&world)?; |
312 | let res = nav_info | 296 | Ok(Some(res)) |
313 | .info | ||
314 | .into_iter() | ||
315 | .map(|nav| RangeInfo::new(nav_range, nav)) | ||
316 | .map(|nav| to_location_link(&nav, &world, &line_index)) | ||
317 | .collect::<Result<Vec<_>>>()?; | ||
318 | Ok(Some(res.into())) | ||
319 | } | 297 | } |
320 | 298 | ||
321 | pub fn handle_parent_module( | 299 | pub fn handle_parent_module( |
@@ -323,12 +301,7 @@ pub fn handle_parent_module( | |||
323 | params: req::TextDocumentPositionParams, | 301 | params: req::TextDocumentPositionParams, |
324 | ) -> Result<Vec<Location>> { | 302 | ) -> Result<Vec<Location>> { |
325 | let position = params.try_conv_with(&world)?; | 303 | let position = params.try_conv_with(&world)?; |
326 | world | 304 | world.analysis().parent_module(position)?.iter().try_conv_with_to_vec(&world) |
327 | .analysis() | ||
328 | .parent_module(position)? | ||
329 | .into_iter() | ||
330 | .map(|nav| nav.try_conv_with(&world)) | ||
331 | .collect::<Result<Vec<_>>>() | ||
332 | } | 305 | } |
333 | 306 | ||
334 | pub fn handle_runnables( | 307 | pub fn handle_runnables( |
diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs index fdc577622..9fd654305 100644 --- a/crates/ra_lsp_server/src/world.rs +++ b/crates/ra_lsp_server/src/world.rs | |||
@@ -19,6 +19,13 @@ use crate::{ | |||
19 | LspError, Result, | 19 | LspError, Result, |
20 | }; | 20 | }; |
21 | 21 | ||
22 | #[derive(Debug, Clone)] | ||
23 | pub struct Options { | ||
24 | pub publish_decorations: bool, | ||
25 | pub show_workspace_loaded: bool, | ||
26 | pub supports_location_link: bool, | ||
27 | } | ||
28 | |||
22 | /// `WorldState` is the primary mutable state of the language server | 29 | /// `WorldState` is the primary mutable state of the language server |
23 | /// | 30 | /// |
24 | /// The most interesting components are `vfs`, which stores a consistent | 31 | /// The most interesting components are `vfs`, which stores a consistent |
@@ -26,6 +33,7 @@ use crate::{ | |||
26 | /// incremental salsa database. | 33 | /// incremental salsa database. |
27 | #[derive(Debug)] | 34 | #[derive(Debug)] |
28 | pub struct WorldState { | 35 | pub struct WorldState { |
36 | pub options: Options, | ||
29 | pub roots_to_scan: usize, | 37 | pub roots_to_scan: usize, |
30 | pub roots: Vec<PathBuf>, | 38 | pub roots: Vec<PathBuf>, |
31 | pub workspaces: Arc<Vec<ProjectWorkspace>>, | 39 | pub workspaces: Arc<Vec<ProjectWorkspace>>, |
@@ -36,6 +44,7 @@ pub struct WorldState { | |||
36 | 44 | ||
37 | /// An immutable snapshot of the world's state at a point in time. | 45 | /// An immutable snapshot of the world's state at a point in time. |
38 | pub struct WorldSnapshot { | 46 | pub struct WorldSnapshot { |
47 | pub options: Options, | ||
39 | pub workspaces: Arc<Vec<ProjectWorkspace>>, | 48 | pub workspaces: Arc<Vec<ProjectWorkspace>>, |
40 | pub analysis: Analysis, | 49 | pub analysis: Analysis, |
41 | pub vfs: Arc<RwLock<Vfs>>, | 50 | pub vfs: Arc<RwLock<Vfs>>, |
@@ -47,6 +56,7 @@ impl WorldState { | |||
47 | folder_roots: Vec<PathBuf>, | 56 | folder_roots: Vec<PathBuf>, |
48 | workspaces: Vec<ProjectWorkspace>, | 57 | workspaces: Vec<ProjectWorkspace>, |
49 | lru_capacity: Option<usize>, | 58 | lru_capacity: Option<usize>, |
59 | options: Options, | ||
50 | ) -> WorldState { | 60 | ) -> WorldState { |
51 | let mut change = AnalysisChange::new(); | 61 | let mut change = AnalysisChange::new(); |
52 | 62 | ||
@@ -78,6 +88,7 @@ impl WorldState { | |||
78 | let mut analysis_host = AnalysisHost::new(lru_capacity); | 88 | let mut analysis_host = AnalysisHost::new(lru_capacity); |
79 | analysis_host.apply_change(change); | 89 | analysis_host.apply_change(change); |
80 | WorldState { | 90 | WorldState { |
91 | options, | ||
81 | roots_to_scan, | 92 | roots_to_scan, |
82 | roots: folder_roots, | 93 | roots: folder_roots, |
83 | workspaces: Arc::new(workspaces), | 94 | workspaces: Arc::new(workspaces), |
@@ -140,6 +151,7 @@ impl WorldState { | |||
140 | 151 | ||
141 | pub fn snapshot(&self) -> WorldSnapshot { | 152 | pub fn snapshot(&self) -> WorldSnapshot { |
142 | WorldSnapshot { | 153 | WorldSnapshot { |
154 | options: self.options.clone(), | ||
143 | workspaces: Arc::clone(&self.workspaces), | 155 | workspaces: Arc::clone(&self.workspaces), |
144 | analysis: self.analysis_host.analysis(), | 156 | analysis: self.analysis_host.analysis(), |
145 | vfs: Arc::clone(&self.vfs), | 157 | vfs: Arc::clone(&self.vfs), |
diff --git a/crates/ra_lsp_server/tests/heavy_tests/support.rs b/crates/ra_lsp_server/tests/heavy_tests/support.rs index a5e352da1..5dddbbe17 100644 --- a/crates/ra_lsp_server/tests/heavy_tests/support.rs +++ b/crates/ra_lsp_server/tests/heavy_tests/support.rs | |||
@@ -13,7 +13,8 @@ use lsp_types::{ | |||
13 | notification::DidOpenTextDocument, | 13 | notification::DidOpenTextDocument, |
14 | notification::{Notification, ShowMessage}, | 14 | notification::{Notification, ShowMessage}, |
15 | request::{Request, Shutdown}, | 15 | request::{Request, Shutdown}, |
16 | DidOpenTextDocumentParams, TextDocumentIdentifier, TextDocumentItem, Url, | 16 | ClientCapabilities, DidOpenTextDocumentParams, GotoCapability, TextDocumentClientCapabilities, |
17 | TextDocumentIdentifier, TextDocumentItem, Url, | ||
17 | }; | 18 | }; |
18 | use serde::Serialize; | 19 | use serde::Serialize; |
19 | use serde_json::{to_string_pretty, Value}; | 20 | use serde_json::{to_string_pretty, Value}; |
@@ -92,8 +93,25 @@ impl Server { | |||
92 | "test server", | 93 | "test server", |
93 | 128, | 94 | 128, |
94 | move |msg_receiver, msg_sender| { | 95 | move |msg_receiver, msg_sender| { |
95 | main_loop(roots, InitializationOptions::default(), &msg_receiver, &msg_sender) | 96 | main_loop( |
96 | .unwrap() | 97 | roots, |
98 | ClientCapabilities { | ||
99 | workspace: None, | ||
100 | text_document: Some(TextDocumentClientCapabilities { | ||
101 | definition: Some(GotoCapability { | ||
102 | dynamic_registration: None, | ||
103 | link_support: Some(true), | ||
104 | }), | ||
105 | ..Default::default() | ||
106 | }), | ||
107 | window: None, | ||
108 | experimental: None, | ||
109 | }, | ||
110 | InitializationOptions::default(), | ||
111 | &msg_receiver, | ||
112 | &msg_sender, | ||
113 | ) | ||
114 | .unwrap() | ||
97 | }, | 115 | }, |
98 | ); | 116 | ); |
99 | let res = Server { req_id: Cell::new(1), dir, messages: Default::default(), worker }; | 117 | let res = Server { req_id: Cell::new(1), dir, messages: Default::default(), worker }; |