export function getExpandOptions()

in src/emmetHelper.ts [599:728]


export function getExpandOptions(syntax: string, emmetConfig?: VSCodeEmmetConfig, filter?: string): ExpandOptionsConfig {
	emmetConfig = emmetConfig ?? {};
	emmetConfig['preferences'] = emmetConfig['preferences'] ?? {};

	const preferences: any = emmetConfig['preferences'];
	const stylesheetSyntax = isStyleSheet(syntax) ? syntax : 'css';

	// Fetch Profile
	const profile = getProfile(syntax, emmetConfig['syntaxProfiles'] ?? {});
	const filtersFromProfile: string[] = (profile && profile['filters']) ? profile['filters'].split(',') : [];
	const trimmedFilters = filtersFromProfile.map(filterFromProfile => filterFromProfile.trim());
	const bemEnabled = (filter && filter.split(',').some(x => x.trim() === 'bem')) || trimmedFilters.includes('bem');
	const commentEnabled = (filter && filter.split(',').some(x => x.trim() === 'c')) || trimmedFilters.includes('c');

	// Fetch formatters
	const formatters = getFormatters(syntax, emmetConfig['preferences']);
	const unitAliases: SnippetsMap = (formatters?.stylesheet && formatters.stylesheet['unitAliases']) || {};

	// These options are the default values provided by vscode for
	// extension preferences
	const defaultVSCodeOptions: Partial<Options> = {
		// inlineElements: string[],
		// 'output.indent': string,
		// 'output.baseIndent': string,
		// 'output.newline': string,
		// 'output.tagCase': profile['tagCase'],
		// 'output.attributeCase': profile['attributeCase'],
		// 'output.attributeQuotes': profile['attributeQuotes'],
		// 'output.format': profile['format'] ?? true,
		// 'output.formatLeafNode': boolean,
		'output.formatSkip': ['html'],
		'output.formatForce': ['body'],
		'output.inlineBreak': 0,
		'output.compactBoolean': false,
		// 'output.booleanAttributes': string[],
		'output.reverseAttributes': false,
		// 'output.selfClosingStyle': profile['selfClosingStyle'],
		'output.field': emmetSnippetField,
		// 'output.text': TextOutput,
		'markup.href': true,
		'comment.enabled': false,
		'comment.trigger': ['id', 'class'],
		'comment.before': '',
		'comment.after': '\n<!-- /[#ID][.CLASS] -->',
		'bem.enabled': false,
		'bem.element': '__',
		'bem.modifier': '_',
		'jsx.enabled': syntax === 'jsx',
		// 'stylesheet.keywords': string[],
		// 'stylesheet.unitless': string[],
		'stylesheet.shortHex': true,
		'stylesheet.between': syntax === 'stylus' ? ' ' : ': ',
		'stylesheet.after': (syntax === 'sass' || syntax === 'stylus') ? '' : ';',
		'stylesheet.intUnit': 'px',
		'stylesheet.floatUnit': 'em',
		'stylesheet.unitAliases': { e: 'em', p: '%', x: 'ex', r: 'rem' },
		// 'stylesheet.json': boolean,
		// 'stylesheet.jsonDoubleQuotes': boolean,
		'stylesheet.fuzzySearchMinScore': 0.3,
	};

	// These options come from user prefs in the vscode repo
	const userPreferenceOptions: Partial<Options> = {
		// inlineElements: string[],
		// 'output.indent': string,
		// 'output.baseIndent': string,
		// 'output.newline': string,
		'output.tagCase': profile['tagCase'],
		'output.attributeCase': profile['attributeCase'],
		'output.attributeQuotes': profile['attributeQuotes'],
		'output.format': profile['format'] ?? true,
		// 'output.formatLeafNode': boolean,
		'output.formatSkip': preferences['format.noIndentTags'],
		'output.formatForce': preferences['format.forceIndentationForTags'],
		'output.inlineBreak': profile['inlineBreak'] ?? preferences['output.inlineBreak'],
		'output.compactBoolean': profile['compactBooleanAttributes'] ?? preferences['profile.allowCompactBoolean'],
		// 'output.booleanAttributes': string[],
		'output.reverseAttributes': preferences['output.reverseAttributes'],
		'output.selfClosingStyle': profile['selfClosingStyle'] ?? preferences['output.selfClosingStyle'] ?? getClosingStyle(syntax),
		'output.field': emmetSnippetField,
		// 'output.text': TextOutput,
		// 'markup.href': boolean,
		'comment.enabled': commentEnabled,
		'comment.trigger': preferences['filter.commentTrigger'],
		'comment.before': preferences['filter.commentBefore'],
		'comment.after': preferences['filter.commentAfter'],
		'bem.enabled': bemEnabled,
		'bem.element': preferences['bem.elementSeparator'] ?? '__',
		'bem.modifier': preferences['bem.modifierSeparator'] ?? '_',
		'jsx.enabled': syntax === 'jsx',
		// 'stylesheet.keywords': string[],
		// 'stylesheet.unitless': string[],
		'stylesheet.shortHex': preferences['css.color.short'],
		'stylesheet.between': preferences[`${stylesheetSyntax}.valueSeparator`],
		'stylesheet.after': preferences[`${stylesheetSyntax}.propertyEnd`],
		'stylesheet.intUnit': preferences['css.intUnit'],
		'stylesheet.floatUnit': preferences['css.floatUnit'],
		'stylesheet.unitAliases': unitAliases,
		// 'stylesheet.json': boolean,
		// 'stylesheet.jsonDoubleQuotes': boolean,
		'stylesheet.fuzzySearchMinScore': preferences['css.fuzzySearchMinScore'],
	}

	const combinedOptions: any = {};
	[...Object.keys(defaultVSCodeOptions), ...Object.keys(userPreferenceOptions)].forEach(key => {
		const castKey = key as keyof Options;
		combinedOptions[castKey] = userPreferenceOptions[castKey] ?? defaultVSCodeOptions[castKey];
	});
	const mergedAliases = { ...defaultVSCodeOptions['stylesheet.unitAliases'], ...userPreferenceOptions['stylesheet.unitAliases'] };
	combinedOptions['stylesheet.unitAliases'] = mergedAliases;

	const type = getSyntaxType(syntax);
	const variables = getVariables(emmetConfig['variables']);
	const baseSyntax = getDefaultSyntax(syntax);
	const snippets = (type === 'stylesheet') ?
		(customSnippetsRegistry[syntax] ?? customSnippetsRegistry[baseSyntax]) :
		customSnippetsRegistry[syntax];

	return {
		type,
		options: combinedOptions,
		variables,
		snippets,
		syntax,
		// context: null,
		text: undefined,
		maxRepeat: 1000,
		// cache: null
	};
}