Resolve prettier config before every formatting

This commit is contained in:
Kirill Bulatov 2023-09-23 00:39:46 +03:00
parent 658b58378e
commit a9f80a603c
3 changed files with 19 additions and 15 deletions

View file

@ -199,14 +199,11 @@ impl Prettier {
pub async fn format( pub async fn format(
&self, &self,
buffer: &ModelHandle<Buffer>, buffer: &ModelHandle<Buffer>,
buffer_path: Option<PathBuf>,
cx: &AsyncAppContext, cx: &AsyncAppContext,
) -> anyhow::Result<Diff> { ) -> anyhow::Result<Diff> {
let params = buffer.read_with(cx, |buffer, cx| { let params = buffer.read_with(cx, |buffer, cx| {
let buffer_file = buffer.file();
let buffer_language = buffer.language(); let buffer_language = buffer.language();
let path = buffer_file
.map(|file| file.full_path(cx))
.map(|path| path.to_path_buf());
let parsers_with_plugins = buffer_language let parsers_with_plugins = buffer_language
.into_iter() .into_iter()
.flat_map(|language| { .flat_map(|language| {
@ -242,7 +239,6 @@ impl Prettier {
log::warn!("Found multiple parsers with plugins {parsers_with_plugins:?}, will select only one: {selected_parser_with_plugins:?}"); log::warn!("Found multiple parsers with plugins {parsers_with_plugins:?}, will select only one: {selected_parser_with_plugins:?}");
} }
// TODO kb move the entire prettier server js file into *.mjs one instead?
let plugin_name_into_path = |plugin_name: &str| self.prettier_dir.join("node_modules").join(plugin_name).join("dist").join("index.mjs"); let plugin_name_into_path = |plugin_name: &str| self.prettier_dir.join("node_modules").join(plugin_name).join("dist").join("index.mjs");
let (parser, plugins) = match selected_parser_with_plugins { let (parser, plugins) = match selected_parser_with_plugins {
Some((parser, plugins)) => { Some((parser, plugins)) => {
@ -267,7 +263,7 @@ impl Prettier {
}; };
let prettier_options = if self.default { let prettier_options = if self.default {
let language_settings = language_settings(buffer_language, buffer_file, cx); let language_settings = language_settings(buffer_language, buffer.file(), cx);
let mut options = language_settings.prettier.clone(); let mut options = language_settings.prettier.clone();
if !options.contains_key("tabWidth") { if !options.contains_key("tabWidth") {
options.insert( options.insert(
@ -295,8 +291,7 @@ impl Prettier {
options: FormatOptions { options: FormatOptions {
parser, parser,
plugins, plugins,
// TODO kb is not absolute now path: buffer_path,
path,
prettier_options, prettier_options,
}, },
} }

View file

@ -150,15 +150,19 @@ async function handleMessage(message, prettier) {
throw new Error(`Message params.options is undefined: ${JSON.stringify(message)}`); throw new Error(`Message params.options is undefined: ${JSON.stringify(message)}`);
} }
let resolvedConfig = {};
if (params.options.filepath !== undefined) {
resolvedConfig = await prettier.prettier.resolveConfig(params.options.filepath) || {};
}
const options = { const options = {
...(params.options.prettierOptions || prettier.config), ...(params.options.prettierOptions || prettier.config),
...resolvedConfig,
parser: params.options.parser, parser: params.options.parser,
plugins: params.options.plugins, plugins: params.options.plugins,
path: params.options.path path: params.options.filepath
}; };
// TODO kb always resolve prettier config for each file. process.stderr.write(`Resolved config: ${JSON.stringify(resolvedConfig)}, will format file '${params.options.filepath || ''}' with options: ${JSON.stringify(options)}\n`);
// need to understand if default prettier can be affected by other configs in the project
// (restart default prettiers on config changes too then)
const formattedText = await prettier.prettier.format(params.text, options); const formattedText = await prettier.prettier.format(params.text, options);
sendResponse({ id, result: { text: formattedText } }); sendResponse({ id, result: { text: formattedText } });
} else if (method === 'prettier/clear_cache') { } else if (method === 'prettier/clear_cache') {

View file

@ -4130,9 +4130,12 @@ impl Project {
.await .await
{ {
Ok(prettier) => { Ok(prettier) => {
let buffer_path = buffer.read_with(&cx, |buffer, cx| {
File::from_dyn(buffer.file()).map(|file| file.abs_path(cx))
});
format_operation = Some(FormatOperation::Prettier( format_operation = Some(FormatOperation::Prettier(
prettier prettier
.format(buffer, &cx) .format(buffer, buffer_path, &cx)
.await .await
.context("formatting via prettier")?, .context("formatting via prettier")?,
)); ));
@ -4168,9 +4171,12 @@ impl Project {
.await .await
{ {
Ok(prettier) => { Ok(prettier) => {
let buffer_path = buffer.read_with(&cx, |buffer, cx| {
File::from_dyn(buffer.file()).map(|file| file.abs_path(cx))
});
format_operation = Some(FormatOperation::Prettier( format_operation = Some(FormatOperation::Prettier(
prettier prettier
.format(buffer, &cx) .format(buffer, buffer_path, &cx)
.await .await
.context("formatting via prettier")?, .context("formatting via prettier")?,
)); ));
@ -8309,7 +8315,6 @@ impl Project {
let task = cx.spawn(|this, mut cx| async move { let task = cx.spawn(|this, mut cx| async move {
let fs = this.update(&mut cx, |project, _| Arc::clone(&project.fs)); let fs = this.update(&mut cx, |project, _| Arc::clone(&project.fs));
// TODO kb can we have a cache for this instead?
let prettier_dir = match cx let prettier_dir = match cx
.background() .background()
.spawn(Prettier::locate( .spawn(Prettier::locate(