diff --git a/Cargo.lock b/Cargo.lock index 1795d3d748..4d9b3ee713 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5523,6 +5523,7 @@ name = "prettier" version = "0.1.0" dependencies = [ "anyhow", + "collections", "fs", "futures 0.3.28", "gpui", diff --git a/assets/settings/default.json b/assets/settings/default.json index be47ac9c8c..1611d80e2f 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -199,7 +199,11 @@ // "arguments": ["--stdin-filepath", "{buffer_path}"] // } // } - // TODO kb description + // 3. Format code using Zed's Prettier integration: + // "formatter": "prettier" + // 4. Default. Format files using Zed's Prettier integration (if applicable), + // or falling back to formatting via language server: + // "formatter": "auto" "formatter": "auto", // How to soft-wrap long lines of text. This setting can take // three values: @@ -430,6 +434,16 @@ "tab_size": 2 } }, + // Zed's Prettier integration settings. + // If Prettier is enabled, Zed will use this its Prettier instance for any applicable file, if + // project has no other Prettier installed. + "prettier": { + // Use regular Prettier json configuration: + // "trailingComma": "es5", + // "tabWidth": 4, + // "semi": false, + // "singleQuote": true + }, // LSP Specific settings. "lsp": { // Specify the LSP name as a key here. diff --git a/crates/language/src/language_settings.rs b/crates/language/src/language_settings.rs index 8778ba8d64..9cac5c523e 100644 --- a/crates/language/src/language_settings.rs +++ b/crates/language/src/language_settings.rs @@ -50,6 +50,7 @@ pub struct LanguageSettings { pub remove_trailing_whitespace_on_save: bool, pub ensure_final_newline_on_save: bool, pub formatter: Formatter, + pub prettier: HashMap, pub enable_language_server: bool, pub show_copilot_suggestions: bool, pub show_whitespaces: ShowWhitespaceSetting, @@ -98,6 +99,8 @@ pub struct LanguageSettingsContent { #[serde(default)] pub formatter: Option, #[serde(default)] + pub prettier: Option>, + #[serde(default)] pub enable_language_server: Option, #[serde(default)] pub show_copilot_suggestions: Option, @@ -155,9 +158,7 @@ pub enum Formatter { #[default] Auto, LanguageServer, - Prettier { - config: (), // Support some of the most important settings in the prettier-vscode extension. - }, + Prettier, External { command: Arc, arguments: Arc<[String]>, @@ -397,6 +398,7 @@ fn merge_settings(settings: &mut LanguageSettings, src: &LanguageSettingsContent src.preferred_line_length, ); merge(&mut settings.formatter, src.formatter.clone()); + merge(&mut settings.prettier, src.prettier.clone()); merge(&mut settings.format_on_save, src.format_on_save.clone()); merge( &mut settings.remove_trailing_whitespace_on_save, diff --git a/crates/prettier/Cargo.toml b/crates/prettier/Cargo.toml index d10e8abdf9..129e928da2 100644 --- a/crates/prettier/Cargo.toml +++ b/crates/prettier/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" path = "src/prettier.rs" [dependencies] +collections = { path = "../collections"} language = { path = "../language" } gpui = { path = "../gpui" } fs = { path = "../fs" } diff --git a/crates/prettier/src/prettier.rs b/crates/prettier/src/prettier.rs index 01f1a055d3..77baf6cbf3 100644 --- a/crates/prettier/src/prettier.rs +++ b/crates/prettier/src/prettier.rs @@ -1,8 +1,9 @@ -use std::collections::{HashMap, VecDeque}; +use std::collections::VecDeque; use std::path::{Path, PathBuf}; use std::sync::Arc; use anyhow::Context; +use collections::HashMap; use fs::Fs; use gpui::{AsyncAppContext, ModelHandle}; use language::language_settings::language_settings; @@ -202,7 +203,6 @@ impl Prettier { let params = buffer.read_with(cx, |buffer, cx| { let buffer_file = buffer.file(); let buffer_language = buffer.language(); - let language_settings = language_settings(buffer_language, buffer_file, cx); let path = buffer_file .map(|file| file.full_path(cx)) .map(|path| path.to_path_buf()); @@ -217,14 +217,38 @@ impl Prettier { } }) }); - let tab_width = Some(language_settings.tab_size.get()); + + let prettier_options = if self.default { + let language_settings = language_settings(buffer_language, buffer_file, cx); + let mut options = language_settings.prettier.clone(); + if !options.contains_key("tabWidth") { + options.insert( + "tabWidth".to_string(), + serde_json::Value::Number(serde_json::Number::from( + language_settings.tab_size.get(), + )), + ); + } + if !options.contains_key("printWidth") { + options.insert( + "printWidth".to_string(), + serde_json::Value::Number(serde_json::Number::from( + language_settings.preferred_line_length, + )), + ); + } + Some(options) + } else { + None + }; + FormatParams { text: buffer.text(), options: FormatOptions { parser, // TODO kb is not absolute now path, - tab_width, + prettier_options, }, } }); @@ -318,13 +342,13 @@ struct FormatParams { options: FormatOptions, } -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] struct FormatOptions { parser: Option, #[serde(rename = "filepath")] path: Option, - tab_width: Option, + prettier_options: 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 5896c295f6..0a16a73b14 100644 --- a/crates/prettier/src/prettier_server.js +++ b/crates/prettier/src/prettier_server.js @@ -149,7 +149,13 @@ async function handleMessage(message, prettier) { if (params.options === undefined) { throw new Error(`Message params.options is undefined: ${JSON.stringify(message)}`); } - const formattedText = await prettier.prettier.format(params.text, { ...prettier.config, ...params.options }); + + const options = { + ...(params.options.prettierOptions || prettier.config), + parser: params.options.parser, + path: params.options.path + }; + const formattedText = await prettier.prettier.format(params.text, options); sendResponse({ id, result: { text: formattedText } }); } else if (method === 'prettier/clear_cache') { prettier.prettier.clearConfigCache(); diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index bcf640d865..059256ee3f 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -911,7 +911,6 @@ impl Project { .detach(); } - // TODO kb restart all default formatters if Zed prettier settings change for (worktree, language, settings) in language_formatters_to_check { self.maybe_start_default_formatters(worktree, &language, &settings, cx); } @@ -8428,7 +8427,7 @@ impl Project { } fn maybe_start_default_formatters( - &mut self, + &self, worktree: Option, new_language: &Language, language_settings: &LanguageSettings,