diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index ed0a0d8ee8..31415a2dd6 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -341,6 +341,7 @@ pub trait LspAdapter: 'static + Send + Sync { // TODO kb enable this for // markdown somehow? // tailwind (needs a css plugin, there are 2 of them) + // svelte (needs a plugin) fn enabled_formatters(&self) -> Vec { Vec::new() } @@ -348,12 +349,16 @@ pub trait LspAdapter: 'static + Send + Sync { #[derive(Clone, Debug, PartialEq, Eq)] pub enum BundledFormatter { - Prettier { plugin_names: Vec }, + Prettier { + parser_name: &'static str, + plugin_names: Vec, + }, } impl BundledFormatter { - pub fn prettier() -> Self { + pub fn prettier(parser_name: &'static str) -> Self { Self::Prettier { + parser_name, plugin_names: Vec::new(), } } diff --git a/crates/prettier/src/prettier.rs b/crates/prettier/src/prettier.rs index f94801c01b..68374d8a03 100644 --- a/crates/prettier/src/prettier.rs +++ b/crates/prettier/src/prettier.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use anyhow::Context; use fs::Fs; use gpui::{AsyncAppContext, ModelHandle, Task}; -use language::{Buffer, Diff}; +use language::{Buffer, BundledFormatter, Diff}; use lsp::{LanguageServer, LanguageServerBinary, LanguageServerId}; use node_runtime::NodeRuntime; use serde::{Deserialize, Serialize}; @@ -187,16 +187,30 @@ impl Prettier { buffer: &ModelHandle, cx: &AsyncAppContext, ) -> anyhow::Result { - // TODO kb prettier needs either a path or a `parser` (depends on a language) option to format - let (buffer_text, buffer_language) = - buffer.read_with(cx, |buffer, _| (buffer.text(), buffer.language().cloned())); + let params = buffer.read_with(cx, |buffer, cx| { + let path = buffer + .file() + .map(|file| file.full_path(cx)) + .map(|path| path.to_path_buf()); + let parser = buffer.language().and_then(|language| { + language + .lsp_adapters() + .iter() + .flat_map(|adapter| adapter.enabled_formatters()) + .find_map(|formatter| match formatter { + BundledFormatter::Prettier { parser_name, .. } => { + Some(parser_name.to_string()) + } + }) + }); + PrettierFormatParams { + text: buffer.text(), + options: FormatOptions { parser, path }, + } + }); let response = self .server - .request::(PrettierFormatParams { - text: buffer_text, - path: None, - parser: None, - }) + .request::(params) .await .context("prettier format request")?; let diff_task = buffer.read_with(cx, |buffer, cx| buffer.diff(response.text, cx)); @@ -262,9 +276,14 @@ enum PrettierFormat {} #[serde(rename_all = "camelCase")] struct PrettierFormatParams { text: String, - // TODO kb have "options" or something more generic instead? + options: FormatOptions, +} + +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +struct FormatOptions { parser: Option, - path: Option, + path: Option, } #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] diff --git a/crates/prettier/src/prettier_server.js b/crates/prettier/src/prettier_server.js index a0f7f0da5e..5e86720cd8 100644 --- a/crates/prettier/src/prettier_server.js +++ b/crates/prettier/src/prettier_server.js @@ -131,12 +131,16 @@ async function handleMessage(messageText, prettier) { if (params === undefined || params.text === undefined) { throw new Error(`Message params.text is undefined: ${messageText}`); } + if (params.options === undefined) { + throw new Error(`Message params.options is undefined: ${messageText}`); + } let options = {}; - if (message.path !== undefined) { - options.filepath = message.path; - } else { - options.parser = message.parser || 'babel'; + if (params.options.path !== undefined) { + options.filepath = params.options.path; + } + if (params.options.parser !== undefined) { + options.parser = params.options.parser; } const formattedText = await prettier.format(params.text, options); sendResponse({ id, result: { text: formattedText } }); diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 84b5f09cac..cf8df9eafd 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -8323,7 +8323,7 @@ impl Project { .flat_map(|adapter| adapter.enabled_formatters()) { match formatter { - BundledFormatter::Prettier { plugin_names } => prettier_plugins + BundledFormatter::Prettier { plugin_names, .. } => prettier_plugins .get_or_insert_with(|| HashSet::default()) .extend(plugin_names), } diff --git a/crates/zed/src/languages/css.rs b/crates/zed/src/languages/css.rs index a28523a741..f046437d75 100644 --- a/crates/zed/src/languages/css.rs +++ b/crates/zed/src/languages/css.rs @@ -98,7 +98,7 @@ impl LspAdapter for CssLspAdapter { } fn enabled_formatters(&self) -> Vec { - vec![BundledFormatter::prettier()] + vec![BundledFormatter::prettier("css")] } } diff --git a/crates/zed/src/languages/html.rs b/crates/zed/src/languages/html.rs index af8fb1690c..6f27b7ca8f 100644 --- a/crates/zed/src/languages/html.rs +++ b/crates/zed/src/languages/html.rs @@ -98,7 +98,7 @@ impl LspAdapter for HtmlLspAdapter { } fn enabled_formatters(&self) -> Vec { - vec![BundledFormatter::prettier()] + vec![BundledFormatter::prettier("html")] } } diff --git a/crates/zed/src/languages/json.rs b/crates/zed/src/languages/json.rs index e66a5d96a6..f017af0a22 100644 --- a/crates/zed/src/languages/json.rs +++ b/crates/zed/src/languages/json.rs @@ -148,7 +148,7 @@ impl LspAdapter for JsonLspAdapter { } fn enabled_formatters(&self) -> Vec { - vec![BundledFormatter::prettier()] + vec![BundledFormatter::prettier("json")] } } diff --git a/crates/zed/src/languages/php.rs b/crates/zed/src/languages/php.rs index f8f9351111..bf65deb642 100644 --- a/crates/zed/src/languages/php.rs +++ b/crates/zed/src/languages/php.rs @@ -3,7 +3,7 @@ use anyhow::{anyhow, Result}; use async_trait::async_trait; use collections::HashMap; -use language::{BundledFormatter, LanguageServerName, LspAdapter, LspAdapterDelegate}; +use language::{LanguageServerName, LspAdapter, LspAdapterDelegate}; use lsp::LanguageServerBinary; use node_runtime::NodeRuntime; @@ -100,13 +100,10 @@ impl LspAdapter for IntelephenseLspAdapter { async fn initialization_options(&self) -> Option { None } + async fn language_ids(&self) -> HashMap { HashMap::from_iter([("PHP".into(), "php".into())]) } - - fn enabled_formatters(&self) -> Vec { - vec![BundledFormatter::prettier()] - } } async fn get_cached_server_binary( diff --git a/crates/zed/src/languages/svelte.rs b/crates/zed/src/languages/svelte.rs index 487720ce46..5e42d80e77 100644 --- a/crates/zed/src/languages/svelte.rs +++ b/crates/zed/src/languages/svelte.rs @@ -1,7 +1,7 @@ use anyhow::{anyhow, Result}; use async_trait::async_trait; use futures::StreamExt; -use language::{BundledFormatter, LanguageServerName, LspAdapter, LspAdapterDelegate}; +use language::{LanguageServerName, LspAdapter, LspAdapterDelegate}; use lsp::LanguageServerBinary; use node_runtime::NodeRuntime; use serde_json::json; @@ -95,10 +95,6 @@ impl LspAdapter for SvelteLspAdapter { "provideFormatter": true })) } - - fn enabled_formatters(&self) -> Vec { - vec![BundledFormatter::prettier()] - } } async fn get_cached_server_binary( diff --git a/crates/zed/src/languages/typescript.rs b/crates/zed/src/languages/typescript.rs index 78b1214b1a..f09c964588 100644 --- a/crates/zed/src/languages/typescript.rs +++ b/crates/zed/src/languages/typescript.rs @@ -163,7 +163,7 @@ impl LspAdapter for TypeScriptLspAdapter { } fn enabled_formatters(&self) -> Vec { - vec![BundledFormatter::prettier()] + vec![BundledFormatter::prettier("typescript")] } } @@ -315,7 +315,7 @@ impl LspAdapter for EsLintLspAdapter { } fn enabled_formatters(&self) -> Vec { - vec![BundledFormatter::prettier()] + vec![BundledFormatter::prettier("babel")] } } diff --git a/crates/zed/src/languages/yaml.rs b/crates/zed/src/languages/yaml.rs index c9168b3480..1c1ce18668 100644 --- a/crates/zed/src/languages/yaml.rs +++ b/crates/zed/src/languages/yaml.rs @@ -111,7 +111,7 @@ impl LspAdapter for YamlLspAdapter { } fn enabled_formatters(&self) -> Vec { - vec![BundledFormatter::prettier()] + vec![BundledFormatter::prettier("yaml")] } }