From 939279aa1075aab9b647e9a149df31da346fa7f2 Mon Sep 17 00:00:00 2001 From: Nayeem Rahman Date: Tue, 26 Sep 2023 03:54:07 +0100 Subject: [PATCH] feat(lsp): support more vscode built-in settings (#20679) --- cli/lsp/config.rs | 151 ++++++++++++++++++++++++ cli/lsp/language_server.rs | 227 ++++++++++++++++++------------------- cli/lsp/repl.rs | 32 ++++-- cli/lsp/tsc.rs | 164 +++++++++++++++++++-------- 4 files changed, 399 insertions(+), 175 deletions(-) diff --git a/cli/lsp/config.rs b/cli/lsp/config.rs index 52ee362b8c..d0ef33d405 100644 --- a/cli/lsp/config.rs +++ b/cli/lsp/config.rs @@ -94,26 +94,67 @@ pub struct DenoCompletionSettings { pub imports: ImportCompletionSettings, } +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct ClassMemberSnippets { + #[serde(default = "is_true")] + pub enabled: bool, +} + +impl Default for ClassMemberSnippets { + fn default() -> Self { + Self { enabled: true } + } +} + +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct ObjectLiteralMethodSnippets { + #[serde(default = "is_true")] + pub enabled: bool, +} + +impl Default for ObjectLiteralMethodSnippets { + fn default() -> Self { + Self { enabled: true } + } +} + #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct CompletionSettings { #[serde(default)] pub complete_function_calls: bool, #[serde(default = "is_true")] + pub include_automatic_optional_chain_completions: bool, + #[serde(default = "is_true")] + pub include_completions_for_import_statements: bool, + #[serde(default = "is_true")] pub names: bool, #[serde(default = "is_true")] pub paths: bool, #[serde(default = "is_true")] pub auto_imports: bool, + #[serde(default = "is_true")] + pub enabled: bool, + #[serde(default)] + pub class_member_snippets: ClassMemberSnippets, + #[serde(default)] + pub object_literal_method_snippets: ObjectLiteralMethodSnippets, } impl Default for CompletionSettings { fn default() -> Self { Self { complete_function_calls: false, + include_automatic_optional_chain_completions: true, + include_completions_for_import_statements: true, names: true, paths: true, auto_imports: true, + enabled: true, + class_member_snippets: Default::default(), + object_literal_method_snippets: Default::default(), } } } @@ -286,13 +327,91 @@ fn empty_string_none<'de, D: serde::Deserializer<'de>>( Ok(o.filter(|s| !s.is_empty())) } +#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)] +#[serde(rename_all = "kebab-case")] +pub enum ImportModuleSpecifier { + NonRelative, + ProjectRelative, + Relative, + Shortest, +} + +impl Default for ImportModuleSpecifier { + fn default() -> Self { + Self::Shortest + } +} + +#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)] +#[serde(rename_all = "kebab-case")] +pub enum JsxAttributeCompletionStyle { + Auto, + Braces, + None, +} + +impl Default for JsxAttributeCompletionStyle { + fn default() -> Self { + Self::Auto + } +} + +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct LanguagePreferences { + #[serde(default)] + pub import_module_specifier: ImportModuleSpecifier, + #[serde(default)] + pub jsx_attribute_completion_style: JsxAttributeCompletionStyle, + #[serde(default)] + pub auto_import_file_exclude_patterns: Vec, + #[serde(default = "is_true")] + pub use_aliases_for_renames: bool, +} + +impl Default for LanguagePreferences { + fn default() -> Self { + LanguagePreferences { + import_module_specifier: Default::default(), + jsx_attribute_completion_style: Default::default(), + auto_import_file_exclude_patterns: vec![], + use_aliases_for_renames: true, + } + } +} + +#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct UpdateImportsOnFileMoveOptions { + #[serde(default)] + pub enabled: UpdateImportsOnFileMoveEnabled, +} + +#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)] +#[serde(rename_all = "kebab-case")] +pub enum UpdateImportsOnFileMoveEnabled { + Always, + Prompt, + Never, +} + +impl Default for UpdateImportsOnFileMoveEnabled { + fn default() -> Self { + Self::Prompt + } +} + #[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct LanguageWorkspaceSettings { #[serde(default)] pub inlay_hints: InlayHintsSettings, #[serde(default)] + pub preferences: LanguagePreferences, + #[serde(default)] pub suggest: CompletionSettings, + #[serde(default)] + pub update_imports_on_file_move: UpdateImportsOnFileMoveOptions, } /// Deno language server specific settings that are applied to a workspace. @@ -1244,12 +1363,28 @@ mod tests { enabled: false }, }, + preferences: LanguagePreferences { + import_module_specifier: ImportModuleSpecifier::Shortest, + jsx_attribute_completion_style: JsxAttributeCompletionStyle::Auto, + auto_import_file_exclude_patterns: vec![], + use_aliases_for_renames: true, + }, suggest: CompletionSettings { complete_function_calls: false, + include_automatic_optional_chain_completions: true, + include_completions_for_import_statements: true, names: true, paths: true, auto_imports: true, + enabled: true, + class_member_snippets: ClassMemberSnippets { enabled: true }, + object_literal_method_snippets: ObjectLiteralMethodSnippets { + enabled: true, + }, }, + update_imports_on_file_move: UpdateImportsOnFileMoveOptions { + enabled: UpdateImportsOnFileMoveEnabled::Prompt + } }, typescript: LanguageWorkspaceSettings { inlay_hints: InlayHintsSettings { @@ -1272,12 +1407,28 @@ mod tests { enabled: false }, }, + preferences: LanguagePreferences { + import_module_specifier: ImportModuleSpecifier::Shortest, + jsx_attribute_completion_style: JsxAttributeCompletionStyle::Auto, + auto_import_file_exclude_patterns: vec![], + use_aliases_for_renames: true, + }, suggest: CompletionSettings { complete_function_calls: false, + include_automatic_optional_chain_completions: true, + include_completions_for_import_statements: true, names: true, paths: true, auto_imports: true, + enabled: true, + class_member_snippets: ClassMemberSnippets { enabled: true }, + object_literal_method_snippets: ObjectLiteralMethodSnippets { + enabled: true, + }, }, + update_imports_on_file_move: UpdateImportsOnFileMoveOptions { + enabled: UpdateImportsOnFileMoveEnabled::Prompt + } }, } ); diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index c415cf45bc..c72239aa72 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -45,6 +45,7 @@ use super::code_lens; use super::completions; use super::config::Config; use super::config::ConfigSnapshot; +use super::config::UpdateImportsOnFileMoveEnabled; use super::config::WorkspaceSettings; use super::config::SETTINGS_SECTION; use super::diagnostics; @@ -1933,13 +1934,11 @@ impl Inner { ..line_index.offset_tsc(diagnostic.range.end)?, codes, (&self.fmt_options.options).into(), - tsc::UserPreferences { - quote_preference: Some((&self.fmt_options.options).into()), - ..tsc::UserPreferences::from_workspace_settings_for_specifier( - self.config.workspace_settings(), - &specifier, - ) - }, + tsc::UserPreferences::from_config_for_specifier( + &self.config, + &self.fmt_options.options, + &specifier, + ), ) .await; for action in actions { @@ -2024,13 +2023,11 @@ impl Inner { specifier.clone(), line_index.offset_tsc(params.range.start)? ..line_index.offset_tsc(params.range.end)?, - Some(tsc::UserPreferences { - quote_preference: Some((&self.fmt_options.options).into()), - ..tsc::UserPreferences::from_workspace_settings_for_specifier( - self.config.workspace_settings(), - &specifier, - ) - }), + Some(tsc::UserPreferences::from_config_for_specifier( + &self.config, + &self.fmt_options.options, + &specifier, + )), only, ) .await?; @@ -2086,13 +2083,11 @@ impl Inner { self.snapshot(), &code_action_data, (&self.fmt_options.options).into(), - tsc::UserPreferences { - quote_preference: Some((&self.fmt_options.options).into()), - ..tsc::UserPreferences::from_workspace_settings_for_specifier( - self.config.workspace_settings(), - &code_action_data.specifier, - ) - }, + tsc::UserPreferences::from_config_for_specifier( + &self.config, + &self.fmt_options.options, + &code_action_data.specifier, + ), ) .await?; if combined_code_actions.commands.is_some() { @@ -2138,13 +2133,11 @@ impl Inner { ..line_index.offset_tsc(action_data.range.end)?, action_data.refactor_name, action_data.action_name, - Some(tsc::UserPreferences { - quote_preference: Some((&self.fmt_options.options).into()), - ..tsc::UserPreferences::from_workspace_settings_for_specifier( - self.config.workspace_settings(), - &action_data.specifier, - ) - }), + Some(tsc::UserPreferences::from_config_for_specifier( + &self.config, + &self.fmt_options.options, + &action_data.specifier, + )), ) .await?; code_action.edit = refactor_edit_info.to_workspace_edit(self).await?; @@ -2413,8 +2406,13 @@ impl Inner { ¶ms.text_document_position.text_document.uri, LspUrlKind::File, ); + let language_settings = self + .config + .workspace_settings() + .language_settings_for_specifier(&specifier); if !self.is_diagnosable(&specifier) || !self.config.specifier_enabled(&specifier) + || !language_settings.map(|s| s.suggest.enabled).unwrap_or(true) { return Ok(None); } @@ -2425,20 +2423,24 @@ impl Inner { // completions, we will use internal logic and if there are completions // for imports, we will return those and not send a message into tsc, where // other completions come from. - let response = if let Some(response) = completions::get_import_completions( - &specifier, - ¶ms.text_document_position.position, - &self.config.snapshot(), - &self.client, - &self.module_registries, - &self.npm.search_api, - &self.documents, - self.maybe_import_map.clone(), - ) - .await + let mut response = None; + if language_settings + .map(|s| s.suggest.include_completions_for_import_statements) + .unwrap_or(true) { - Some(response) - } else { + response = completions::get_import_completions( + &specifier, + ¶ms.text_document_position.position, + &self.config.snapshot(), + &self.client, + &self.module_registries, + &self.npm.search_api, + &self.documents, + self.maybe_import_map.clone(), + ) + .await; + } + if response.is_none() { let line_index = asset_or_doc.line_index(); let (trigger_character, trigger_kind) = if let Some(context) = ¶ms.context { @@ -2451,7 +2453,6 @@ impl Inner { }; let position = line_index.offset_tsc(params.text_document_position.position)?; - let use_snippets = self.config.client_capabilities.snippet_support; let maybe_completion_info = self .ts_server .get_completions( @@ -2459,38 +2460,11 @@ impl Inner { specifier.clone(), position, tsc::GetCompletionsAtPositionOptions { - user_preferences: tsc::UserPreferences { - quote_preference: Some((&self.fmt_options.options).into()), - allow_incomplete_completions: Some(true), - allow_text_changes_in_new_files: Some( - specifier.scheme() == "file", - ), - import_module_specifier_ending: Some( - tsc::ImportModuleSpecifierEnding::Index, - ), - include_automatic_optional_chain_completions: Some(true), - include_completions_for_import_statements: Some(true), - include_completions_for_module_exports: self - .config - .workspace_settings() - .language_settings_for_specifier(&specifier) - .map(|s| s.suggest.auto_imports), - include_completions_with_object_literal_method_snippets: Some( - use_snippets, - ), - include_completions_with_class_member_snippets: Some( - use_snippets, - ), - include_completions_with_insert_text: Some(true), - include_completions_with_snippet_text: Some(use_snippets), - jsx_attribute_completion_style: Some( - tsc::JsxAttributeCompletionStyle::Auto, - ), - provide_prefix_and_suffix_text_for_rename: Some(true), - provide_refactor_not_applicable_reason: Some(true), - use_label_details_in_completion_entries: Some(true), - ..Default::default() - }, + user_preferences: tsc::UserPreferences::from_config_for_specifier( + &self.config, + &self.fmt_options.options, + &specifier, + ), trigger_character, trigger_kind, }, @@ -2499,22 +2473,21 @@ impl Inner { .await; if let Some(completions) = maybe_completion_info { - let results = completions.as_completion_response( - line_index, - &self - .config - .workspace_settings() - .language_settings_for_specifier(&specifier) - .cloned() - .unwrap_or_default() - .suggest, - &specifier, - position, - self, + response = Some( + completions.as_completion_response( + line_index, + &self + .config + .workspace_settings() + .language_settings_for_specifier(&specifier) + .cloned() + .unwrap_or_default() + .suggest, + &specifier, + position, + self, + ), ); - Some(results) - } else { - None } }; self.performance.measure(mark); @@ -2536,17 +2509,22 @@ impl Inner { })?; if let Some(data) = &data.tsc { let specifier = &data.specifier; - let mut args = GetCompletionDetailsArgs { - format_code_settings: Some((&self.fmt_options.options).into()), - ..data.into() - }; - args - .preferences - .get_or_insert(Default::default()) - .quote_preference = Some((&self.fmt_options.options).into()); let result = self .ts_server - .get_completion_details(self.snapshot(), args) + .get_completion_details( + self.snapshot(), + GetCompletionDetailsArgs { + format_code_settings: Some((&self.fmt_options.options).into()), + preferences: Some( + tsc::UserPreferences::from_config_for_specifier( + &self.config, + &self.fmt_options.options, + specifier, + ), + ), + ..data.into() + }, + ) .await; match result { Ok(maybe_completion_info) => { @@ -3029,15 +3007,27 @@ impl Inner { ) -> LspResult> { let mut changes = vec![]; for rename in params.files { + let old_specifier = self.url_map.normalize_url( + &resolve_url(&rename.old_uri).unwrap(), + LspUrlKind::File, + ); + let options = self + .config + .workspace_settings() + .language_settings_for_specifier(&old_specifier) + .map(|s| s.update_imports_on_file_move.clone()) + .unwrap_or_default(); + // Note that `Always` and `Prompt` are treated the same in the server, the + // client will worry about that after receiving the edits. + if options.enabled == UpdateImportsOnFileMoveEnabled::Never { + continue; + } changes.extend( self .ts_server .get_edits_for_file_rename( self.snapshot(), - self.url_map.normalize_url( - &resolve_url(&rename.old_uri).unwrap(), - LspUrlKind::File, - ), + old_specifier, self.url_map.normalize_url( &resolve_url(&rename.new_uri).unwrap(), LspUrlKind::File, @@ -3300,20 +3290,19 @@ impl tower_lsp::LanguageServer for LanguageServer { async fn did_save(&self, params: DidSaveTextDocumentParams) { let uri = ¶ms.text_document.uri; - let Ok(path) = specifier_to_file_path(uri) else { - return; - }; - if !is_importable_ext(&path) { - return; - } { let inner = self.0.read().await; + let specifier = inner.url_map.normalize_url(uri, LspUrlKind::File); if !inner.config.workspace_settings().cache_on_save - || !inner.config.specifier_enabled(uri) - || !inner.diagnostics_state.has_no_cache_diagnostics(uri) + || !inner.config.specifier_enabled(&specifier) + || !inner.diagnostics_state.has_no_cache_diagnostics(&specifier) { return; } + match specifier_to_file_path(&specifier) { + Ok(path) if is_importable_ext(&path) => {} + _ => return, + } } if let Err(err) = self .cache_request(Some( @@ -3677,10 +3666,12 @@ impl Inner { let specifier = self .url_map .normalize_url(¶ms.text_document.uri, LspUrlKind::File); - let workspace_settings = self.config.workspace_settings(); if !self.is_diagnosable(&specifier) || !self.config.specifier_enabled(&specifier) - || !workspace_settings.enabled_inlay_hints(&specifier) + || !self + .config + .workspace_settings() + .enabled_inlay_hints(&specifier) { return Ok(None); } @@ -3701,13 +3692,11 @@ impl Inner { self.snapshot(), specifier.clone(), text_span, - tsc::UserPreferences { - quote_preference: Some((&self.fmt_options.options).into()), - ..tsc::UserPreferences::from_workspace_settings_for_specifier( - workspace_settings, - &specifier, - ) - }, + tsc::UserPreferences::from_config_for_specifier( + &self.config, + &self.fmt_options.options, + &specifier, + ), ) .await?; let maybe_inlay_hints = maybe_inlay_hints.map(|hints| { diff --git a/cli/lsp/repl.rs b/cli/lsp/repl.rs index 2512d2073c..836d75a5bb 100644 --- a/cli/lsp/repl.rs +++ b/cli/lsp/repl.rs @@ -32,10 +32,12 @@ use tower_lsp::lsp_types::WorkDoneProgressParams; use tower_lsp::LanguageServer; use super::client::Client; +use super::config::ClassMemberSnippets; use super::config::CompletionSettings; use super::config::DenoCompletionSettings; use super::config::ImportCompletionSettings; use super::config::LanguageWorkspaceSettings; +use super::config::ObjectLiteralMethodSnippets; use super::config::TestingSettings; use super::config::WorkspaceSettings; @@ -309,22 +311,36 @@ pub fn get_repl_workspace_settings() -> WorkspaceSettings { }, testing: TestingSettings { args: vec![] }, javascript: LanguageWorkspaceSettings { - inlay_hints: Default::default(), suggest: CompletionSettings { - complete_function_calls: false, - names: false, - paths: false, auto_imports: false, + class_member_snippets: ClassMemberSnippets { enabled: false }, + complete_function_calls: false, + enabled: true, + include_automatic_optional_chain_completions: false, + include_completions_for_import_statements: true, + names: false, + object_literal_method_snippets: ObjectLiteralMethodSnippets { + enabled: false, + }, + paths: false, }, + ..Default::default() }, typescript: LanguageWorkspaceSettings { - inlay_hints: Default::default(), suggest: CompletionSettings { - complete_function_calls: false, - names: false, - paths: false, auto_imports: false, + class_member_snippets: ClassMemberSnippets { enabled: false }, + complete_function_calls: false, + enabled: true, + include_automatic_optional_chain_completions: false, + include_completions_for_import_statements: true, + names: false, + object_literal_method_snippets: ObjectLiteralMethodSnippets { + enabled: false, + }, + paths: false, }, + ..Default::default() }, } } diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs index e4c71e976f..77bfd20780 100644 --- a/cli/lsp/tsc.rs +++ b/cli/lsp/tsc.rs @@ -3532,14 +3532,7 @@ impl From<&FmtOptionsConfig> for QuotePreference { } } -#[derive(Debug, Serialize)] -#[serde(rename_all = "kebab-case")] -#[allow(dead_code)] -pub enum ImportModuleSpecifierPreference { - Auto, - Relative, - NonRelative, -} +pub type ImportModuleSpecifierPreference = config::ImportModuleSpecifier; #[derive(Debug, Serialize)] #[serde(rename_all = "kebab-case")] @@ -3581,14 +3574,7 @@ pub enum IncludePackageJsonAutoImports { Off, } -#[derive(Debug, Serialize)] -#[serde(rename_all = "kebab-case")] -#[allow(dead_code)] -pub enum JsxAttributeCompletionStyle { - Auto, - Braces, - None, -} +pub type JsxAttributeCompletionStyle = config::JsxAttributeCompletionStyle; #[derive(Debug, Default, Serialize)] #[serde(rename_all = "camelCase")] @@ -3666,35 +3652,115 @@ pub struct UserPreferences { } impl UserPreferences { - pub fn from_workspace_settings_for_specifier( - settings: &config::WorkspaceSettings, + pub fn from_config_for_specifier( + config: &config::Config, + fmt_config: &FmtOptionsConfig, specifier: &ModuleSpecifier, ) -> Self { - let language_settings = settings.language_settings_for_specifier(specifier); - Self { - include_inlay_parameter_name_hints: language_settings - .map(|s| (&s.inlay_hints.parameter_names.enabled).into()), - include_inlay_parameter_name_hints_when_argument_matches_name: - language_settings.map(|s| { - !s.inlay_hints - .parameter_names - .suppress_when_argument_matches_name - }), - include_inlay_function_parameter_type_hints: language_settings - .map(|s| s.inlay_hints.parameter_types.enabled), - include_inlay_variable_type_hints: language_settings - .map(|s| s.inlay_hints.variable_types.enabled), - include_inlay_variable_type_hints_when_type_matches_name: - language_settings.map(|s| { - !s.inlay_hints.variable_types.suppress_when_type_matches_name - }), - include_inlay_property_declaration_type_hints: language_settings - .map(|s| s.inlay_hints.property_declaration_types.enabled), - include_inlay_function_like_return_type_hints: language_settings - .map(|s| s.inlay_hints.function_like_return_types.enabled), - include_inlay_enum_member_value_hints: language_settings - .map(|s| s.inlay_hints.enum_member_values.enabled), + let base_preferences = Self { + allow_incomplete_completions: Some(true), + allow_text_changes_in_new_files: Some(specifier.scheme() == "file"), + // TODO(nayeemrmn): Investigate why we use `Index` here. + import_module_specifier_ending: Some(ImportModuleSpecifierEnding::Index), + include_completions_with_snippet_text: Some( + config.client_capabilities.snippet_support, + ), + provide_refactor_not_applicable_reason: Some(true), + quote_preference: Some(fmt_config.into()), + use_label_details_in_completion_entries: Some(true), ..Default::default() + }; + let Some(language_settings) = config + .workspace_settings() + .language_settings_for_specifier(specifier) + else { + return base_preferences; + }; + Self { + auto_import_file_exclude_patterns: Some( + language_settings + .preferences + .auto_import_file_exclude_patterns + .clone(), + ), + include_automatic_optional_chain_completions: Some( + language_settings.suggest.enabled + && language_settings + .suggest + .include_automatic_optional_chain_completions, + ), + include_completions_for_import_statements: Some( + language_settings.suggest.enabled + && language_settings + .suggest + .include_completions_for_import_statements, + ), + include_completions_for_module_exports: Some( + language_settings.suggest.enabled + && language_settings.suggest.auto_imports, + ), + include_completions_with_class_member_snippets: Some( + language_settings.suggest.enabled + && language_settings.suggest.class_member_snippets.enabled + && config.client_capabilities.snippet_support, + ), + include_completions_with_insert_text: Some( + language_settings.suggest.enabled, + ), + include_completions_with_object_literal_method_snippets: Some( + language_settings.suggest.enabled + && language_settings + .suggest + .object_literal_method_snippets + .enabled + && config.client_capabilities.snippet_support, + ), + import_module_specifier_preference: Some( + language_settings.preferences.import_module_specifier, + ), + include_inlay_parameter_name_hints: Some( + (&language_settings.inlay_hints.parameter_names.enabled).into(), + ), + include_inlay_parameter_name_hints_when_argument_matches_name: Some( + !language_settings + .inlay_hints + .parameter_names + .suppress_when_argument_matches_name, + ), + include_inlay_function_parameter_type_hints: Some( + language_settings.inlay_hints.parameter_types.enabled, + ), + include_inlay_variable_type_hints: Some( + language_settings.inlay_hints.variable_types.enabled, + ), + include_inlay_variable_type_hints_when_type_matches_name: Some( + !language_settings + .inlay_hints + .variable_types + .suppress_when_type_matches_name, + ), + include_inlay_property_declaration_type_hints: Some( + language_settings + .inlay_hints + .property_declaration_types + .enabled, + ), + include_inlay_function_like_return_type_hints: Some( + language_settings + .inlay_hints + .function_like_return_types + .enabled, + ), + include_inlay_enum_member_value_hints: Some( + language_settings.inlay_hints.enum_member_values.enabled, + ), + jsx_attribute_completion_style: Some( + language_settings.preferences.jsx_attribute_completion_style, + ), + provide_prefix_and_suffix_text_for_rename: Some( + language_settings.preferences.use_aliases_for_renames, + ), + ..base_preferences } } } @@ -5149,7 +5215,7 @@ mod tests { } #[test] - fn include_suppress_inlay_hit_settings() { + fn include_suppress_inlay_hint_settings() { let mut settings = WorkspaceSettings::default(); settings .typescript @@ -5161,11 +5227,13 @@ mod tests { .inlay_hints .variable_types .suppress_when_type_matches_name = true; - let user_preferences = - UserPreferences::from_workspace_settings_for_specifier( - &settings, - &ModuleSpecifier::parse("file:///foo.ts").unwrap(), - ); + let mut config = config::Config::new(); + config.set_workspace_settings(settings); + let user_preferences = UserPreferences::from_config_for_specifier( + &config, + &Default::default(), + &ModuleSpecifier::parse("file:///foo.ts").unwrap(), + ); assert_eq!( user_preferences.include_inlay_variable_type_hints_when_type_matches_name, Some(false)