From b2b3611cf478d46b769fa582e4f5d89c10e4a886 Mon Sep 17 00:00:00 2001 From: Princesseuh <3019731+Princesseuh@users.noreply.github.com> Date: Wed, 28 Feb 2024 18:31:36 +0100 Subject: [PATCH 1/5] feat(prettier): Allow a Prettier instance to be optional --- .gitignore | 1 + packages/prettier/index.ts | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ddf23eed..5b3437e9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ node_modules *.js *.map *.tgz +.DS_Store diff --git a/packages/prettier/index.ts b/packages/prettier/index.ts index d7852e8a..2371c605 100644 --- a/packages/prettier/index.ts +++ b/packages/prettier/index.ts @@ -44,6 +44,10 @@ export function create( */ prettier?: typeof import('prettier') | undefined; getPrettier?: (serviceEnv: ServiceEnvironment) => typeof import('prettier') | undefined, + /** + * If true, the plugin will not throw an error if it can't load Prettier either through the `prettier`, or `getPrettier` properties or through a normal `import('prettier')`. + */ + allowImportError?: boolean; } = {}, getPrettierConfig = async (filePath: string, prettier: typeof import('prettier'), config?: ResolveConfigOptions) => { return await prettier.resolveConfig(filePath, config) ?? {}; @@ -59,12 +63,13 @@ export function create( ?? options.getPrettier?.(context.env) ?? require('prettier'); } catch (e) { - throw new Error("Could not load Prettier: " + e); + if (!options.allowImportError) throw new Error("Could not load Prettier: " + e); } const languages = options.languages ?? ['html', 'css', 'scss', 'typescript', 'javascript']; return { async provideDocumentFormattingEdits(document, _, formatOptions) { + if (!prettier) return; if (!languages.includes(document.languageId)) { return; } From c830c3a9e6d3031d355444586b8710a7785c7611 Mon Sep 17 00:00:00 2001 From: Princesseuh <3019731+Princesseuh@users.noreply.github.com> Date: Wed, 28 Feb 2024 18:34:36 +0100 Subject: [PATCH 2/5] fix: register an empty plugin instedad --- packages/prettier/index.ts | 122 +++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 60 deletions(-) diff --git a/packages/prettier/index.ts b/packages/prettier/index.ts index 2371c605..36ea0df1 100644 --- a/packages/prettier/index.ts +++ b/packages/prettier/index.ts @@ -56,83 +56,85 @@ export function create( return { name: 'prettier', create(context): ServicePluginInstance { + const languages = options.languages ?? ['html', 'css', 'scss', 'typescript', 'javascript']; let prettier: typeof import('prettier'); try { prettier = options.prettier ?? options.getPrettier?.(context.env) ?? require('prettier'); - } catch (e) { - if (!options.allowImportError) throw new Error("Could not load Prettier: " + e); - } - const languages = options.languages ?? ['html', 'css', 'scss', 'typescript', 'javascript']; - return { - async provideDocumentFormattingEdits(document, _, formatOptions) { - if (!prettier) return; - if (!languages.includes(document.languageId)) { - return; - } + return { + async provideDocumentFormattingEdits(document, _, formatOptions) { + if (!prettier) return; + if (!languages.includes(document.languageId)) { + return; + } - const filePath = URI.parse(document.uri).fsPath; - const fileInfo = await prettier.getFileInfo(filePath, { ignorePath: '.prettierignore', resolveConfig: false }); + const filePath = URI.parse(document.uri).fsPath; + const fileInfo = await prettier.getFileInfo(filePath, { ignorePath: '.prettierignore', resolveConfig: false }); - if (fileInfo.ignored) { - return; - } + if (fileInfo.ignored) { + return; + } - const filePrettierOptions = await getPrettierConfig( - filePath, - prettier, - options.resolveConfigOptions - ); + const filePrettierOptions = await getPrettierConfig( + filePath, + prettier, + options.resolveConfigOptions + ); - const editorPrettierOptions = await context.env.getConfiguration?.('prettier', document.uri); - const ideFormattingOptions = - formatOptions !== undefined && options.useIdeOptionsFallback // We need to check for options existing here because some editors might not have it - ? { - tabWidth: formatOptions.tabSize, - useTabs: !formatOptions.insertSpaces, - } - : {}; + const editorPrettierOptions = await context.env.getConfiguration?.('prettier', document.uri); + const ideFormattingOptions = + formatOptions !== undefined && options.useIdeOptionsFallback // We need to check for options existing here because some editors might not have it + ? { + tabWidth: formatOptions.tabSize, + useTabs: !formatOptions.insertSpaces, + } + : {}; - // Return a config with the following cascade: - // - Prettier config file should always win if it exists, if it doesn't: - // - Prettier config from the VS Code extension is used, if it doesn't exist: - // - Use the editor's basic configuration settings - const prettierOptions = returnObjectIfHasKeys(filePrettierOptions) || returnObjectIfHasKeys(editorPrettierOptions) || ideFormattingOptions; + // Return a config with the following cascade: + // - Prettier config file should always win if it exists, if it doesn't: + // - Prettier config from the VS Code extension is used, if it doesn't exist: + // - Use the editor's basic configuration settings + const prettierOptions = returnObjectIfHasKeys(filePrettierOptions) || returnObjectIfHasKeys(editorPrettierOptions) || ideFormattingOptions; - const currentPrettierConfig: Options = { - ...(options.additionalOptions - ? await options.additionalOptions(prettierOptions) - : prettierOptions), - filepath: filePath, - }; + const currentPrettierConfig: Options = { + ...(options.additionalOptions + ? await options.additionalOptions(prettierOptions) + : prettierOptions), + filepath: filePath, + }; - if (!options.ignoreIdeOptions) { - currentPrettierConfig.useTabs = !formatOptions.insertSpaces; - currentPrettierConfig.tabWidth = formatOptions.tabSize; - } + if (!options.ignoreIdeOptions) { + currentPrettierConfig.useTabs = !formatOptions.insertSpaces; + currentPrettierConfig.tabWidth = formatOptions.tabSize; + } - const fullText = document.getText(); - let oldText = fullText; + const fullText = document.getText(); + let oldText = fullText; - const isHTML = document.languageId === "html"; - if (isHTML && options.html?.breakContentsFromTags) { - oldText = oldText - .replace(/(<[a-z][^>]*>)([^ \n])/gi, "$1 $2") - .replace(/([^ \n])(<\/[a-z][a-z0-9\t\n\r -]*>)/gi, "$1 $2"); - } + const isHTML = document.languageId === "html"; + if (isHTML && options.html?.breakContentsFromTags) { + oldText = oldText + .replace(/(<[a-z][^>]*>)([^ \n])/gi, "$1 $2") + .replace(/([^ \n])(<\/[a-z][a-z0-9\t\n\r -]*>)/gi, "$1 $2"); + } + + return [{ + newText: await prettier.format(oldText, currentPrettierConfig), + range: { + start: document.positionAt(0), + end: document.positionAt(fullText.length), + }, + }]; + }, + }; + } catch (e) { + if (!options.allowImportError) throw new Error("Could not load Prettier: " + e); + } - return [{ - newText: await prettier.format(oldText, currentPrettierConfig), - range: { - start: document.positionAt(0), - end: document.positionAt(fullText.length), - }, - }]; - }, - }; + return {}; }, }; } From e4c5a531b2a49e1cf12aa66f6a503223dd60f6b2 Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Tue, 5 Mar 2024 03:08:50 +0800 Subject: [PATCH 3/5] Apply @remcohaszing suggest --- packages/prettier/index.ts | 136 ++++++++++++++++++++----------------- 1 file changed, 72 insertions(+), 64 deletions(-) diff --git a/packages/prettier/index.ts b/packages/prettier/index.ts index 36ea0df1..933a036d 100644 --- a/packages/prettier/index.ts +++ b/packages/prettier/index.ts @@ -58,83 +58,91 @@ export function create( create(context): ServicePluginInstance { const languages = options.languages ?? ['html', 'css', 'scss', 'typescript', 'javascript']; - let prettier: typeof import('prettier'); + let prettier = options.prettier; try { - prettier = options.prettier - ?? options.getPrettier?.(context.env) - ?? require('prettier'); + if (!prettier) { + if (options.getPrettier) { + prettier = options.getPrettier(context.env); + } else { + prettier = require('prettier'); + } + } + } catch (error) { + if (!options.allowImportError) { + throw new Error("Could not load Prettier: "); + }; + } - return { - async provideDocumentFormattingEdits(document, _, formatOptions) { - if (!prettier) return; - if (!languages.includes(document.languageId)) { - return; - } + if (!prettier) { + return {}; + } - const filePath = URI.parse(document.uri).fsPath; - const fileInfo = await prettier.getFileInfo(filePath, { ignorePath: '.prettierignore', resolveConfig: false }); + return { + async provideDocumentFormattingEdits(document, _, formatOptions) { + if (!prettier) return; + if (!languages.includes(document.languageId)) { + return; + } - if (fileInfo.ignored) { - return; - } + const filePath = URI.parse(document.uri).fsPath; + const fileInfo = await prettier.getFileInfo(filePath, { ignorePath: '.prettierignore', resolveConfig: false }); - const filePrettierOptions = await getPrettierConfig( - filePath, - prettier, - options.resolveConfigOptions - ); + if (fileInfo.ignored) { + return; + } - const editorPrettierOptions = await context.env.getConfiguration?.('prettier', document.uri); - const ideFormattingOptions = - formatOptions !== undefined && options.useIdeOptionsFallback // We need to check for options existing here because some editors might not have it - ? { - tabWidth: formatOptions.tabSize, - useTabs: !formatOptions.insertSpaces, - } - : {}; + const filePrettierOptions = await getPrettierConfig( + filePath, + prettier, + options.resolveConfigOptions + ); - // Return a config with the following cascade: - // - Prettier config file should always win if it exists, if it doesn't: - // - Prettier config from the VS Code extension is used, if it doesn't exist: - // - Use the editor's basic configuration settings - const prettierOptions = returnObjectIfHasKeys(filePrettierOptions) || returnObjectIfHasKeys(editorPrettierOptions) || ideFormattingOptions; + const editorPrettierOptions = await context.env.getConfiguration?.('prettier', document.uri); + const ideFormattingOptions = + formatOptions !== undefined && options.useIdeOptionsFallback // We need to check for options existing here because some editors might not have it + ? { + tabWidth: formatOptions.tabSize, + useTabs: !formatOptions.insertSpaces, + } + : {}; - const currentPrettierConfig: Options = { - ...(options.additionalOptions - ? await options.additionalOptions(prettierOptions) - : prettierOptions), - filepath: filePath, - }; + // Return a config with the following cascade: + // - Prettier config file should always win if it exists, if it doesn't: + // - Prettier config from the VS Code extension is used, if it doesn't exist: + // - Use the editor's basic configuration settings + const prettierOptions = returnObjectIfHasKeys(filePrettierOptions) || returnObjectIfHasKeys(editorPrettierOptions) || ideFormattingOptions; - if (!options.ignoreIdeOptions) { - currentPrettierConfig.useTabs = !formatOptions.insertSpaces; - currentPrettierConfig.tabWidth = formatOptions.tabSize; - } + const currentPrettierConfig: Options = { + ...(options.additionalOptions + ? await options.additionalOptions(prettierOptions) + : prettierOptions), + filepath: filePath, + }; - const fullText = document.getText(); - let oldText = fullText; + if (!options.ignoreIdeOptions) { + currentPrettierConfig.useTabs = !formatOptions.insertSpaces; + currentPrettierConfig.tabWidth = formatOptions.tabSize; + } - const isHTML = document.languageId === "html"; - if (isHTML && options.html?.breakContentsFromTags) { - oldText = oldText - .replace(/(<[a-z][^>]*>)([^ \n])/gi, "$1 $2") - .replace(/([^ \n])(<\/[a-z][a-z0-9\t\n\r -]*>)/gi, "$1 $2"); - } + const fullText = document.getText(); + let oldText = fullText; - return [{ - newText: await prettier.format(oldText, currentPrettierConfig), - range: { - start: document.positionAt(0), - end: document.positionAt(fullText.length), - }, - }]; - }, - }; - } catch (e) { - if (!options.allowImportError) throw new Error("Could not load Prettier: " + e); - } + const isHTML = document.languageId === "html"; + if (isHTML && options.html?.breakContentsFromTags) { + oldText = oldText + .replace(/(<[a-z][^>]*>)([^ \n])/gi, "$1 $2") + .replace(/([^ \n])(<\/[a-z][a-z0-9\t\n\r -]*>)/gi, "$1 $2"); + } - return {}; + return [{ + newText: await prettier.format(oldText, currentPrettierConfig), + range: { + start: document.positionAt(0), + end: document.positionAt(fullText.length), + }, + }]; + }, + }; }, }; } From 761f4820a79011a45932f2da9f665097bd598e04 Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Tue, 5 Mar 2024 03:10:43 +0800 Subject: [PATCH 4/5] Update .gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5b3437e9..ddf23eed 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,3 @@ node_modules *.js *.map *.tgz -.DS_Store From 3b1aa2b59bd47eed91d4d52d2dd8fee6772e41e4 Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Tue, 5 Mar 2024 03:11:56 +0800 Subject: [PATCH 5/5] Update index.ts --- packages/prettier/index.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/prettier/index.ts b/packages/prettier/index.ts index 933a036d..d69da09d 100644 --- a/packages/prettier/index.ts +++ b/packages/prettier/index.ts @@ -58,13 +58,13 @@ export function create( create(context): ServicePluginInstance { const languages = options.languages ?? ['html', 'css', 'scss', 'typescript', 'javascript']; - let prettier = options.prettier; + let _prettier = options.prettier; try { - if (!prettier) { + if (!_prettier) { if (options.getPrettier) { - prettier = options.getPrettier(context.env); + _prettier = options.getPrettier(context.env); } else { - prettier = require('prettier'); + _prettier = require('prettier'); } } } catch (error) { @@ -73,13 +73,14 @@ export function create( }; } - if (!prettier) { + if (!_prettier) { return {}; } + const prettier = _prettier; + return { async provideDocumentFormattingEdits(document, _, formatOptions) { - if (!prettier) return; if (!languages.includes(document.languageId)) { return; }