prettier-plugin-multiline-arrays
Version:
Prettier plugin to force all arrays to be multiline.
85 lines (84 loc) • 3.85 kB
JavaScript
import { stringify } from '@augment-vir/common';
import { createWrappedMultiTargetProxy } from 'proxy-vir';
import { pluginMarker } from './plugin-marker.js';
import { multilineArrayPrinter } from './printer/multiline-array-printer.js';
import { setOriginalPrinter } from './printer/original-printer.js';
function addMultilinePrinter(options) {
if ('printer' in options) {
setOriginalPrinter(options.printer);
// overwrite the printer with ours
options.printer = multilineArrayPrinter;
}
else {
const astFormat = options.astFormat;
if (!astFormat) {
throw new Error(`Could not find astFormat while adding printer.`);
}
/**
* If the printer hasn't already been assigned in options, rearrange plugins so that ours
* gets chosen.
*/
const plugins = options.plugins ?? [];
const firstMatchedPlugin = plugins.find((plugin) => typeof plugin !== 'string' && !!plugin.printers && !!plugin.printers[astFormat]);
if (!firstMatchedPlugin || typeof firstMatchedPlugin === 'string') {
throw new Error(`Matched invalid first plugin: ${firstMatchedPlugin}`);
}
const matchedPrinter = firstMatchedPlugin.printers?.[astFormat];
if (!matchedPrinter) {
throw new Error(`Printer not found on matched plugin: ${stringify(firstMatchedPlugin)}`);
}
setOriginalPrinter(matchedPrinter);
const thisPluginIndex = plugins.findIndex((plugin) => {
return plugin.pluginMarker === pluginMarker;
});
const thisPlugin = plugins[thisPluginIndex];
if (!thisPlugin) {
throw new Error(`This plugin was not found.`);
}
// remove this plugin from its current location in the array
plugins.splice(thisPluginIndex, 1);
// add this plugin to the beginning of the array so its printer is found first
plugins.splice(0, 0, thisPlugin);
}
}
function findPluginsByParserName(parserName, plugins) {
return plugins.filter((plugin) => {
return (typeof plugin === 'object' &&
plugin.pluginMarker !== pluginMarker &&
!!plugin.parsers?.[parserName]);
});
}
export function wrapParser(originalParser, parserName) {
/** Create a multi-target proxy of parsers so that we don't block other plugins. */
const parserProxy = createWrappedMultiTargetProxy({
initialTarget: originalParser,
});
function multilineArraysPluginPreprocess(text, options) {
const pluginsFromOptions = options.plugins ?? [];
const pluginsWithRelevantParsers = findPluginsByParserName(parserName, pluginsFromOptions);
pluginsWithRelevantParsers.forEach((plugin) => {
const currentParser = plugin.parsers?.[parserName];
if (currentParser &&
plugin?.name?.includes('prettier-plugin-sort-json')) {
parserProxy.proxyModifier.addOverrideTarget(currentParser);
}
});
const pluginsWithPreprocessor = pluginsWithRelevantParsers.filter((plugin) => !!plugin.parsers?.[parserName]?.preprocess);
let processedText = text;
pluginsWithPreprocessor.forEach((pluginWithPreprocessor) => {
const nextText = pluginWithPreprocessor.parsers?.[parserName]?.preprocess?.(processedText, {
...options,
plugins: pluginsFromOptions.filter((plugin) => plugin.pluginMarker !== pluginMarker),
});
if (nextText != undefined) {
processedText = nextText;
}
});
addMultilinePrinter(options);
return processedText;
}
parserProxy.proxyModifier.addOverrideTarget({
preprocess: multilineArraysPluginPreprocess,
});
return parserProxy.proxy;
}