diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_lsp_server/src/main_loop.rs | 103 |
1 files changed, 52 insertions, 51 deletions
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index e3cae94f4..9fc392749 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs | |||
@@ -452,59 +452,60 @@ impl<'a> PoolDispatcher<'a> { | |||
452 | None => return Ok(self), | 452 | None => return Ok(self), |
453 | Some(req) => req, | 453 | Some(req) => req, |
454 | }; | 454 | }; |
455 | match req.cast::<R>() { | 455 | let (id, params) = match req.cast::<R>() { |
456 | Ok((id, params)) => { | 456 | Ok(it) => it, |
457 | // Real time requests block user typing, so we should react quickly to them. | 457 | Err(req) => { |
458 | // Currently this means that we try to cancel background jobs if we don't have | 458 | self.req = Some(req); |
459 | // a spare thread. | 459 | return Ok(self); |
460 | let is_real_time = TypeId::of::<R>() == TypeId::of::<req::JoinLines>() | ||
461 | || TypeId::of::<R>() == TypeId::of::<req::OnEnter>(); | ||
462 | if self.pool.queued_count() > 0 && is_real_time { | ||
463 | self.world.cancel_requests(); | ||
464 | } | ||
465 | |||
466 | let world = self.world.snapshot(); | ||
467 | let sender = self.sender.clone(); | ||
468 | self.pool.execute(move || { | ||
469 | let response = match f(world, params) { | ||
470 | Ok(resp) => RawResponse::ok::<R>(id, &resp), | ||
471 | Err(e) => match e.downcast::<LspError>() { | ||
472 | Ok(lsp_error) => { | ||
473 | RawResponse::err(id, lsp_error.code, lsp_error.message) | ||
474 | } | ||
475 | Err(e) => { | ||
476 | if is_canceled(&e) { | ||
477 | // FIXME: When https://github.com/Microsoft/vscode-languageserver-node/issues/457 | ||
478 | // gets fixed, we can return the proper response. | ||
479 | // This works around the issue where "content modified" error would continuously | ||
480 | // show an message pop-up in VsCode | ||
481 | // RawResponse::err( | ||
482 | // id, | ||
483 | // ErrorCode::ContentModified as i32, | ||
484 | // "content modified".to_string(), | ||
485 | // ) | ||
486 | RawResponse { | ||
487 | id, | ||
488 | result: Some(serde_json::to_value(&()).unwrap()), | ||
489 | error: None, | ||
490 | } | ||
491 | } else { | ||
492 | RawResponse::err( | ||
493 | id, | ||
494 | ErrorCode::InternalError as i32, | ||
495 | format!("{}\n{}", e, e.backtrace()), | ||
496 | ) | ||
497 | } | ||
498 | } | ||
499 | }, | ||
500 | }; | ||
501 | let task = Task::Respond(response); | ||
502 | sender.send(task).unwrap(); | ||
503 | }); | ||
504 | self.res = Some(id); | ||
505 | } | 460 | } |
506 | Err(req) => self.req = Some(req), | 461 | }; |
462 | self.res = Some(id); | ||
463 | |||
464 | // Real time requests block user typing, so we should react quickly to them. | ||
465 | // Currently this means that we try to cancel background jobs if we don't have | ||
466 | // a spare thread. | ||
467 | let is_real_time = TypeId::of::<R>() == TypeId::of::<req::JoinLines>() | ||
468 | || TypeId::of::<R>() == TypeId::of::<req::OnEnter>(); | ||
469 | if self.pool.queued_count() > 0 && is_real_time { | ||
470 | self.world.cancel_requests(); | ||
507 | } | 471 | } |
472 | |||
473 | let world = self.world.snapshot(); | ||
474 | let sender = self.sender.clone(); | ||
475 | self.pool.execute(move || { | ||
476 | let response = match f(world, params) { | ||
477 | Ok(resp) => RawResponse::ok::<R>(id, &resp), | ||
478 | Err(e) => match e.downcast::<LspError>() { | ||
479 | Ok(lsp_error) => RawResponse::err(id, lsp_error.code, lsp_error.message), | ||
480 | Err(e) => { | ||
481 | if is_canceled(&e) { | ||
482 | // FIXME: When https://github.com/Microsoft/vscode-languageserver-node/issues/457 | ||
483 | // gets fixed, we can return the proper response. | ||
484 | // This works around the issue where "content modified" error would continuously | ||
485 | // show an message pop-up in VsCode | ||
486 | // RawResponse::err( | ||
487 | // id, | ||
488 | // ErrorCode::ContentModified as i32, | ||
489 | // "content modified".to_string(), | ||
490 | // ) | ||
491 | RawResponse { | ||
492 | id, | ||
493 | result: Some(serde_json::to_value(&()).unwrap()), | ||
494 | error: None, | ||
495 | } | ||
496 | } else { | ||
497 | RawResponse::err( | ||
498 | id, | ||
499 | ErrorCode::InternalError as i32, | ||
500 | format!("{}\n{}", e, e.backtrace()), | ||
501 | ) | ||
502 | } | ||
503 | } | ||
504 | }, | ||
505 | }; | ||
506 | let task = Task::Respond(response); | ||
507 | sender.send(task).unwrap(); | ||
508 | }); | ||
508 | Ok(self) | 509 | Ok(self) |
509 | } | 510 | } |
510 | 511 | ||