From fd6fdfc3a2dc4f2766d385629d7ec91f1726b59c Mon Sep 17 00:00:00 2001 From: Esa-Matti Suuronen Date: Sun, 17 Mar 2019 16:27:10 +0200 Subject: [PATCH] Add plugin support Closes #395 Closes #612 --- README.md | 4 ++++ src/PrettierEditProvider.ts | 10 +++++++- src/utils.ts | 47 +++++++++++++++++++++++++++++++++++-- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index daeeb4bde..14cbf14f9 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,10 @@ You can turn on format-on-save on a per-language basis by scoping the setting: `eslint`, `tslint`, and all peer dependencies required by your specific configuration must be installed locally. Global installations will not be recognized. +### Prettier Plugins + +Prettier plugins are supported when using a local Prettier installation. Just install the plugin you need locally to your project, restart vscode and you are good to go. + ## Settings ### Prettier's Settings diff --git a/src/PrettierEditProvider.ts b/src/PrettierEditProvider.ts index a4e22920d..618bb5b54 100644 --- a/src/PrettierEditProvider.ts +++ b/src/PrettierEditProvider.ts @@ -6,10 +6,11 @@ import { FormattingOptions, CancellationToken, TextEdit, + window, } from 'vscode'; import { safeExecution, addToOutput, setUsedModule } from './errorHandler'; -import { getParsersFromLanguageId, getConfig } from './utils'; +import { getParsersFromLanguageId, getConfig, supportsLanguage } from './utils'; import { requireLocalPkg } from './requirePkg'; import { @@ -103,6 +104,13 @@ async function format( return text; } + if (!supportsLanguage(languageId, localPrettier)) { + window.showErrorMessage( + `Prettier does not support "${languageId}". Maybe a plugin is missing from the workspace?` + ); + return text; + } + const dynamicParsers = getParsersFromLanguageId( languageId, localPrettier, diff --git a/src/utils.ts b/src/utils.ts index fc7b11d71..b843cd203 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -6,6 +6,7 @@ import { PrettierSupportInfo, ParserOption, } from './types.d'; +import { requireLocalPkg } from './requirePkg'; const bundledPrettier = require('prettier') as Prettier; @@ -35,8 +36,35 @@ export function getParsersFromLanguageId( } export function allEnabledLanguages(): string[] { - return getSupportLanguages().reduce( - (ids, language) => [...ids, ...(language.vscodeLanguageIds || [])], + if (!workspace.workspaceFolders) { + return getSupportLanguages().reduce( + (ids, language) => [...ids, ...(language.vscodeLanguageIds || [])], + [] as string[] + ); + } + + return workspace.workspaceFolders.reduce( + (ids, workspaceFolder) => { + const workspacePrettier = requireLocalPkg( + workspaceFolder.uri.fsPath, + 'prettier' + ) as Prettier; + + const newLanguages: string[] = []; + + for (const language of getSupportLanguages(workspacePrettier)) { + if (!language.vscodeLanguageIds) { + continue; + } + for (const id of language.vscodeLanguageIds) { + if (!ids.includes(id)) { + newLanguages.push(id); + } + } + } + + return [...ids, ...newLanguages]; + }, [] as string[] ); } @@ -59,3 +87,18 @@ export function getGroup(group: string): PrettierSupportInfo['languages'] { function getSupportLanguages(prettierInstance: Prettier = bundledPrettier) { return prettierInstance.getSupportInfo(prettierInstance.version).languages; } + +export function supportsLanguage( + vscodeLanguageId: string, + prettierInstance: Prettier +) { + return prettierInstance + .getSupportInfo(prettierInstance.version) + .languages.some(language => { + if (!language.vscodeLanguageIds) { + return false; + } + + return language.vscodeLanguageIds.includes(vscodeLanguageId); + }); +}