diff --git a/cli/lsp/completions.rs b/cli/lsp/completions.rs index 7a93c8baf1..73f772cf22 100644 --- a/cli/lsp/completions.rs +++ b/cli/lsp/completions.rs @@ -526,7 +526,7 @@ mod tests { documents.open( specifier.clone(), *version, - language_id.clone(), + *language_id, (*source).into(), ); } diff --git a/cli/lsp/diagnostics.rs b/cli/lsp/diagnostics.rs index 58156bad26..2723b44dbd 100644 --- a/cli/lsp/diagnostics.rs +++ b/cli/lsp/diagnostics.rs @@ -1010,7 +1010,7 @@ mod tests { documents.open( specifier.clone(), *version, - language_id.clone(), + *language_id, (*source).into(), ); } diff --git a/cli/lsp/documents.rs b/cli/lsp/documents.rs index 308e987bdb..edf5497aba 100644 --- a/cli/lsp/documents.rs +++ b/cli/lsp/documents.rs @@ -80,7 +80,7 @@ static TSX_HEADERS: Lazy> = Lazy::new(|| { .collect() }); -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum LanguageId { JavaScript, Jsx, @@ -93,6 +93,31 @@ pub enum LanguageId { } impl LanguageId { + pub fn as_media_type(&self) -> MediaType { + match self { + LanguageId::JavaScript => MediaType::JavaScript, + LanguageId::Jsx => MediaType::Jsx, + LanguageId::TypeScript => MediaType::TypeScript, + LanguageId::Tsx => MediaType::Tsx, + LanguageId::Json => MediaType::Json, + LanguageId::JsonC => MediaType::Json, + LanguageId::Markdown | LanguageId::Unknown => MediaType::Unknown, + } + } + + pub fn as_extension(&self) -> Option<&'static str> { + match self { + LanguageId::JavaScript => Some("js"), + LanguageId::Jsx => Some("jsx"), + LanguageId::TypeScript => Some("ts"), + LanguageId::Tsx => Some("tsx"), + LanguageId::Json => Some("json"), + LanguageId::JsonC => Some("jsonc"), + LanguageId::Markdown => Some("md"), + LanguageId::Unknown => None, + } + } + fn as_headers(&self) -> Option<&HashMap> { match self { Self::JavaScript => Some(&JS_HEADERS), @@ -394,7 +419,7 @@ impl Document { Ok(Document(Arc::new(DocumentInner { specifier: self.0.specifier.clone(), fs_version: self.0.fs_version.clone(), - maybe_language_id: self.0.maybe_language_id.clone(), + maybe_language_id: self.0.maybe_language_id, dependencies, text_info, line_index, @@ -464,10 +489,22 @@ impl Document { pub fn media_type(&self) -> MediaType { if let Some(Ok(module)) = &self.0.maybe_module { - module.media_type - } else { - MediaType::from(&self.0.specifier) + return module.media_type; } + let specifier_media_type = MediaType::from(&self.0.specifier); + if specifier_media_type != MediaType::Unknown { + return specifier_media_type; + } + + self + .0 + .maybe_language_id + .map(|id| id.as_media_type()) + .unwrap_or(MediaType::Unknown) + } + + pub fn maybe_language_id(&self) -> Option { + self.0.maybe_language_id } /// Returns the current language server client version if any. diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index a97b3d1f2b..e23db159a8 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -1212,6 +1212,14 @@ impl Inner { } Some(Err(err)) => Err(anyhow!("{}", err)), None => { + // the file path is only used to determine what formatter should + // be used to format the file, so give the filepath an extension + // that matches what the user selected as the language + let file_path = document + .maybe_language_id() + .and_then(|id| id.as_extension()) + .map(|ext| file_path.with_extension(ext)) + .unwrap_or(file_path); // it's not a js/ts file, so attempt to format its contents format_file(&file_path, &document.content(), &fmt_options) } diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs index c6b5315e06..de34c7fa6a 100644 --- a/cli/lsp/tsc.rs +++ b/cli/lsp/tsc.rs @@ -3466,7 +3466,7 @@ mod tests { documents.open( specifier.clone(), *version, - language_id.clone(), + *language_id, (*source).into(), ); } diff --git a/cli/tests/lsp_tests.rs b/cli/tests/lsp_tests.rs index 066f3efa81..8ed6a67d71 100644 --- a/cli/tests/lsp_tests.rs +++ b/cli/tests/lsp_tests.rs @@ -5339,7 +5339,9 @@ mod lsp { "textDocument/didOpen", json!({ "textDocument": { - "uri": "file:///a/file.json", + // Also test out using a non-json file extension here. + // What should matter is the language identifier. + "uri": "file:///a/file.lock", "languageId": "json", "version": 1, "text": "{\"key\":\"value\"}" @@ -5353,7 +5355,7 @@ mod lsp { "textDocument/formatting", json!({ "textDocument": { - "uri": "file:///a/file.json" + "uri": "file:///a/file.lock" }, "options": { "tabSize": 2,