Comprehensive configuration system with syntax-specific options, output formatting, and behavior customization.
Core function for resolving user configuration with defaults and syntax-specific settings.
/**
* Resolves user configuration with built-in defaults and syntax-specific settings
* @param config - User-provided partial configuration
* @returns Complete resolved configuration object
*/
function resolveConfig(config?: UserConfig): Config;
interface Config {
/** Type of abbreviation: 'markup' or 'stylesheet' */
type: SyntaxType;
/** Target syntax (html, css, jsx, pug, etc.) */
syntax: string;
/** Complete configuration options */
options: Options;
/** Variable substitutions */
variables: SnippetsMap;
/** Custom snippet definitions */
snippets: SnippetsMap;
/** Context information for abbreviation resolution */
context?: AbbreviationContext;
/** Text content to wrap with abbreviation */
text?: string | string[];
/** Maximum repetition count for safety */
maxRepeat?: number;
/** Cache object for performance optimization */
cache?: Cache;
/** Warning/error callback */
warn?: (message: string, err?: Error) => void;
}
interface UserConfig {
type?: SyntaxType;
syntax?: string;
options?: Partial<Options>;
variables?: SnippetsMap;
snippets?: SnippetsMap;
context?: AbbreviationContext;
text?: string | string[];
maxRepeat?: number;
cache?: Cache;
warn?: (message: string, err?: Error) => void;
}
type SyntaxType = 'markup' | 'stylesheet';Basic Usage Examples:
import { resolveConfig, expand } from "emmet";
// Use defaults
const defaultConfig = resolveConfig();
console.log(defaultConfig.syntax); // "html"
console.log(defaultConfig.type); // "markup"
// Specify syntax
const cssConfig = resolveConfig({
type: "stylesheet",
syntax: "css"
});
// Custom options
const customConfig = resolveConfig({
syntax: "html",
options: {
"output.indent": " ",
"output.selfClosingStyle": "xhtml"
}
});
expand("input[type=email]", customConfig);
// Result: <input type="email" />interface AbbreviationContext {
/** Context name or scope identifier */
name: string;
/** Optional context attributes */
attributes?: { [name: string]: string | null };
}
interface SnippetsMap {
[name: string]: string;
}
interface Cache {
/** Cached stylesheet snippets for performance */
stylesheetSnippets?: CSSSnippet[];
/** Cached markup snippets for performance */
markupSnippets?: { [name: string]: Abbreviation | null };
}
interface GlobalConfig {
/** Syntax-specific configuration overrides */
[syntax: string]: Partial<BaseConfig>;
}
interface BaseConfig {
type: SyntaxType;
options: Partial<Options>;
variables: SnippetsMap;
snippets: SnippetsMap;
}type FieldOutput = (
index: number,
placeholder: string,
offset: number,
line: number,
column: number
) => string;
type TextOutput = (
text: string,
offset: number,
line: number,
column: number
) => string;
type StringCase = '' | 'lower' | 'upper';The Options interface contains 200+ configuration properties organized by category:
interface Options {
/////////////////////
// Generic options //
/////////////////////
/** List of inline-level elements */
inlineElements: string[];
////////////////////
// Output options //
////////////////////
/** String for one level of indentation */
"output.indent": string;
/** Base indentation to add to all lines */
"output.baseIndent": string;
/** Newline character sequence */
"output.newline": string;
/** Case transformation for tag names */
"output.tagCase": StringCase;
/** Case transformation for attribute names */
"output.attributeCase": StringCase;
/** Quotes style for attribute values */
"output.attributeQuotes": "single" | "double";
/** Format style for self-closing tags */
"output.selfClosingStyle": "html" | "xhtml" | "xml";
/** Whether to add extra newlines for readability */
"output.format": boolean;
/** Whether to skip formatting for specific tags */
"output.formatSkip": string[];
/** Whether to force attribute value quotes */
"output.formatForce": string[];
/** Whether to compact boolean attributes */
"output.compactBoolean": boolean;
/** Whether to reverse attribute order */
"output.reverseAttributes": boolean;
/** Function for field/tabstop output */
"output.field": FieldOutput;
/** Function for text output */
"output.text": TextOutput;
///////////////////
// Markup options //
///////////////////
/** Whether to auto-add href attributes */
"markup.href": boolean;
/** Attributes for specific elements */
"markup.attributes": { [element: string]: string };
/** Value sources for attributes */
"markup.valuePrefix": { [attr: string]: string };
/////////////////
// JSX options //
/////////////////
/** Whether JSX mode is enabled */
"jsx.enabled": boolean;
/////////////////
// BEM options //
/////////////////
/** Whether BEM naming is enabled */
"bem.enabled": boolean;
/** Separator between block and element */
"bem.element": string;
/** Separator for modifiers */
"bem.modifier": string;
//////////////////////
// Stylesheet options //
//////////////////////
/** String between property and value */
"stylesheet.between": string;
/** String after each property */
"stylesheet.after": string;
/** Default unit for integer values */
"stylesheet.intUnit": string;
/** Default unit for float values */
"stylesheet.floatUnit": string;
/** Unit aliases mapping */
"stylesheet.unitAliases": { [alias: string]: string };
/** Properties that shouldn't have units */
"stylesheet.unitless": string[];
/** Available CSS keywords */
"stylesheet.keywords": string[];
/** Minimum score for fuzzy matching */
"stylesheet.fuzzySearchMinScore": number;
/** Use short hex colors when possible */
"stylesheet.shortHex": boolean;
/** Strict property matching mode */
"stylesheet.strictMatch": boolean;
///////////////////////////
// Comment options //
///////////////////////////
/** Whether to add comments */
"comment.enabled": boolean;
/** Comment trigger character */
"comment.trigger": string;
/** Comment format for opening tags */
"comment.before": string;
/** Comment format for closing tags */
"comment.after": string;
}Emmet provides built-in configuration for different syntaxes:
import { resolveConfig } from "emmet";
const htmlConfig = resolveConfig({ syntax: "html" });
// Built-in settings:
// - Self-closing style: HTML
// - Attribute quotes: double
// - Boolean attribute compacting: true
// - Inline elements list: a, abbr, acronym, etc.import { resolveConfig } from "emmet";
const xhtmlConfig = resolveConfig({ syntax: "xhtml" });
// Built-in settings:
// - Self-closing style: XHTML
// - All tags must be properly closed
// - Attribute quotes: requiredimport { resolveConfig } from "emmet";
const jsxConfig = resolveConfig({ syntax: "jsx" });
// Built-in settings:
// - JSX mode enabled
// - className instead of class
// - Self-closing style: XML
// - Expression attribute values: {value}import { resolveConfig } from "emmet";
const cssConfig = resolveConfig({
type: "stylesheet",
syntax: "css"
});
// Built-in settings:
// - Between: ": "
// - After: ";"
// - Int unit: "px"
// - Float unit: "em"import { resolveConfig, expand } from "emmet";
const customFormat = resolveConfig({
syntax: "html",
options: {
"output.indent": "\t",
"output.newline": "\r\n",
"output.tagCase": "upper",
"output.attributeCase": "upper",
"output.attributeQuotes": "single",
"output.selfClosingStyle": "xhtml"
}
});
expand("div.container>input[type=email required]", customFormat);
// Result: <DIV CLASS='container'>\r\n\t<INPUT TYPE='email' REQUIRED='' />\r\n</DIV>import { resolveConfig, expand } from "emmet";
const editorConfig = resolveConfig({
syntax: "html",
options: {
"output.field": (index, placeholder, offset, line, column) => {
return placeholder ? `\${${index}:${placeholder}}` : `\${${index}}`;
},
"output.text": (text, offset, line, column) => {
return `<!--[${line}:${column}]-->${text}`;
}
}
});
expand("div>{Click $}+input[placeholder=${1:Enter text}]", editorConfig);
// Result: <div><!--[0:5]-->Click 1</div><input placeholder="${1:Enter text}">import { resolveConfig, expand } from "emmet";
const bemConfig = resolveConfig({
syntax: "html",
options: {
"bem.enabled": true,
"bem.element": "__",
"bem.modifier": "--"
}
});
expand("div.block>div.-element+div.-element--modifier", bemConfig);
// Result: <div class="block"><div class="block__element"></div><div class="block__element block__element--modifier"></div></div>import { resolveConfig, expand } from "emmet";
const stylusConfig = resolveConfig({
type: "stylesheet",
syntax: "stylus",
options: {
"stylesheet.between": " ",
"stylesheet.after": "",
"stylesheet.intUnit": "rem",
"stylesheet.unitAliases": {
"r": "rem",
"v": "vw"
}
}
});
expand("w100v+h50r+m10", stylusConfig);
// Result: width 100vw\nheight 50rem\nmargin 10remYou can set up global configuration that applies to multiple syntaxes:
import { resolveConfig } from "emmet";
const globalConfig: GlobalConfig = {
// Default settings for all markup syntaxes
markup: {
options: {
"output.indent": " ",
"output.format": true
}
},
// Default settings for all stylesheet syntaxes
stylesheet: {
options: {
"stylesheet.intUnit": "rem",
"stylesheet.shortHex": true
}
},
// HTML-specific overrides
html: {
options: {
"output.selfClosingStyle": "xhtml"
}
},
// JSX-specific overrides
jsx: {
options: {
"jsx.enabled": true,
"markup.attributes": {
"class": "className",
"for": "htmlFor"
}
}
}
};
// Apply global config to specific syntax
const htmlConfig = resolveConfig({
syntax: "html",
options: globalConfig.html?.options
});import { resolveConfig, expand } from "emmet";
// Create cache object for reuse across multiple expansions
const cache: Cache = {};
const config = resolveConfig({
syntax: "html",
cache: cache
});
// First expansion populates cache
expand("div>p*3", config);
// Subsequent expansions reuse cached data
expand("ul>li*5", config);
expand("table>tr*3>td*4", config);
// Cache contains parsed snippets and computed data
console.log(cache.markupSnippets); // Cached abbreviation objectsimport { resolveConfig, expand } from "emmet";
const config = resolveConfig({
syntax: "html",
warn: (message, error) => {
console.warn(`Emmet warning: ${message}`, error);
// Could log to external service, show user notification, etc.
}
});
// Invalid abbreviations will trigger warning callback
expand("div[unclosed-attribute", config);