diff --git a/docs/rules/enforce-consistent-line-wrapping.md b/docs/rules/enforce-consistent-line-wrapping.md
index 9939c34..98f1565 100644
--- a/docs/rules/enforce-consistent-line-wrapping.md
+++ b/docs/rules/enforce-consistent-line-wrapping.md
@@ -9,6 +9,7 @@ Enforce tailwind classes to be broken up into multiple lines. It is possible to
### `printWidth`
The maximum line length. Lines are wrapped appropriately to stay within this limit. The value `0` disables line wrapping by `printWidth`.
+ Tabs count according to [`tabWidth`](#tabwidth) when evaluating this limit.
**Type**: `number`
**Default**: `80`
@@ -51,6 +52,16 @@ Enforce tailwind classes to be broken up into multiple lines. It is possible to
+### `tabWidth`
+
+ Determines how many columns a tab character contributes when checking `printWidth`.
+ This option only affects width calculations and does not change emitted indentation characters.
+
+ **Type**: `number`
+ **Default**: `1`
+
+
+
### `lineBreakStyle`
The line break style.
diff --git a/src/rules/enforce-consistent-line-wrapping.test.ts b/src/rules/enforce-consistent-line-wrapping.test.ts
index 4da092a..ef10e2f 100644
--- a/src/rules/enforce-consistent-line-wrapping.test.ts
+++ b/src/rules/enforce-consistent-line-wrapping.test.ts
@@ -841,6 +841,90 @@ describe(enforceConsistentLineWrapping.name, () => {
);
});
+ it("should use tabWidth when checking printWidth", () => {
+
+ const dirty = "a b c d";
+ const clean = "\n\ta b c\n\td\n";
+
+ lint(
+ enforceConsistentLineWrapping,
+ {
+ invalid: [
+ {
+ jsx: `() =>
`,
+ jsxOutput: `() =>
`,
+ svelte: `
`,
+ svelteOutput: `
`,
+
+ errors: 1,
+ options: [{ classesPerLine: 0, indent: "tab", printWidth: 10, tabWidth: 4 }]
+ }
+ ]
+ }
+ );
+ });
+
+ it("should default tabWidth to 1 when it is not configured", () => {
+ lint(
+ enforceConsistentLineWrapping,
+ {
+ invalid: [
+ {
+ jsx: `() =>
`,
+ jsxOutput: `() =>
`,
+ svelte: `
`,
+ svelteOutput: `
`,
+
+ errors: 1,
+ options: [{ classesPerLine: 0, indent: "tab", printWidth: 10 }]
+ }
+ ]
+ }
+ );
+ });
+
+ it("should not apply tabWidth when indentation uses spaces", () => {
+ lint(
+ enforceConsistentLineWrapping,
+ {
+ invalid: [
+ {
+ jsx: `() =>
`,
+ jsxOutput: `() =>
`,
+ svelte: `
`,
+ svelteOutput: `
`,
+
+ errors: 1,
+ options: [{ classesPerLine: 0, indent: 2, printWidth: 10, tabWidth: 8 }]
+ }
+ ]
+ }
+ );
+ });
+
+ it("should still ignore printWidth when it is set to 0 even with tabWidth", () => {
+
+ const dirty = "a b c d";
+ const clean = "\n\ta b c\n\td\n";
+
+ lint(
+ enforceConsistentLineWrapping,
+ {
+ invalid: [
+ {
+ jsx: `() =>
`,
+ jsxOutput: `() =>
`,
+ svelte: `
`,
+ svelteOutput: `
`,
+
+ errors: 1,
+ options: [{ classesPerLine: 3, indent: "tab", printWidth: 0, tabWidth: 4 }]
+ }
+ ]
+ }
+ );
+ });
+
it("should warn if `lineBreakStyle` is likely misconfigured", async () => {
{
@@ -975,7 +1059,6 @@ describe(enforceConsistentLineWrapping.name, () => {
// #52
it("should wrap expressions even if `group` is set to `never`", () => {
-
const expression = "${true ? 'b' : 'c'}";
const correct = dedent`
@@ -997,7 +1080,6 @@ describe(enforceConsistentLineWrapping.name, () => {
]
}
);
-
});
it("should be possible to change group separation by emptyLines", () => {
@@ -1099,7 +1181,34 @@ describe(enforceConsistentLineWrapping.name, () => {
]
}
);
+ });
+
+ it("should still start on a new line when `group` is set to `never` except if `preferSingleLine` is enabled", () => {
+ lint(
+ enforceConsistentLineWrapping,
+ {
+ valid: [
+ {
+ angular: `
`,
+ html: `
`,
+ jsx: `() =>
`,
+ svelte: `
`,
+ vue: `
`,
+
+ options: [{ group: "never", preferSingleLine: false, printWidth: 100 }]
+ },
+ {
+ angular: `
`,
+ html: `
`,
+ jsx: `() =>
`,
+ svelte: `
`,
+ vue: `
`,
+ options: [{ group: "never", preferSingleLine: true, printWidth: 100 }]
+ }
+ ]
+ }
+ );
});
it("should remove duplicate classes in string literals in defined tagged template literals", () => {
diff --git a/src/rules/enforce-consistent-line-wrapping.ts b/src/rules/enforce-consistent-line-wrapping.ts
index 01eecf5..da67e05 100644
--- a/src/rules/enforce-consistent-line-wrapping.ts
+++ b/src/rules/enforce-consistent-line-wrapping.ts
@@ -103,6 +103,14 @@ export const enforceConsistentLineWrapping = createRule({
description("Enable this option if prettier is used in your project.")
),
"strict"
+ ),
+ tabWidth: optional(
+ pipe(
+ number(),
+ minValue(1),
+ description("The visual width of a tab character when evaluating printWidth.")
+ ),
+ 1
)
}),
@@ -239,8 +247,7 @@ function lintLiterals(ctx: Context, litera
const simulatedLine = multilineClasses.line
.clone()
- .addClass(className)
- .toString();
+ .addClass(className);
// wrap after the first sticky class
if(
@@ -582,7 +589,22 @@ class Line {
}
public get length() {
- return this.toString().length;
+ const line = this.toString();
+ const { tabWidth } = this.ctx.options;
+
+ if(tabWidth <= 1 || !line.includes("\t")){
+ return line.length;
+ }
+
+ let width = 0;
+
+ for(let i = 0; i < line.length; i++){
+ width += line[i] === "\t"
+ ? tabWidth
+ : 1;
+ }
+
+ return width;
}
public get classCount() {