diff options
author | Kitson Kelly <me@kitsonkelly.com> | 2020-12-10 06:50:47 +1100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-10 06:50:47 +1100 |
commit | 95a6698caca228e8a3ec920a59e1904a09c78eaf (patch) | |
tree | bb7ef4c5a54d78a1915cabc2f36ea64f2fbb6b4e /cli/lsp/mod.rs | |
parent | b6dd850f71c029a3d82eb10c2528380b0ed4bc71 (diff) |
feat(lsp): support import maps (#8683)
Diffstat (limited to 'cli/lsp/mod.rs')
-rw-r--r-- | cli/lsp/mod.rs | 66 |
1 files changed, 61 insertions, 5 deletions
diff --git a/cli/lsp/mod.rs b/cli/lsp/mod.rs index e3092d815..784f3503d 100644 --- a/cli/lsp/mod.rs +++ b/cli/lsp/mod.rs @@ -18,6 +18,7 @@ use config::Config; use diagnostics::DiagnosticSource; use dispatch::NotificationDispatcher; use dispatch::RequestDispatcher; +use state::update_import_map; use state::DocumentData; use state::Event; use state::ServerState; @@ -87,13 +88,13 @@ pub fn start() -> Result<(), AnyError> { } let mut config = Config::default(); + config.root_uri = initialize_params.root_uri.clone(); if let Some(value) = initialize_params.initialization_options { config.update(value)?; } config.update_capabilities(&initialize_params.capabilities); let mut server_state = state::ServerState::new(connection.sender, config); - let state = server_state.snapshot(); // TODO(@kitsonk) need to make this configurable, respect unstable let ts_config = TsConfig::new(json!({ @@ -106,6 +107,7 @@ pub fn start() -> Result<(), AnyError> { "strict": true, "target": "esnext", })); + let state = server_state.snapshot(); tsc::request( &mut server_state.ts_runtime, &state, @@ -259,7 +261,7 @@ impl ServerState { specifier.clone(), params.text_document.version, ¶ms.text_document.text, - None, + state.maybe_import_map.clone(), ), ) .is_some() @@ -281,7 +283,11 @@ impl ServerState { let mut content = file_cache.get_contents(file_id)?; apply_content_changes(&mut content, params.content_changes); let doc_data = state.doc_data.get_mut(&specifier).unwrap(); - doc_data.update(params.text_document.version, &content, None); + doc_data.update( + params.text_document.version, + &content, + state.maybe_import_map.clone(), + ); file_cache.set_contents(specifier, Some(content.into_bytes())); Ok(()) @@ -326,6 +332,15 @@ impl ServerState { if let Err(err) = state.config.update(config.clone()) { error!("failed to update settings: {}", err); } + if let Err(err) = update_import_map(state) { + state + .send_notification::<lsp_types::notification::ShowMessage>( + lsp_types::ShowMessageParams { + typ: lsp_types::MessageType::Warning, + message: err.to_string(), + }, + ); + } } } (None, None) => { @@ -337,6 +352,15 @@ impl ServerState { Ok(()) })? + .on::<lsp_types::notification::DidChangeWatchedFiles>(|state, params| { + // if the current import map has changed, we need to reload it + if let Some(import_map_uri) = &state.maybe_import_map_uri { + if params.changes.iter().any(|fe| import_map_uri == &fe.uri) { + update_import_map(state)?; + } + } + Ok(()) + })? .finish(); Ok(()) @@ -395,8 +419,40 @@ impl ServerState { /// Start consuming events from the provided receiver channel. pub fn run(mut self, inbox: Receiver<Message>) -> Result<(), AnyError> { - // currently we don't need to do any other loading or tasks, so as soon as - // we run we are "ready" + // Check to see if we need to setup the import map + if let Err(err) = update_import_map(&mut self) { + self.send_notification::<lsp_types::notification::ShowMessage>( + lsp_types::ShowMessageParams { + typ: lsp_types::MessageType::Warning, + message: err.to_string(), + }, + ); + } + + // we are going to watch all the JSON files in the workspace, and the + // notification handler will pick up any of the changes of those files we + // are interested in. + let watch_registration_options = + lsp_types::DidChangeWatchedFilesRegistrationOptions { + watchers: vec![lsp_types::FileSystemWatcher { + glob_pattern: "**/*.json".to_string(), + kind: Some(lsp_types::WatchKind::Change), + }], + }; + let registration = lsp_types::Registration { + id: "workspace/didChangeWatchedFiles".to_string(), + method: "workspace/didChangeWatchedFiles".to_string(), + register_options: Some( + serde_json::to_value(watch_registration_options).unwrap(), + ), + }; + self.send_request::<lsp_types::request::RegisterCapability>( + lsp_types::RegistrationParams { + registrations: vec![registration], + }, + |_, _| (), + ); + self.transition(Status::Ready); while let Some(event) = self.next_event(&inbox) { |