2 Object.defineProperty(exports, "__esModule", { value: true });
3 const tslib_1 = require("tslib");
4 const coc_nvim_1 = require("coc.nvim");
5 const path_1 = tslib_1.__importDefault(require("path"));
6 const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol");
7 const errorHandler_1 = require("./errorHandler");
8 const requirePkg_1 = require("./requirePkg");
9 const utils_1 = require("./utils");
11 * HOLD style parsers (for stylelint integration)
13 const STYLE_PARSERS = ['postcss', 'css', 'less', 'scss'];
15 * Resolves the prettierconfig for the given file.
17 * @param filePath file's path
19 function resolveConfig(filePath, options) {
20 return tslib_1.__awaiter(this, void 0, void 0, function* () {
22 const localPrettier = (yield requirePkg_1.requireLocalPkg(path_1.default.dirname(filePath), 'prettier', { silent: true, ignoreBundled: true }));
23 let prettierInstance = localPrettier;
24 if (!prettierInstance && !options.onlyUseLocalVersion) {
25 prettierInstance = require('prettier');
27 const config = yield prettierInstance.resolveConfig(filePath, options);
31 return { config: null, error };
36 * Define which config should be used.
37 * If a prettierconfig exists, it returns itself.
38 * It merges prettierconfig into vscode's config (editorconfig).
43 * @param hasPrettierConfig a prettierconfig exists
44 * @param additionalConfig config we really want to see in. (range)
45 * @param prettierConfig prettier's file config
46 * @param vscodeConfig our config
48 function mergeConfig(hasPrettierConfig, additionalConfig, prettierConfig, vscodeConfig) {
49 return hasPrettierConfig
50 ? Object.assign({ parser: vscodeConfig.parser }, // always merge our inferred parser in
51 prettierConfig, additionalConfig)
52 : Object.assign(vscodeConfig, prettierConfig, additionalConfig);
55 * Format the given text with user's configuration.
56 * @param text Text to format
57 * @param path formatting file's path
58 * @returns {string} formatted text
60 function format(text, { languageId, uri }, customOptions) {
61 return tslib_1.__awaiter(this, void 0, void 0, function* () {
62 let u = coc_nvim_1.Uri.parse(uri);
63 const isUntitled = u.scheme == 'untitled';
64 const fileName = u.fsPath;
65 const vscodeConfig = utils_1.getConfig(u);
66 const localOnly = vscodeConfig.onlyUseLocalVersion;
67 const resolvedPrettier = yield utils_1.getPrettierInstance();
68 if (!resolvedPrettier) {
69 errorHandler_1.addToOutput(`Prettier module not found, prettier.onlyUseLocalVersion: ${vscodeConfig.onlyUseLocalVersion}`, 'Error');
71 let supportedLanguages = utils_1.allLanguages(resolvedPrettier);
72 if (supportedLanguages.indexOf(languageId) == -1) {
73 coc_nvim_1.workspace.showMessage(`${languageId} not supported by prettier`, 'error');
76 const dynamicParsers = utils_1.getParsersFromLanguageId(languageId, resolvedPrettier, isUntitled ? undefined : fileName);
77 let useBundled = false;
79 if (!dynamicParsers.length) {
80 const bundledParsers = utils_1.getParsersFromLanguageId(languageId, require('prettier'), isUntitled ? undefined : fileName);
81 parser = bundledParsers[0] || 'babylon';
84 else if (dynamicParsers.includes(vscodeConfig.parser)) {
85 // handle deprecated parser option (parser: "flow")
86 parser = vscodeConfig.parser;
89 parser = dynamicParsers[0];
91 const doesParserSupportEslint = [
97 ].includes(languageId);
98 const { config: fileOptions, error } = yield resolveConfig(fileName, {
100 onlyUseLocalVersion: localOnly,
101 requireConfig: vscodeConfig.requireConfig,
103 const hasConfig = fileOptions != null;
104 if (!hasConfig && vscodeConfig.requireConfig) {
108 errorHandler_1.addToOutput(`Failed to resolve config for ${fileName}. Falling back to the default config settings.`, 'Error');
110 const prettierOptions = mergeConfig(hasConfig, customOptions, fileOptions || {}, {
111 printWidth: vscodeConfig.printWidth,
112 tabWidth: vscodeConfig.tabWidth,
113 singleQuote: vscodeConfig.singleQuote,
114 jsxSingleQuote: vscodeConfig.jsxSingleQuote,
115 trailingComma: vscodeConfig.trailingComma,
116 bracketSpacing: vscodeConfig.bracketSpacing,
117 jsxBracketSameLine: vscodeConfig.jsxBracketSameLine,
119 semi: vscodeConfig.semi,
120 useTabs: vscodeConfig.useTabs,
121 proseWrap: vscodeConfig.proseWrap,
122 arrowParens: vscodeConfig.arrowParens,
124 if (vscodeConfig.tslintIntegration && parser === 'typescript') {
125 return errorHandler_1.safeExecution(() => {
126 const prettierTslint = requirePkg_1.requireLocalPkg(u.fsPath, 'prettier-tslint')
128 // setUsedModule('prettier-tslint', 'Unknown', true)
129 return prettierTslint({
132 fallbackPrettierOptions: prettierOptions,
136 if (vscodeConfig.eslintIntegration && doesParserSupportEslint) {
137 return errorHandler_1.safeExecution(() => {
138 const prettierEslint = requirePkg_1.requireLocalPkg(u.fsPath, 'prettier-eslint');
139 // setUsedModule('prettier-eslint', 'Unknown', true)
140 return prettierEslint({
143 fallbackPrettierOptions: prettierOptions,
147 if (vscodeConfig.stylelintIntegration && STYLE_PARSERS.includes(parser)) {
148 const prettierStylelint = requirePkg_1.requireLocalPkg(u.fsPath, 'prettier-stylelint');
149 return errorHandler_1.safeExecution(prettierStylelint.format({
155 if (!doesParserSupportEslint && useBundled) {
156 let bundledPrettier = require('prettier');
157 return errorHandler_1.safeExecution(() => {
158 const warningMessage = `prettier@${bundledPrettier.version} doesn't support ${languageId}. ` +
159 `Falling back to bundled prettier@${bundledPrettier.version}.`;
160 errorHandler_1.addToOutput(warningMessage, 'Warning');
161 // setUsedModule('prettier', bundledPrettier.version, true)
162 return bundledPrettier.format(text, prettierOptions);
165 // setUsedModule('prettier', localPrettier.version, false)
166 return errorHandler_1.safeExecution(() => resolvedPrettier.format(text, prettierOptions), text, fileName);
169 exports.format = format;
170 function fullDocumentRange(document) {
171 const lastLineId = document.lineCount - 1;
172 let doc = coc_nvim_1.workspace.getDocument(document.uri);
173 return vscode_languageserver_protocol_1.Range.create({ character: 0, line: 0 }, { character: doc.getline(lastLineId).length, line: lastLineId });
175 exports.fullDocumentRange = fullDocumentRange;
176 class PrettierEditProvider {
177 constructor(_fileIsIgnored) {
178 this._fileIsIgnored = _fileIsIgnored;
180 provideDocumentRangeFormattingEdits(document, range, _options, _token) {
181 return this._provideEdits(document, {
182 rangeStart: document.offsetAt(range.start),
183 rangeEnd: document.offsetAt(range.end),
186 provideDocumentFormattingEdits(document, _options, _token) {
187 return this._provideEdits(document, {});
189 _provideEdits(document, options) {
190 return tslib_1.__awaiter(this, void 0, void 0, function* () {
191 let fileName = coc_nvim_1.Uri.parse(document.uri).fsPath;
192 if (!document.uri.startsWith('untitled') && this._fileIsIgnored(fileName)) {
193 return Promise.resolve([]);
195 const code = yield format(document.getText(), document, options);
196 const edits = [yield vscode_languageserver_protocol_1.TextEdit.replace(fullDocumentRange(document), code)];
197 const { disableSuccessMessage } = utils_1.getConfig();
198 if (edits && edits.length && !disableSuccessMessage) {
199 coc_nvim_1.workspace.showMessage('Formatted by prettier');
201 errorHandler_1.addToOutput(`Formatted file: ${document.uri}`);
202 errorHandler_1.addToOutput(`Prettier format edits: ${JSON.stringify(edits, null, 2)}`);
207 exports.default = PrettierEditProvider;
208 //# sourceMappingURL=PrettierEditProvider.js.map