mirror of
https://github.com/denoland/deno.git
synced 2024-12-24 08:09:08 -05:00
refactor(lsp): store language sections in WorkspaceSettings (#20593)
When sending configuration requests to the client, reads `javascript` and `typescript` sections in addition to `deno`. The LSP's initialization options now accepts `javascript` and `typescript` namespaces.
This commit is contained in:
parent
0981aefbdc
commit
a4ac6a3f5f
7 changed files with 501 additions and 185 deletions
|
@ -7,7 +7,6 @@ use deno_core::anyhow::anyhow;
|
||||||
use deno_core::anyhow::bail;
|
use deno_core::anyhow::bail;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::serde_json;
|
use deno_core::serde_json;
|
||||||
use deno_core::serde_json::Value;
|
|
||||||
use deno_core::unsync::spawn;
|
use deno_core::unsync::spawn;
|
||||||
use tower_lsp::lsp_types as lsp;
|
use tower_lsp::lsp_types as lsp;
|
||||||
use tower_lsp::lsp_types::ConfigurationItem;
|
use tower_lsp::lsp_types::ConfigurationItem;
|
||||||
|
@ -15,6 +14,7 @@ use tower_lsp::lsp_types::ConfigurationItem;
|
||||||
use crate::lsp::repl::get_repl_workspace_settings;
|
use crate::lsp::repl::get_repl_workspace_settings;
|
||||||
|
|
||||||
use super::config::SpecifierSettings;
|
use super::config::SpecifierSettings;
|
||||||
|
use super::config::WorkspaceSettings;
|
||||||
use super::config::SETTINGS_SECTION;
|
use super::config::SETTINGS_SECTION;
|
||||||
use super::lsp_custom;
|
use super::lsp_custom;
|
||||||
use super::testing::lsp_custom as testing_lsp_custom;
|
use super::testing::lsp_custom as testing_lsp_custom;
|
||||||
|
@ -148,7 +148,9 @@ impl OutsideLockClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn workspace_configuration(&self) -> Result<Value, AnyError> {
|
pub async fn workspace_configuration(
|
||||||
|
&self,
|
||||||
|
) -> Result<WorkspaceSettings, AnyError> {
|
||||||
self.0.workspace_configuration().await
|
self.0.workspace_configuration().await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +188,9 @@ trait ClientTrait: Send + Sync {
|
||||||
&self,
|
&self,
|
||||||
uris: Vec<lsp::Url>,
|
uris: Vec<lsp::Url>,
|
||||||
) -> Result<Vec<Result<SpecifierSettings, AnyError>>, AnyError>;
|
) -> Result<Vec<Result<SpecifierSettings, AnyError>>, AnyError>;
|
||||||
async fn workspace_configuration(&self) -> Result<Value, AnyError>;
|
async fn workspace_configuration(
|
||||||
|
&self,
|
||||||
|
) -> Result<WorkspaceSettings, AnyError>;
|
||||||
async fn show_message(&self, message_type: lsp::MessageType, text: String);
|
async fn show_message(&self, message_type: lsp::MessageType, text: String);
|
||||||
async fn register_capability(
|
async fn register_capability(
|
||||||
&self,
|
&self,
|
||||||
|
@ -284,19 +288,36 @@ impl ClientTrait for TowerClient {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn workspace_configuration(&self) -> Result<Value, AnyError> {
|
async fn workspace_configuration(
|
||||||
|
&self,
|
||||||
|
) -> Result<WorkspaceSettings, AnyError> {
|
||||||
let config_response = self
|
let config_response = self
|
||||||
.0
|
.0
|
||||||
.configuration(vec![ConfigurationItem {
|
.configuration(vec![
|
||||||
scope_uri: None,
|
ConfigurationItem {
|
||||||
section: Some(SETTINGS_SECTION.to_string()),
|
scope_uri: None,
|
||||||
}])
|
section: Some(SETTINGS_SECTION.to_string()),
|
||||||
|
},
|
||||||
|
ConfigurationItem {
|
||||||
|
scope_uri: None,
|
||||||
|
section: Some("javascript".to_string()),
|
||||||
|
},
|
||||||
|
ConfigurationItem {
|
||||||
|
scope_uri: None,
|
||||||
|
section: Some("typescript".to_string()),
|
||||||
|
},
|
||||||
|
])
|
||||||
.await;
|
.await;
|
||||||
match config_response {
|
match config_response {
|
||||||
Ok(value_vec) => match value_vec.get(0).cloned() {
|
Ok(configs) => {
|
||||||
Some(value) => Ok(value),
|
let mut configs = configs.into_iter();
|
||||||
None => bail!("Missing response workspace configuration."),
|
let deno = serde_json::to_value(configs.next()).unwrap();
|
||||||
},
|
let javascript = serde_json::to_value(configs.next()).unwrap();
|
||||||
|
let typescript = serde_json::to_value(configs.next()).unwrap();
|
||||||
|
Ok(WorkspaceSettings::from_raw_settings(
|
||||||
|
deno, javascript, typescript,
|
||||||
|
))
|
||||||
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
bail!("Error getting workspace configuration: {}", err)
|
bail!("Error getting workspace configuration: {}", err)
|
||||||
}
|
}
|
||||||
|
@ -367,8 +388,10 @@ impl ClientTrait for ReplClient {
|
||||||
Ok(settings)
|
Ok(settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn workspace_configuration(&self) -> Result<Value, AnyError> {
|
async fn workspace_configuration(
|
||||||
Ok(serde_json::to_value(get_repl_workspace_settings()).unwrap())
|
&self,
|
||||||
|
) -> Result<WorkspaceSettings, AnyError> {
|
||||||
|
Ok(get_repl_workspace_settings())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn show_message(
|
async fn show_message(
|
||||||
|
|
|
@ -5,8 +5,9 @@ use crate::args::ConfigFile;
|
||||||
use crate::lsp::logging::lsp_warn;
|
use crate::lsp::logging::lsp_warn;
|
||||||
use crate::util::fs::canonicalize_path_maybe_not_exists;
|
use crate::util::fs::canonicalize_path_maybe_not_exists;
|
||||||
use crate::util::path::specifier_to_file_path;
|
use crate::util::path::specifier_to_file_path;
|
||||||
use deno_core::error::AnyError;
|
use deno_ast::MediaType;
|
||||||
use deno_core::parking_lot::Mutex;
|
use deno_core::parking_lot::Mutex;
|
||||||
|
use deno_core::serde::de::DeserializeOwned;
|
||||||
use deno_core::serde::Deserialize;
|
use deno_core::serde::Deserialize;
|
||||||
use deno_core::serde::Serialize;
|
use deno_core::serde::Serialize;
|
||||||
use deno_core::serde_json;
|
use deno_core::serde_json;
|
||||||
|
@ -86,6 +87,13 @@ impl Default for CodeLensSpecifierSettings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DenoCompletionSettings {
|
||||||
|
#[serde(default)]
|
||||||
|
pub imports: ImportCompletionSettings,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct CompletionSettings {
|
pub struct CompletionSettings {
|
||||||
|
@ -97,8 +105,6 @@ pub struct CompletionSettings {
|
||||||
pub paths: bool,
|
pub paths: bool,
|
||||||
#[serde(default = "is_true")]
|
#[serde(default = "is_true")]
|
||||||
pub auto_imports: bool,
|
pub auto_imports: bool,
|
||||||
#[serde(default)]
|
|
||||||
pub imports: ImportCompletionSettings,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CompletionSettings {
|
impl Default for CompletionSettings {
|
||||||
|
@ -108,7 +114,6 @@ impl Default for CompletionSettings {
|
||||||
names: true,
|
names: true,
|
||||||
paths: true,
|
paths: true,
|
||||||
auto_imports: true,
|
auto_imports: true,
|
||||||
imports: ImportCompletionSettings::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -281,6 +286,15 @@ fn empty_string_none<'de, D: serde::Deserializer<'de>>(
|
||||||
Ok(o.filter(|s| !s.is_empty()))
|
Ok(o.filter(|s| !s.is_empty()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct LanguageWorkspaceSettings {
|
||||||
|
#[serde(default)]
|
||||||
|
pub inlay_hints: InlayHintsSettings,
|
||||||
|
#[serde(default)]
|
||||||
|
pub suggest: CompletionSettings,
|
||||||
|
}
|
||||||
|
|
||||||
/// Deno language server specific settings that are applied to a workspace.
|
/// Deno language server specific settings that are applied to a workspace.
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
|
@ -319,9 +333,6 @@ pub struct WorkspaceSettings {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub code_lens: CodeLensSettings,
|
pub code_lens: CodeLensSettings,
|
||||||
|
|
||||||
#[serde(default)]
|
|
||||||
pub inlay_hints: InlayHintsSettings,
|
|
||||||
|
|
||||||
/// A flag that indicates if internal debug logging should be made available.
|
/// A flag that indicates if internal debug logging should be made available.
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub internal_debug: bool,
|
pub internal_debug: bool,
|
||||||
|
@ -334,10 +345,8 @@ pub struct WorkspaceSettings {
|
||||||
#[serde(default = "default_document_preload_limit")]
|
#[serde(default = "default_document_preload_limit")]
|
||||||
pub document_preload_limit: usize,
|
pub document_preload_limit: usize,
|
||||||
|
|
||||||
/// A flag that indicates if Dene should validate code against the unstable
|
|
||||||
/// APIs for the workspace.
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub suggest: CompletionSettings,
|
pub suggest: DenoCompletionSettings,
|
||||||
|
|
||||||
/// Testing settings for the workspace.
|
/// Testing settings for the workspace.
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
@ -355,6 +364,12 @@ pub struct WorkspaceSettings {
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub unstable: bool,
|
pub unstable: bool,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub javascript: LanguageWorkspaceSettings,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub typescript: LanguageWorkspaceSettings,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for WorkspaceSettings {
|
impl Default for WorkspaceSettings {
|
||||||
|
@ -368,7 +383,6 @@ impl Default for WorkspaceSettings {
|
||||||
config: None,
|
config: None,
|
||||||
import_map: None,
|
import_map: None,
|
||||||
code_lens: Default::default(),
|
code_lens: Default::default(),
|
||||||
inlay_hints: Default::default(),
|
|
||||||
internal_debug: false,
|
internal_debug: false,
|
||||||
lint: true,
|
lint: true,
|
||||||
document_preload_limit: default_document_preload_limit(),
|
document_preload_limit: default_document_preload_limit(),
|
||||||
|
@ -377,28 +391,220 @@ impl Default for WorkspaceSettings {
|
||||||
tls_certificate: None,
|
tls_certificate: None,
|
||||||
unsafely_ignore_certificate_errors: None,
|
unsafely_ignore_certificate_errors: None,
|
||||||
unstable: false,
|
unstable: false,
|
||||||
|
javascript: Default::default(),
|
||||||
|
typescript: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WorkspaceSettings {
|
impl WorkspaceSettings {
|
||||||
|
pub fn from_raw_settings(
|
||||||
|
deno: Value,
|
||||||
|
javascript: Value,
|
||||||
|
typescript: Value,
|
||||||
|
) -> Self {
|
||||||
|
fn parse_or_default<T: Default + DeserializeOwned>(
|
||||||
|
value: Value,
|
||||||
|
description: &str,
|
||||||
|
) -> T {
|
||||||
|
if value.is_null() {
|
||||||
|
return T::default();
|
||||||
|
}
|
||||||
|
match serde_json::from_value(value) {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(err) => {
|
||||||
|
lsp_warn!("Couldn't parse {description}: {err}");
|
||||||
|
T::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let deno_inlay_hints =
|
||||||
|
deno.as_object().and_then(|o| o.get("inlayHints").cloned());
|
||||||
|
let deno_suggest = deno.as_object().and_then(|o| o.get("suggest").cloned());
|
||||||
|
let mut settings: Self = parse_or_default(deno, "settings under \"deno\"");
|
||||||
|
settings.javascript =
|
||||||
|
parse_or_default(javascript, "settings under \"javascript\"");
|
||||||
|
settings.typescript =
|
||||||
|
parse_or_default(typescript, "settings under \"typescript\"");
|
||||||
|
if let Some(inlay_hints) = deno_inlay_hints {
|
||||||
|
let inlay_hints: InlayHintsSettings =
|
||||||
|
parse_or_default(inlay_hints, "settings under \"deno.inlayHints\"");
|
||||||
|
if inlay_hints.parameter_names.enabled != Default::default() {
|
||||||
|
lsp_warn!("\"deno.inlayHints.parameterNames.enabled\" is deprecated. Instead use \"javascript.inlayHints.parameterNames.enabled\" and \"typescript.inlayHints.parameterNames.enabled\".");
|
||||||
|
settings.javascript.inlay_hints.parameter_names.enabled =
|
||||||
|
inlay_hints.parameter_names.enabled.clone();
|
||||||
|
settings.typescript.inlay_hints.parameter_names.enabled =
|
||||||
|
inlay_hints.parameter_names.enabled;
|
||||||
|
}
|
||||||
|
if !inlay_hints
|
||||||
|
.parameter_names
|
||||||
|
.suppress_when_argument_matches_name
|
||||||
|
{
|
||||||
|
lsp_warn!("\"deno.inlayHints.parameterNames.suppressWhenArgumentMatchesName\" is deprecated. Instead use \"javascript.inlayHints.parameterNames.suppressWhenArgumentMatchesName\" and \"typescript.inlayHints.parameterNames.suppressWhenArgumentMatchesName\".");
|
||||||
|
settings
|
||||||
|
.javascript
|
||||||
|
.inlay_hints
|
||||||
|
.parameter_names
|
||||||
|
.suppress_when_argument_matches_name = inlay_hints
|
||||||
|
.parameter_names
|
||||||
|
.suppress_when_argument_matches_name;
|
||||||
|
settings
|
||||||
|
.typescript
|
||||||
|
.inlay_hints
|
||||||
|
.parameter_names
|
||||||
|
.suppress_when_argument_matches_name = inlay_hints
|
||||||
|
.parameter_names
|
||||||
|
.suppress_when_argument_matches_name;
|
||||||
|
}
|
||||||
|
if inlay_hints.parameter_types.enabled {
|
||||||
|
lsp_warn!("\"deno.inlayHints.parameterTypes.enabled\" is deprecated. Instead use \"javascript.inlayHints.parameterTypes.enabled\" and \"typescript.inlayHints.parameterTypes.enabled\".");
|
||||||
|
settings.javascript.inlay_hints.parameter_types.enabled =
|
||||||
|
inlay_hints.parameter_types.enabled;
|
||||||
|
settings.typescript.inlay_hints.parameter_types.enabled =
|
||||||
|
inlay_hints.parameter_types.enabled;
|
||||||
|
}
|
||||||
|
if inlay_hints.variable_types.enabled {
|
||||||
|
lsp_warn!("\"deno.inlayHints.variableTypes.enabled\" is deprecated. Instead use \"javascript.inlayHints.variableTypes.enabled\" and \"typescript.inlayHints.variableTypes.enabled\".");
|
||||||
|
settings.javascript.inlay_hints.variable_types.enabled =
|
||||||
|
inlay_hints.variable_types.enabled;
|
||||||
|
settings.typescript.inlay_hints.variable_types.enabled =
|
||||||
|
inlay_hints.variable_types.enabled;
|
||||||
|
}
|
||||||
|
if !inlay_hints.variable_types.suppress_when_type_matches_name {
|
||||||
|
lsp_warn!("\"deno.inlayHints.variableTypes.suppressWhenTypeMatchesName\" is deprecated. Instead use \"javascript.inlayHints.variableTypes.suppressWhenTypeMatchesName\" and \"typescript.inlayHints.variableTypes.suppressWhenTypeMatchesName\".");
|
||||||
|
settings
|
||||||
|
.javascript
|
||||||
|
.inlay_hints
|
||||||
|
.variable_types
|
||||||
|
.suppress_when_type_matches_name =
|
||||||
|
inlay_hints.variable_types.suppress_when_type_matches_name;
|
||||||
|
settings
|
||||||
|
.typescript
|
||||||
|
.inlay_hints
|
||||||
|
.variable_types
|
||||||
|
.suppress_when_type_matches_name =
|
||||||
|
inlay_hints.variable_types.suppress_when_type_matches_name;
|
||||||
|
}
|
||||||
|
if inlay_hints.property_declaration_types.enabled {
|
||||||
|
lsp_warn!("\"deno.inlayHints.propertyDeclarationTypes.enabled\" is deprecated. Instead use \"javascript.inlayHints.propertyDeclarationTypes.enabled\" and \"typescript.inlayHints.propertyDeclarationTypes.enabled\".");
|
||||||
|
settings
|
||||||
|
.javascript
|
||||||
|
.inlay_hints
|
||||||
|
.property_declaration_types
|
||||||
|
.enabled = inlay_hints.property_declaration_types.enabled;
|
||||||
|
settings
|
||||||
|
.typescript
|
||||||
|
.inlay_hints
|
||||||
|
.property_declaration_types
|
||||||
|
.enabled = inlay_hints.property_declaration_types.enabled;
|
||||||
|
}
|
||||||
|
if inlay_hints.function_like_return_types.enabled {
|
||||||
|
lsp_warn!("\"deno.inlayHints.functionLikeReturnTypes.enabled\" is deprecated. Instead use \"javascript.inlayHints.functionLikeReturnTypes.enabled\" and \"typescript.inlayHints.functionLikeReturnTypes.enabled\".");
|
||||||
|
settings
|
||||||
|
.javascript
|
||||||
|
.inlay_hints
|
||||||
|
.function_like_return_types
|
||||||
|
.enabled = inlay_hints.function_like_return_types.enabled;
|
||||||
|
settings
|
||||||
|
.typescript
|
||||||
|
.inlay_hints
|
||||||
|
.function_like_return_types
|
||||||
|
.enabled = inlay_hints.function_like_return_types.enabled;
|
||||||
|
}
|
||||||
|
if inlay_hints.enum_member_values.enabled {
|
||||||
|
lsp_warn!("\"deno.inlayHints.enumMemberValues.enabled\" is deprecated. Instead use \"javascript.inlayHints.enumMemberValues.enabled\" and \"typescript.inlayHints.enumMemberValues.enabled\".");
|
||||||
|
settings.javascript.inlay_hints.enum_member_values.enabled =
|
||||||
|
inlay_hints.enum_member_values.enabled;
|
||||||
|
settings.typescript.inlay_hints.enum_member_values.enabled =
|
||||||
|
inlay_hints.enum_member_values.enabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(suggest) = deno_suggest {
|
||||||
|
let suggest: CompletionSettings =
|
||||||
|
parse_or_default(suggest, "settings under \"deno.suggest\"");
|
||||||
|
if suggest.complete_function_calls {
|
||||||
|
lsp_warn!("\"deno.suggest.completeFunctionCalls\" is deprecated. Instead use \"javascript.suggest.completeFunctionCalls\" and \"typescript.suggest.completeFunctionCalls\".");
|
||||||
|
settings.javascript.suggest.complete_function_calls =
|
||||||
|
suggest.complete_function_calls;
|
||||||
|
settings.typescript.suggest.complete_function_calls =
|
||||||
|
suggest.complete_function_calls;
|
||||||
|
}
|
||||||
|
if !suggest.names {
|
||||||
|
lsp_warn!("\"deno.suggest.names\" is deprecated. Instead use \"javascript.suggest.names\" and \"typescript.suggest.names\".");
|
||||||
|
settings.javascript.suggest.names = suggest.names;
|
||||||
|
settings.typescript.suggest.names = suggest.names;
|
||||||
|
}
|
||||||
|
if !suggest.paths {
|
||||||
|
lsp_warn!("\"deno.suggest.paths\" is deprecated. Instead use \"javascript.suggest.paths\" and \"typescript.suggest.paths\".");
|
||||||
|
settings.javascript.suggest.paths = suggest.paths;
|
||||||
|
settings.typescript.suggest.paths = suggest.paths;
|
||||||
|
}
|
||||||
|
if !suggest.auto_imports {
|
||||||
|
lsp_warn!("\"deno.suggest.autoImports\" is deprecated. Instead use \"javascript.suggest.autoImports\" and \"typescript.suggest.autoImports\".");
|
||||||
|
settings.javascript.suggest.auto_imports = suggest.auto_imports;
|
||||||
|
settings.typescript.suggest.auto_imports = suggest.auto_imports;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
settings
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_initialization_options(options: Value) -> Self {
|
||||||
|
let deno = options;
|
||||||
|
let javascript = deno
|
||||||
|
.as_object()
|
||||||
|
.and_then(|o| o.get("javascript").cloned())
|
||||||
|
.unwrap_or_default();
|
||||||
|
let typescript = deno
|
||||||
|
.as_object()
|
||||||
|
.and_then(|o| o.get("typescript").cloned())
|
||||||
|
.unwrap_or_default();
|
||||||
|
Self::from_raw_settings(deno, javascript, typescript)
|
||||||
|
}
|
||||||
|
|
||||||
/// Determine if any code lenses are enabled at all. This allows short
|
/// Determine if any code lenses are enabled at all. This allows short
|
||||||
/// circuiting when there are no code lenses enabled.
|
/// circuiting when there are no code lenses enabled.
|
||||||
pub fn enabled_code_lens(&self) -> bool {
|
pub fn enabled_code_lens(&self) -> bool {
|
||||||
self.code_lens.implementations || self.code_lens.references
|
self.code_lens.implementations || self.code_lens.references
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn language_settings_for_specifier(
|
||||||
|
&self,
|
||||||
|
specifier: &ModuleSpecifier,
|
||||||
|
) -> Option<&LanguageWorkspaceSettings> {
|
||||||
|
match MediaType::from_specifier(specifier) {
|
||||||
|
MediaType::JavaScript
|
||||||
|
| MediaType::Jsx
|
||||||
|
| MediaType::Mjs
|
||||||
|
| MediaType::Cjs => Some(&self.javascript),
|
||||||
|
MediaType::TypeScript
|
||||||
|
| MediaType::Mts
|
||||||
|
| MediaType::Cts
|
||||||
|
| MediaType::Dts
|
||||||
|
| MediaType::Dmts
|
||||||
|
| MediaType::Dcts
|
||||||
|
| MediaType::Tsx => Some(&self.typescript),
|
||||||
|
MediaType::Json
|
||||||
|
| MediaType::Wasm
|
||||||
|
| MediaType::TsBuildInfo
|
||||||
|
| MediaType::SourceMap
|
||||||
|
| MediaType::Unknown => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Determine if any inlay hints are enabled. This allows short circuiting
|
/// Determine if any inlay hints are enabled. This allows short circuiting
|
||||||
/// when there are no inlay hints enabled.
|
/// when there are no inlay hints enabled.
|
||||||
pub fn enabled_inlay_hints(&self) -> bool {
|
pub fn enabled_inlay_hints(&self, specifier: &ModuleSpecifier) -> bool {
|
||||||
|
let Some(settings) = self.language_settings_for_specifier(specifier) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
!matches!(
|
!matches!(
|
||||||
self.inlay_hints.parameter_names.enabled,
|
settings.inlay_hints.parameter_names.enabled,
|
||||||
InlayHintsParamNamesEnabled::None
|
InlayHintsParamNamesEnabled::None
|
||||||
) || self.inlay_hints.parameter_types.enabled
|
) || settings.inlay_hints.parameter_types.enabled
|
||||||
|| self.inlay_hints.variable_types.enabled
|
|| settings.inlay_hints.variable_types.enabled
|
||||||
|| self.inlay_hints.property_declaration_types.enabled
|
|| settings.inlay_hints.property_declaration_types.enabled
|
||||||
|| self.inlay_hints.function_like_return_types.enabled
|
|| settings.inlay_hints.function_like_return_types.enabled
|
||||||
|| self.inlay_hints.enum_member_values.enabled
|
|| settings.inlay_hints.enum_member_values.enabled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,16 +799,12 @@ impl Config {
|
||||||
|
|
||||||
/// Set the workspace settings directly, which occurs during initialization
|
/// Set the workspace settings directly, which occurs during initialization
|
||||||
/// and when the client does not support workspace configuration requests
|
/// and when the client does not support workspace configuration requests
|
||||||
pub fn set_workspace_settings(
|
pub fn set_workspace_settings(&mut self, settings: WorkspaceSettings) {
|
||||||
&mut self,
|
self.settings.workspace = settings;
|
||||||
value: Value,
|
|
||||||
) -> Result<(), AnyError> {
|
|
||||||
self.settings.workspace = serde_json::from_value(value)?;
|
|
||||||
// See https://github.com/denoland/vscode_deno/issues/908.
|
// See https://github.com/denoland/vscode_deno/issues/908.
|
||||||
if self.settings.workspace.enable_paths == Some(vec![]) {
|
if self.settings.workspace.enable_paths == Some(vec![]) {
|
||||||
self.settings.workspace.enable_paths = None;
|
self.settings.workspace.enable_paths = None;
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn snapshot(&self) -> Arc<ConfigSnapshot> {
|
pub fn snapshot(&self) -> Arc<ConfigSnapshot> {
|
||||||
|
@ -912,6 +1114,7 @@ fn resolve_lockfile_from_path(lockfile_path: PathBuf) -> Option<Lockfile> {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use deno_core::resolve_url;
|
use deno_core::resolve_url;
|
||||||
|
use deno_core::serde_json;
|
||||||
use deno_core::serde_json::json;
|
use deno_core::serde_json::json;
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
|
@ -921,11 +1124,12 @@ mod tests {
|
||||||
let mut config = Config::new_with_root(root_uri);
|
let mut config = Config::new_with_root(root_uri);
|
||||||
let specifier = resolve_url("file:///a.ts").unwrap();
|
let specifier = resolve_url("file:///a.ts").unwrap();
|
||||||
assert!(!config.specifier_enabled(&specifier));
|
assert!(!config.specifier_enabled(&specifier));
|
||||||
config
|
config.set_workspace_settings(
|
||||||
.set_workspace_settings(json!({
|
serde_json::from_value(json!({
|
||||||
"enable": true
|
"enable": true
|
||||||
}))
|
}))
|
||||||
.expect("could not update");
|
.unwrap(),
|
||||||
|
);
|
||||||
assert!(config.specifier_enabled(&specifier));
|
assert!(config.specifier_enabled(&specifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -935,11 +1139,12 @@ mod tests {
|
||||||
let mut config = Config::new_with_root(root_uri);
|
let mut config = Config::new_with_root(root_uri);
|
||||||
let specifier = resolve_url("file:///a.ts").unwrap();
|
let specifier = resolve_url("file:///a.ts").unwrap();
|
||||||
assert!(!config.specifier_enabled(&specifier));
|
assert!(!config.specifier_enabled(&specifier));
|
||||||
config
|
config.set_workspace_settings(
|
||||||
.set_workspace_settings(json!({
|
serde_json::from_value(json!({
|
||||||
"enable": true
|
"enable": true
|
||||||
}))
|
}))
|
||||||
.expect("could not update");
|
.unwrap(),
|
||||||
|
);
|
||||||
let config_snapshot = config.snapshot();
|
let config_snapshot = config.snapshot();
|
||||||
assert!(config_snapshot.specifier_enabled(&specifier));
|
assert!(config_snapshot.specifier_enabled(&specifier));
|
||||||
}
|
}
|
||||||
|
@ -954,7 +1159,7 @@ mod tests {
|
||||||
assert!(!config.specifier_enabled(&specifier_b));
|
assert!(!config.specifier_enabled(&specifier_b));
|
||||||
let workspace_settings =
|
let workspace_settings =
|
||||||
serde_json::from_str(r#"{ "enablePaths": ["worker"] }"#).unwrap();
|
serde_json::from_str(r#"{ "enablePaths": ["worker"] }"#).unwrap();
|
||||||
config.set_workspace_settings(workspace_settings).unwrap();
|
config.set_workspace_settings(workspace_settings);
|
||||||
assert!(config.specifier_enabled(&specifier_a));
|
assert!(config.specifier_enabled(&specifier_a));
|
||||||
assert!(!config.specifier_enabled(&specifier_b));
|
assert!(!config.specifier_enabled(&specifier_b));
|
||||||
let config_snapshot = config.snapshot();
|
let config_snapshot = config.snapshot();
|
||||||
|
@ -979,9 +1184,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_set_workspace_settings_defaults() {
|
fn test_set_workspace_settings_defaults() {
|
||||||
let mut config = Config::new();
|
let mut config = Config::new();
|
||||||
config
|
config.set_workspace_settings(serde_json::from_value(json!({})).unwrap());
|
||||||
.set_workspace_settings(json!({}))
|
|
||||||
.expect("could not update");
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.workspace_settings().clone(),
|
config.workspace_settings().clone(),
|
||||||
WorkspaceSettings {
|
WorkspaceSettings {
|
||||||
|
@ -998,34 +1201,10 @@ mod tests {
|
||||||
references_all_functions: false,
|
references_all_functions: false,
|
||||||
test: true,
|
test: true,
|
||||||
},
|
},
|
||||||
inlay_hints: InlayHintsSettings {
|
|
||||||
parameter_names: InlayHintsParamNamesOptions {
|
|
||||||
enabled: InlayHintsParamNamesEnabled::None,
|
|
||||||
suppress_when_argument_matches_name: true
|
|
||||||
},
|
|
||||||
parameter_types: InlayHintsParamTypesOptions { enabled: false },
|
|
||||||
variable_types: InlayHintsVarTypesOptions {
|
|
||||||
enabled: false,
|
|
||||||
suppress_when_type_matches_name: true
|
|
||||||
},
|
|
||||||
property_declaration_types: InlayHintsPropDeclTypesOptions {
|
|
||||||
enabled: false
|
|
||||||
},
|
|
||||||
function_like_return_types: InlayHintsFuncLikeReturnTypesOptions {
|
|
||||||
enabled: false
|
|
||||||
},
|
|
||||||
enum_member_values: InlayHintsEnumMemberValuesOptions {
|
|
||||||
enabled: false
|
|
||||||
},
|
|
||||||
},
|
|
||||||
internal_debug: false,
|
internal_debug: false,
|
||||||
lint: true,
|
lint: true,
|
||||||
document_preload_limit: 1_000,
|
document_preload_limit: 1_000,
|
||||||
suggest: CompletionSettings {
|
suggest: DenoCompletionSettings {
|
||||||
complete_function_calls: false,
|
|
||||||
names: true,
|
|
||||||
paths: true,
|
|
||||||
auto_imports: true,
|
|
||||||
imports: ImportCompletionSettings {
|
imports: ImportCompletionSettings {
|
||||||
auto_discover: true,
|
auto_discover: true,
|
||||||
hosts: HashMap::new(),
|
hosts: HashMap::new(),
|
||||||
|
@ -1037,6 +1216,62 @@ mod tests {
|
||||||
tls_certificate: None,
|
tls_certificate: None,
|
||||||
unsafely_ignore_certificate_errors: None,
|
unsafely_ignore_certificate_errors: None,
|
||||||
unstable: false,
|
unstable: false,
|
||||||
|
javascript: LanguageWorkspaceSettings {
|
||||||
|
inlay_hints: InlayHintsSettings {
|
||||||
|
parameter_names: InlayHintsParamNamesOptions {
|
||||||
|
enabled: InlayHintsParamNamesEnabled::None,
|
||||||
|
suppress_when_argument_matches_name: true
|
||||||
|
},
|
||||||
|
parameter_types: InlayHintsParamTypesOptions { enabled: false },
|
||||||
|
variable_types: InlayHintsVarTypesOptions {
|
||||||
|
enabled: false,
|
||||||
|
suppress_when_type_matches_name: true
|
||||||
|
},
|
||||||
|
property_declaration_types: InlayHintsPropDeclTypesOptions {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
function_like_return_types: InlayHintsFuncLikeReturnTypesOptions {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
enum_member_values: InlayHintsEnumMemberValuesOptions {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
suggest: CompletionSettings {
|
||||||
|
complete_function_calls: false,
|
||||||
|
names: true,
|
||||||
|
paths: true,
|
||||||
|
auto_imports: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
typescript: LanguageWorkspaceSettings {
|
||||||
|
inlay_hints: InlayHintsSettings {
|
||||||
|
parameter_names: InlayHintsParamNamesOptions {
|
||||||
|
enabled: InlayHintsParamNamesEnabled::None,
|
||||||
|
suppress_when_argument_matches_name: true
|
||||||
|
},
|
||||||
|
parameter_types: InlayHintsParamTypesOptions { enabled: false },
|
||||||
|
variable_types: InlayHintsVarTypesOptions {
|
||||||
|
enabled: false,
|
||||||
|
suppress_when_type_matches_name: true
|
||||||
|
},
|
||||||
|
property_declaration_types: InlayHintsPropDeclTypesOptions {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
function_like_return_types: InlayHintsFuncLikeReturnTypesOptions {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
enum_member_values: InlayHintsEnumMemberValuesOptions {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
suggest: CompletionSettings {
|
||||||
|
complete_function_calls: false,
|
||||||
|
names: true,
|
||||||
|
paths: true,
|
||||||
|
auto_imports: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1044,9 +1279,9 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_empty_cache() {
|
fn test_empty_cache() {
|
||||||
let mut config = Config::new();
|
let mut config = Config::new();
|
||||||
config
|
config.set_workspace_settings(
|
||||||
.set_workspace_settings(json!({ "cache": "" }))
|
serde_json::from_value(json!({ "cache": "" })).unwrap(),
|
||||||
.expect("could not update");
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.workspace_settings().clone(),
|
config.workspace_settings().clone(),
|
||||||
WorkspaceSettings::default()
|
WorkspaceSettings::default()
|
||||||
|
@ -1056,9 +1291,9 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_empty_import_map() {
|
fn test_empty_import_map() {
|
||||||
let mut config = Config::new();
|
let mut config = Config::new();
|
||||||
config
|
config.set_workspace_settings(
|
||||||
.set_workspace_settings(json!({ "import_map": "" }))
|
serde_json::from_value(json!({ "import_map": "" })).unwrap(),
|
||||||
.expect("could not update");
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.workspace_settings().clone(),
|
config.workspace_settings().clone(),
|
||||||
WorkspaceSettings::default()
|
WorkspaceSettings::default()
|
||||||
|
@ -1068,9 +1303,9 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_empty_tls_certificate() {
|
fn test_empty_tls_certificate() {
|
||||||
let mut config = Config::new();
|
let mut config = Config::new();
|
||||||
config
|
config.set_workspace_settings(
|
||||||
.set_workspace_settings(json!({ "tls_certificate": "" }))
|
serde_json::from_value(json!({ "tls_certificate": "" })).unwrap(),
|
||||||
.expect("could not update");
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.workspace_settings().clone(),
|
config.workspace_settings().clone(),
|
||||||
WorkspaceSettings::default()
|
WorkspaceSettings::default()
|
||||||
|
@ -1080,9 +1315,9 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_empty_config() {
|
fn test_empty_config() {
|
||||||
let mut config = Config::new();
|
let mut config = Config::new();
|
||||||
config
|
config.set_workspace_settings(
|
||||||
.set_workspace_settings(json!({ "config": "" }))
|
serde_json::from_value(json!({ "config": "" })).unwrap(),
|
||||||
.expect("could not update");
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.workspace_settings().clone(),
|
config.workspace_settings().clone(),
|
||||||
WorkspaceSettings::default()
|
WorkspaceSettings::default()
|
||||||
|
|
|
@ -45,6 +45,7 @@ use super::code_lens;
|
||||||
use super::completions;
|
use super::completions;
|
||||||
use super::config::Config;
|
use super::config::Config;
|
||||||
use super::config::ConfigSnapshot;
|
use super::config::ConfigSnapshot;
|
||||||
|
use super::config::WorkspaceSettings;
|
||||||
use super::config::SETTINGS_SECTION;
|
use super::config::SETTINGS_SECTION;
|
||||||
use super::diagnostics;
|
use super::diagnostics;
|
||||||
use super::diagnostics::DiagnosticServerUpdateMessage;
|
use super::diagnostics::DiagnosticServerUpdateMessage;
|
||||||
|
@ -1265,11 +1266,10 @@ impl Inner {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
if let Some(value) = params.initialization_options {
|
if let Some(options) = params.initialization_options {
|
||||||
self.config.set_workspace_settings(value).map_err(|err| {
|
self.config.set_workspace_settings(
|
||||||
error!("Cannot set workspace settings: {}", err);
|
WorkspaceSettings::from_initialization_options(options),
|
||||||
LspError::internal_error()
|
);
|
||||||
})?;
|
|
||||||
}
|
}
|
||||||
if let Some(folders) = params.workspace_folders {
|
if let Some(folders) = params.workspace_folders {
|
||||||
self.config.workspace_folders = folders
|
self.config.workspace_folders = folders
|
||||||
|
@ -1472,24 +1472,26 @@ impl Inner {
|
||||||
|
|
||||||
async fn did_change_configuration(
|
async fn did_change_configuration(
|
||||||
&mut self,
|
&mut self,
|
||||||
client_workspace_config: Option<Value>,
|
client_workspace_config: Option<WorkspaceSettings>,
|
||||||
params: DidChangeConfigurationParams,
|
params: DidChangeConfigurationParams,
|
||||||
) {
|
) {
|
||||||
let maybe_config =
|
let maybe_config =
|
||||||
if self.config.client_capabilities.workspace_configuration {
|
if self.config.client_capabilities.workspace_configuration {
|
||||||
client_workspace_config
|
client_workspace_config
|
||||||
} else {
|
} else {
|
||||||
params
|
params.settings.as_object().map(|settings| {
|
||||||
.settings
|
let deno =
|
||||||
.as_object()
|
serde_json::to_value(settings.get(SETTINGS_SECTION)).unwrap();
|
||||||
.and_then(|settings| settings.get(SETTINGS_SECTION))
|
let javascript =
|
||||||
.cloned()
|
serde_json::to_value(settings.get("javascript")).unwrap();
|
||||||
|
let typescript =
|
||||||
|
serde_json::to_value(settings.get("typescript")).unwrap();
|
||||||
|
WorkspaceSettings::from_raw_settings(deno, javascript, typescript)
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(value) = maybe_config {
|
if let Some(settings) = maybe_config {
|
||||||
if let Err(err) = self.config.set_workspace_settings(value) {
|
self.config.set_workspace_settings(settings);
|
||||||
error!("failed to update settings: {}", err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.update_debug_flag();
|
self.update_debug_flag();
|
||||||
|
@ -1929,7 +1931,10 @@ impl Inner {
|
||||||
(&self.fmt_options.options).into(),
|
(&self.fmt_options.options).into(),
|
||||||
tsc::UserPreferences {
|
tsc::UserPreferences {
|
||||||
quote_preference: Some((&self.fmt_options.options).into()),
|
quote_preference: Some((&self.fmt_options.options).into()),
|
||||||
..self.config.workspace_settings().into()
|
..tsc::UserPreferences::from_workspace_settings_for_specifier(
|
||||||
|
self.config.workspace_settings(),
|
||||||
|
&specifier,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
@ -1990,7 +1995,10 @@ impl Inner {
|
||||||
..line_index.offset_tsc(params.range.end)?,
|
..line_index.offset_tsc(params.range.end)?,
|
||||||
Some(tsc::UserPreferences {
|
Some(tsc::UserPreferences {
|
||||||
quote_preference: Some((&self.fmt_options.options).into()),
|
quote_preference: Some((&self.fmt_options.options).into()),
|
||||||
..self.config.workspace_settings().into()
|
..tsc::UserPreferences::from_workspace_settings_for_specifier(
|
||||||
|
self.config.workspace_settings(),
|
||||||
|
&specifier,
|
||||||
|
)
|
||||||
}),
|
}),
|
||||||
only,
|
only,
|
||||||
)
|
)
|
||||||
|
@ -2049,7 +2057,10 @@ impl Inner {
|
||||||
(&self.fmt_options.options).into(),
|
(&self.fmt_options.options).into(),
|
||||||
tsc::UserPreferences {
|
tsc::UserPreferences {
|
||||||
quote_preference: Some((&self.fmt_options.options).into()),
|
quote_preference: Some((&self.fmt_options.options).into()),
|
||||||
..self.config.workspace_settings().into()
|
..tsc::UserPreferences::from_workspace_settings_for_specifier(
|
||||||
|
self.config.workspace_settings(),
|
||||||
|
&code_action_data.specifier,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -2090,7 +2101,7 @@ impl Inner {
|
||||||
.ts_server
|
.ts_server
|
||||||
.get_edits_for_refactor(
|
.get_edits_for_refactor(
|
||||||
self.snapshot(),
|
self.snapshot(),
|
||||||
action_data.specifier,
|
action_data.specifier.clone(),
|
||||||
(&self.fmt_options.options).into(),
|
(&self.fmt_options.options).into(),
|
||||||
line_index.offset_tsc(action_data.range.start)?
|
line_index.offset_tsc(action_data.range.start)?
|
||||||
..line_index.offset_tsc(action_data.range.end)?,
|
..line_index.offset_tsc(action_data.range.end)?,
|
||||||
|
@ -2098,7 +2109,10 @@ impl Inner {
|
||||||
action_data.action_name,
|
action_data.action_name,
|
||||||
Some(tsc::UserPreferences {
|
Some(tsc::UserPreferences {
|
||||||
quote_preference: Some((&self.fmt_options.options).into()),
|
quote_preference: Some((&self.fmt_options.options).into()),
|
||||||
..self.config.workspace_settings().into()
|
..tsc::UserPreferences::from_workspace_settings_for_specifier(
|
||||||
|
self.config.workspace_settings(),
|
||||||
|
&action_data.specifier,
|
||||||
|
)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -2425,9 +2439,11 @@ impl Inner {
|
||||||
),
|
),
|
||||||
include_automatic_optional_chain_completions: Some(true),
|
include_automatic_optional_chain_completions: Some(true),
|
||||||
include_completions_for_import_statements: Some(true),
|
include_completions_for_import_statements: Some(true),
|
||||||
include_completions_for_module_exports: Some(
|
include_completions_for_module_exports: self
|
||||||
self.config.workspace_settings().suggest.auto_imports,
|
.config
|
||||||
),
|
.workspace_settings()
|
||||||
|
.language_settings_for_specifier(&specifier)
|
||||||
|
.map(|s| s.suggest.auto_imports),
|
||||||
include_completions_with_object_literal_method_snippets: Some(
|
include_completions_with_object_literal_method_snippets: Some(
|
||||||
use_snippets,
|
use_snippets,
|
||||||
),
|
),
|
||||||
|
@ -2454,7 +2470,13 @@ impl Inner {
|
||||||
if let Some(completions) = maybe_completion_info {
|
if let Some(completions) = maybe_completion_info {
|
||||||
let results = completions.as_completion_response(
|
let results = completions.as_completion_response(
|
||||||
line_index,
|
line_index,
|
||||||
&self.config.workspace_settings().suggest,
|
&self
|
||||||
|
.config
|
||||||
|
.workspace_settings()
|
||||||
|
.language_settings_for_specifier(&specifier)
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_default()
|
||||||
|
.suggest,
|
||||||
&specifier,
|
&specifier,
|
||||||
position,
|
position,
|
||||||
self,
|
self,
|
||||||
|
@ -3284,7 +3306,7 @@ impl tower_lsp::LanguageServer for LanguageServer {
|
||||||
.workspace_configuration()
|
.workspace_configuration()
|
||||||
.await;
|
.await;
|
||||||
match config_response {
|
match config_response {
|
||||||
Ok(value) => Some(value),
|
Ok(settings) => Some(settings),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("{}", err);
|
error!("{}", err);
|
||||||
None
|
None
|
||||||
|
@ -3601,7 +3623,7 @@ impl Inner {
|
||||||
let workspace_settings = self.config.workspace_settings();
|
let workspace_settings = self.config.workspace_settings();
|
||||||
if !self.is_diagnosable(&specifier)
|
if !self.is_diagnosable(&specifier)
|
||||||
|| !self.config.specifier_enabled(&specifier)
|
|| !self.config.specifier_enabled(&specifier)
|
||||||
|| !workspace_settings.enabled_inlay_hints()
|
|| !workspace_settings.enabled_inlay_hints(&specifier)
|
||||||
{
|
{
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
@ -3620,11 +3642,14 @@ impl Inner {
|
||||||
.ts_server
|
.ts_server
|
||||||
.provide_inlay_hints(
|
.provide_inlay_hints(
|
||||||
self.snapshot(),
|
self.snapshot(),
|
||||||
specifier,
|
specifier.clone(),
|
||||||
text_span,
|
text_span,
|
||||||
tsc::UserPreferences {
|
tsc::UserPreferences {
|
||||||
quote_preference: Some((&self.fmt_options.options).into()),
|
quote_preference: Some((&self.fmt_options.options).into()),
|
||||||
..workspace_settings.into()
|
..tsc::UserPreferences::from_workspace_settings_for_specifier(
|
||||||
|
workspace_settings,
|
||||||
|
&specifier,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
|
@ -33,7 +33,9 @@ use tower_lsp::LanguageServer;
|
||||||
|
|
||||||
use super::client::Client;
|
use super::client::Client;
|
||||||
use super::config::CompletionSettings;
|
use super::config::CompletionSettings;
|
||||||
|
use super::config::DenoCompletionSettings;
|
||||||
use super::config::ImportCompletionSettings;
|
use super::config::ImportCompletionSettings;
|
||||||
|
use super::config::LanguageWorkspaceSettings;
|
||||||
use super::config::TestingSettings;
|
use super::config::TestingSettings;
|
||||||
use super::config::WorkspaceSettings;
|
use super::config::WorkspaceSettings;
|
||||||
|
|
||||||
|
@ -292,23 +294,36 @@ pub fn get_repl_workspace_settings() -> WorkspaceSettings {
|
||||||
cache: None,
|
cache: None,
|
||||||
import_map: None,
|
import_map: None,
|
||||||
code_lens: Default::default(),
|
code_lens: Default::default(),
|
||||||
inlay_hints: Default::default(),
|
|
||||||
internal_debug: false,
|
internal_debug: false,
|
||||||
lint: false,
|
lint: false,
|
||||||
document_preload_limit: 0, // don't pre-load any modules as it's expensive and not useful for the repl
|
document_preload_limit: 0, // don't pre-load any modules as it's expensive and not useful for the repl
|
||||||
tls_certificate: None,
|
tls_certificate: None,
|
||||||
unsafely_ignore_certificate_errors: None,
|
unsafely_ignore_certificate_errors: None,
|
||||||
unstable: false,
|
unstable: false,
|
||||||
suggest: CompletionSettings {
|
suggest: DenoCompletionSettings {
|
||||||
complete_function_calls: false,
|
|
||||||
names: false,
|
|
||||||
paths: false,
|
|
||||||
auto_imports: false,
|
|
||||||
imports: ImportCompletionSettings {
|
imports: ImportCompletionSettings {
|
||||||
auto_discover: false,
|
auto_discover: false,
|
||||||
hosts: HashMap::from([("https://deno.land".to_string(), true)]),
|
hosts: HashMap::from([("https://deno.land".to_string(), true)]),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
testing: TestingSettings { args: vec![] },
|
testing: TestingSettings { args: vec![] },
|
||||||
|
javascript: LanguageWorkspaceSettings {
|
||||||
|
inlay_hints: Default::default(),
|
||||||
|
suggest: CompletionSettings {
|
||||||
|
complete_function_calls: false,
|
||||||
|
names: false,
|
||||||
|
paths: false,
|
||||||
|
auto_imports: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
typescript: LanguageWorkspaceSettings {
|
||||||
|
inlay_hints: Default::default(),
|
||||||
|
suggest: CompletionSettings {
|
||||||
|
complete_function_calls: false,
|
||||||
|
names: false,
|
||||||
|
paths: false,
|
||||||
|
auto_imports: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3665,36 +3665,35 @@ pub struct UserPreferences {
|
||||||
pub auto_import_file_exclude_patterns: Option<Vec<String>>,
|
pub auto_import_file_exclude_patterns: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&config::WorkspaceSettings> for UserPreferences {
|
impl UserPreferences {
|
||||||
fn from(workspace_settings: &config::WorkspaceSettings) -> Self {
|
pub fn from_workspace_settings_for_specifier(
|
||||||
let inlay_hints = &workspace_settings.inlay_hints;
|
settings: &config::WorkspaceSettings,
|
||||||
|
specifier: &ModuleSpecifier,
|
||||||
|
) -> Self {
|
||||||
|
let language_settings = settings.language_settings_for_specifier(specifier);
|
||||||
Self {
|
Self {
|
||||||
include_inlay_parameter_name_hints: Some(
|
include_inlay_parameter_name_hints: language_settings
|
||||||
(&inlay_hints.parameter_names.enabled).into(),
|
.map(|s| (&s.inlay_hints.parameter_names.enabled).into()),
|
||||||
),
|
include_inlay_parameter_name_hints_when_argument_matches_name:
|
||||||
include_inlay_parameter_name_hints_when_argument_matches_name: Some(
|
language_settings.map(|s| {
|
||||||
!inlay_hints
|
!s.inlay_hints
|
||||||
.parameter_names
|
.parameter_names
|
||||||
.suppress_when_argument_matches_name,
|
.suppress_when_argument_matches_name
|
||||||
),
|
}),
|
||||||
include_inlay_function_parameter_type_hints: Some(
|
include_inlay_function_parameter_type_hints: language_settings
|
||||||
inlay_hints.parameter_types.enabled,
|
.map(|s| s.inlay_hints.parameter_types.enabled),
|
||||||
),
|
include_inlay_variable_type_hints: language_settings
|
||||||
include_inlay_variable_type_hints: Some(
|
.map(|s| s.inlay_hints.variable_types.enabled),
|
||||||
inlay_hints.variable_types.enabled,
|
include_inlay_variable_type_hints_when_type_matches_name:
|
||||||
),
|
language_settings.map(|s| {
|
||||||
include_inlay_variable_type_hints_when_type_matches_name: Some(
|
!s.inlay_hints.variable_types.suppress_when_type_matches_name
|
||||||
!inlay_hints.variable_types.suppress_when_type_matches_name,
|
}),
|
||||||
),
|
include_inlay_property_declaration_type_hints: language_settings
|
||||||
include_inlay_property_declaration_type_hints: Some(
|
.map(|s| s.inlay_hints.property_declaration_types.enabled),
|
||||||
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_function_like_return_type_hints: Some(
|
include_inlay_enum_member_value_hints: language_settings
|
||||||
inlay_hints.function_like_return_types.enabled,
|
.map(|s| s.inlay_hints.enum_member_values.enabled),
|
||||||
),
|
|
||||||
include_inlay_enum_member_value_hints: Some(
|
|
||||||
inlay_hints.enum_member_values.enabled,
|
|
||||||
),
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5153,14 +5152,20 @@ mod tests {
|
||||||
fn include_suppress_inlay_hit_settings() {
|
fn include_suppress_inlay_hit_settings() {
|
||||||
let mut settings = WorkspaceSettings::default();
|
let mut settings = WorkspaceSettings::default();
|
||||||
settings
|
settings
|
||||||
|
.typescript
|
||||||
.inlay_hints
|
.inlay_hints
|
||||||
.parameter_names
|
.parameter_names
|
||||||
.suppress_when_argument_matches_name = true;
|
.suppress_when_argument_matches_name = true;
|
||||||
settings
|
settings
|
||||||
|
.typescript
|
||||||
.inlay_hints
|
.inlay_hints
|
||||||
.variable_types
|
.variable_types
|
||||||
.suppress_when_type_matches_name = true;
|
.suppress_when_type_matches_name = true;
|
||||||
let user_preferences: UserPreferences = (&settings).into();
|
let user_preferences =
|
||||||
|
UserPreferences::from_workspace_settings_for_specifier(
|
||||||
|
&settings,
|
||||||
|
&ModuleSpecifier::parse("file:///foo.ts").unwrap(),
|
||||||
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
user_preferences.include_inlay_variable_type_hints_when_type_matches_name,
|
user_preferences.include_inlay_variable_type_hints_when_type_matches_name,
|
||||||
Some(false)
|
Some(false)
|
||||||
|
|
|
@ -776,12 +776,12 @@ fn lsp_import_attributes() {
|
||||||
"text": "{\"a\":1}"
|
"text": "{\"a\":1}"
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
json!([{
|
&json!({ "deno": {
|
||||||
"enable": true,
|
"enable": true,
|
||||||
"codeLens": {
|
"codeLens": {
|
||||||
"test": true
|
"test": true
|
||||||
}
|
}
|
||||||
}]),
|
} }),
|
||||||
);
|
);
|
||||||
|
|
||||||
let diagnostics = client.did_open(json!({
|
let diagnostics = client.did_open(json!({
|
||||||
|
@ -1131,7 +1131,7 @@ fn lsp_hover_disabled() {
|
||||||
"text": "console.log(Date.now());\n"
|
"text": "console.log(Date.now());\n"
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
json!([{ "enable": false }]),
|
&json!({ "deno": { "enable": false } }),
|
||||||
);
|
);
|
||||||
|
|
||||||
let res = client.write_request(
|
let res = client.write_request(
|
||||||
|
@ -1329,11 +1329,11 @@ fn lsp_workspace_disable_enable_paths() {
|
||||||
}])
|
}])
|
||||||
.set_deno_enable(false);
|
.set_deno_enable(false);
|
||||||
},
|
},
|
||||||
json!([{
|
json!({ "deno": {
|
||||||
"enable": false,
|
"enable": false,
|
||||||
"disablePaths": ["./worker/node.ts"],
|
"disablePaths": ["./worker/node.ts"],
|
||||||
"enablePaths": ["./worker"],
|
"enablePaths": ["./worker"],
|
||||||
}]),
|
} }),
|
||||||
);
|
);
|
||||||
|
|
||||||
client.did_open(json!({
|
client.did_open(json!({
|
||||||
|
@ -3552,12 +3552,12 @@ fn lsp_code_lens_test_disabled() {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
// disable test code lens
|
// disable test code lens
|
||||||
json!([{
|
&json!({ "deno": {
|
||||||
"enable": true,
|
"enable": true,
|
||||||
"codeLens": {
|
"codeLens": {
|
||||||
"test": false
|
"test": false
|
||||||
}
|
}
|
||||||
}]),
|
} }),
|
||||||
);
|
);
|
||||||
let res = client.write_request(
|
let res = client.write_request(
|
||||||
"textDocument/codeLens",
|
"textDocument/codeLens",
|
||||||
|
@ -5160,7 +5160,7 @@ fn lsp_code_actions_deadlock() {
|
||||||
"text": large_file_text,
|
"text": large_file_text,
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
client.handle_configuration_request(json!([{ "enable": true }]));
|
client.handle_configuration_request(&json!({ "deno": { "enable": true } }));
|
||||||
client.write_request(
|
client.write_request(
|
||||||
"textDocument/semanticTokens/full",
|
"textDocument/semanticTokens/full",
|
||||||
json!({
|
json!({
|
||||||
|
@ -5796,9 +5796,9 @@ fn lsp_semantic_tokens_for_disabled_module() {
|
||||||
|builder| {
|
|builder| {
|
||||||
builder.set_deno_enable(false);
|
builder.set_deno_enable(false);
|
||||||
},
|
},
|
||||||
json!({
|
json!({ "deno": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}),
|
} }),
|
||||||
);
|
);
|
||||||
client.did_open(json!({
|
client.did_open(json!({
|
||||||
"textDocument": {
|
"textDocument": {
|
||||||
|
@ -8096,7 +8096,7 @@ fn lsp_configuration_did_change() {
|
||||||
"settings": {}
|
"settings": {}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
let request = json!([{
|
let settings = json!({ "deno": {
|
||||||
"enable": true,
|
"enable": true,
|
||||||
"codeLens": {
|
"codeLens": {
|
||||||
"implementations": true,
|
"implementations": true,
|
||||||
|
@ -8116,11 +8116,11 @@ fn lsp_configuration_did_change() {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"unstable": false
|
"unstable": false
|
||||||
}]);
|
} });
|
||||||
// one for the workspace
|
// one for the workspace
|
||||||
client.handle_configuration_request(request.clone());
|
client.handle_configuration_request(&settings);
|
||||||
// one for the specifier
|
// one for the specifier
|
||||||
client.handle_configuration_request(request);
|
client.handle_configuration_request(&settings);
|
||||||
|
|
||||||
let list = client.get_completion_list(
|
let list = client.get_completion_list(
|
||||||
"file:///a/file.ts",
|
"file:///a/file.ts",
|
||||||
|
@ -8192,16 +8192,20 @@ fn lsp_completions_complete_function_calls() {
|
||||||
"settings": {}
|
"settings": {}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
let request = json!([{
|
let settings = json!({
|
||||||
"enable": true,
|
"deno": {
|
||||||
"suggest": {
|
"enable": true,
|
||||||
"completeFunctionCalls": true,
|
|
||||||
},
|
},
|
||||||
}]);
|
"typescript": {
|
||||||
|
"suggest": {
|
||||||
|
"completeFunctionCalls": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
// one for the workspace
|
// one for the workspace
|
||||||
client.handle_configuration_request(request.clone());
|
client.handle_configuration_request(&settings);
|
||||||
// one for the specifier
|
// one for the specifier
|
||||||
client.handle_configuration_request(request);
|
client.handle_configuration_request(&settings);
|
||||||
|
|
||||||
let list = client.get_completion_list(
|
let list = client.get_completion_list(
|
||||||
"file:///a/file.ts",
|
"file:///a/file.ts",
|
||||||
|
@ -9304,7 +9308,7 @@ fn lsp_node_modules_dir() {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
let request = json!([{
|
let settings = json!({ "deno": {
|
||||||
"enable": true,
|
"enable": true,
|
||||||
"config": "./deno.json",
|
"config": "./deno.json",
|
||||||
"codeLens": {
|
"codeLens": {
|
||||||
|
@ -9321,11 +9325,11 @@ fn lsp_node_modules_dir() {
|
||||||
"imports": {}
|
"imports": {}
|
||||||
},
|
},
|
||||||
"unstable": false
|
"unstable": false
|
||||||
}]);
|
} });
|
||||||
// one for the workspace
|
// one for the workspace
|
||||||
client.handle_configuration_request(request.clone());
|
client.handle_configuration_request(&settings);
|
||||||
// one for the specifier
|
// one for the specifier
|
||||||
client.handle_configuration_request(request);
|
client.handle_configuration_request(&settings);
|
||||||
};
|
};
|
||||||
refresh_config(&mut client);
|
refresh_config(&mut client);
|
||||||
|
|
||||||
|
@ -9439,7 +9443,7 @@ fn lsp_vendor_dir() {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
let request = json!([{
|
let settings = json!({ "deno": {
|
||||||
"enable": true,
|
"enable": true,
|
||||||
"config": "./deno.json",
|
"config": "./deno.json",
|
||||||
"codeLens": {
|
"codeLens": {
|
||||||
|
@ -9456,11 +9460,11 @@ fn lsp_vendor_dir() {
|
||||||
"imports": {}
|
"imports": {}
|
||||||
},
|
},
|
||||||
"unstable": false
|
"unstable": false
|
||||||
}]);
|
} });
|
||||||
// one for the workspace
|
// one for the workspace
|
||||||
client.handle_configuration_request(request.clone());
|
client.handle_configuration_request(&settings);
|
||||||
// one for the specifier
|
// one for the specifier
|
||||||
client.handle_configuration_request(request);
|
client.handle_configuration_request(&settings);
|
||||||
};
|
};
|
||||||
refresh_config(&mut client);
|
refresh_config(&mut client);
|
||||||
|
|
||||||
|
|
|
@ -685,9 +685,9 @@ impl LspClient {
|
||||||
) {
|
) {
|
||||||
self.initialize_with_config(
|
self.initialize_with_config(
|
||||||
do_build,
|
do_build,
|
||||||
json!([{
|
json!({"deno":{
|
||||||
"enable": true
|
"enable": true
|
||||||
}]),
|
}}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -709,18 +709,18 @@ impl LspClient {
|
||||||
self.write_notification("initialized", json!({}));
|
self.write_notification("initialized", json!({}));
|
||||||
self.config = config;
|
self.config = config;
|
||||||
if self.supports_workspace_configuration {
|
if self.supports_workspace_configuration {
|
||||||
self.handle_configuration_request(self.config.clone());
|
self.handle_configuration_request(&self.config.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn did_open(&mut self, params: Value) -> CollectedDiagnostics {
|
pub fn did_open(&mut self, params: Value) -> CollectedDiagnostics {
|
||||||
self.did_open_with_config(params, self.config.clone())
|
self.did_open_with_config(params, &self.config.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn did_open_with_config(
|
pub fn did_open_with_config(
|
||||||
&mut self,
|
&mut self,
|
||||||
params: Value,
|
params: Value,
|
||||||
config: Value,
|
config: &Value,
|
||||||
) -> CollectedDiagnostics {
|
) -> CollectedDiagnostics {
|
||||||
self.did_open_raw(params);
|
self.did_open_raw(params);
|
||||||
if self.supports_workspace_configuration {
|
if self.supports_workspace_configuration {
|
||||||
|
@ -733,9 +733,18 @@ impl LspClient {
|
||||||
self.write_notification("textDocument/didOpen", params);
|
self.write_notification("textDocument/didOpen", params);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_configuration_request(&mut self, result: Value) {
|
pub fn handle_configuration_request(&mut self, settings: &Value) {
|
||||||
let (id, method, _) = self.read_request::<Value>();
|
let (id, method, args) = self.read_request::<Value>();
|
||||||
assert_eq!(method, "workspace/configuration");
|
assert_eq!(method, "workspace/configuration");
|
||||||
|
let params = args.as_ref().unwrap().as_object().unwrap();
|
||||||
|
let items = params.get("items").unwrap().as_array().unwrap();
|
||||||
|
let settings_object = settings.as_object().unwrap();
|
||||||
|
let mut result = vec![];
|
||||||
|
for item in items {
|
||||||
|
let item = item.as_object().unwrap();
|
||||||
|
let section = item.get("section").unwrap().as_str().unwrap();
|
||||||
|
result.push(settings_object.get(section).cloned().unwrap_or_default());
|
||||||
|
}
|
||||||
self.write_response(id, result);
|
self.write_response(id, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue