@d3lm/lint-preset 1.5.0 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -3
- package/dist/bin/comments.js +105 -51
- package/dist/bin/comments.js.map +1 -1
- package/dist/comments.cjs +94 -28
- package/dist/comments.cjs.map +1 -1
- package/dist/comments.d.cts +5 -3
- package/dist/comments.d.ts +5 -3
- package/dist/comments.js +94 -28
- package/dist/comments.js.map +1 -1
- package/package.json +1 -1
package/dist/comments.d.cts
CHANGED
|
@@ -9,7 +9,8 @@ interface WrapOptions {
|
|
|
9
9
|
*/
|
|
10
10
|
readonly avoidSentenceOrphans: boolean;
|
|
11
11
|
/**
|
|
12
|
-
* Sets how many columns a line may exceed its limit before it counts as overflowing.
|
|
12
|
+
* Sets how many columns a line may exceed its limit before it counts as overflowing. A layout
|
|
13
|
+
* also uses them when that saves a line.
|
|
13
14
|
*/
|
|
14
15
|
readonly tolerance: number;
|
|
15
16
|
/**
|
|
@@ -210,8 +211,9 @@ interface CommentsConfig {
|
|
|
210
211
|
*/
|
|
211
212
|
readonly singleLineWidth?: number;
|
|
212
213
|
/**
|
|
213
|
-
* Sets
|
|
214
|
-
*
|
|
214
|
+
* Sets how many columns prose lines may go past `width` when that saves a line in a paragraph of
|
|
215
|
+
* three or more lines. It never goes past `maxWidth`. When `maxWidth` is omitted, it also sets a
|
|
216
|
+
* legacy hard limit of `width + tolerance`.
|
|
215
217
|
*/
|
|
216
218
|
readonly tolerance?: number;
|
|
217
219
|
/**
|
package/dist/comments.d.ts
CHANGED
|
@@ -9,7 +9,8 @@ interface WrapOptions {
|
|
|
9
9
|
*/
|
|
10
10
|
readonly avoidSentenceOrphans: boolean;
|
|
11
11
|
/**
|
|
12
|
-
* Sets how many columns a line may exceed its limit before it counts as overflowing.
|
|
12
|
+
* Sets how many columns a line may exceed its limit before it counts as overflowing. A layout
|
|
13
|
+
* also uses them when that saves a line.
|
|
13
14
|
*/
|
|
14
15
|
readonly tolerance: number;
|
|
15
16
|
/**
|
|
@@ -210,8 +211,9 @@ interface CommentsConfig {
|
|
|
210
211
|
*/
|
|
211
212
|
readonly singleLineWidth?: number;
|
|
212
213
|
/**
|
|
213
|
-
* Sets
|
|
214
|
-
*
|
|
214
|
+
* Sets how many columns prose lines may go past `width` when that saves a line in a paragraph of
|
|
215
|
+
* three or more lines. It never goes past `maxWidth`. When `maxWidth` is omitted, it also sets a
|
|
216
|
+
* legacy hard limit of `width + tolerance`.
|
|
215
217
|
*/
|
|
216
218
|
readonly tolerance?: number;
|
|
217
219
|
/**
|
package/dist/comments.js
CHANGED
|
@@ -288,6 +288,8 @@ function hasWidow(lines) {
|
|
|
288
288
|
}
|
|
289
289
|
var FULLNESS_WEIGHT = 0.07;
|
|
290
290
|
var PARENTHETICAL_SPLIT_WEIGHT = 2;
|
|
291
|
+
var MAX_STEP = 15;
|
|
292
|
+
var EXTRA_LINES = 2;
|
|
291
293
|
function fewestLines(starts, target) {
|
|
292
294
|
const total = starts.length - 1;
|
|
293
295
|
const fewest = new Int32Array(total + 1);
|
|
@@ -420,7 +422,56 @@ function balanceTokens(tokens, firstLimit, restLimit, count, options, preferredL
|
|
|
420
422
|
const bounds = [0, ...best.breaks, total];
|
|
421
423
|
return bounds.slice(0, -1).map((start, index) => tokens.slice(start, bounds[index + 1]));
|
|
422
424
|
}
|
|
425
|
+
function hasStep(lines, offset = 0) {
|
|
426
|
+
return lines.some((line, index) => {
|
|
427
|
+
if (index === 0) {
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
const before = lineLength(lines[index - 1]) + (index === 1 ? offset : 0);
|
|
431
|
+
return lineLength(line) - before > MAX_STEP;
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
function splitCostsOf(tokens, limit) {
|
|
435
|
+
const splitCosts = /* @__PURE__ */ new Map();
|
|
436
|
+
for (const group of parentheticalGroups(tokens, limit)) {
|
|
437
|
+
const length = lineLength(tokens.slice(group.start, group.end));
|
|
438
|
+
for (let at = group.start + 1; at < group.end; at += 1) {
|
|
439
|
+
splitCosts.set(at, length * PARENTHETICAL_SPLIT_WEIGHT);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
return splitCosts;
|
|
443
|
+
}
|
|
444
|
+
function hasParentheticals(tokens, restLimit, options) {
|
|
445
|
+
if (options.parentheticalOverflow === void 0) {
|
|
446
|
+
return false;
|
|
447
|
+
}
|
|
448
|
+
return bindParentheticals(tokens, restLimit + options.parentheticalOverflow).some((token) => isParenthetical(token));
|
|
449
|
+
}
|
|
423
450
|
function layoutTokens(tokens, firstLimit, restLimit, options) {
|
|
451
|
+
const lines = layoutLines(tokens, firstLimit, restLimit, options);
|
|
452
|
+
const offset = restLimit - firstLimit;
|
|
453
|
+
if (options.keepFirstLine || options.keepSteps || !hasStep(lines, offset)) {
|
|
454
|
+
return lines;
|
|
455
|
+
}
|
|
456
|
+
const overflow = hasParentheticals(tokens, restLimit, options) ? options.parentheticalOverflow ?? 0 : 0;
|
|
457
|
+
const splitCosts = overflow > 0 ? splitCostsOf(tokens, restLimit + overflow) : /* @__PURE__ */ new Map();
|
|
458
|
+
for (let count = lines.length + 1; count <= lines.length + EXTRA_LINES; count += 1) {
|
|
459
|
+
const even = balanceTokens(
|
|
460
|
+
tokens,
|
|
461
|
+
firstLimit + overflow,
|
|
462
|
+
restLimit + overflow,
|
|
463
|
+
count,
|
|
464
|
+
options,
|
|
465
|
+
restLimit,
|
|
466
|
+
splitCosts
|
|
467
|
+
);
|
|
468
|
+
if (even && !hasStep(even, offset)) {
|
|
469
|
+
return even;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
return lines;
|
|
473
|
+
}
|
|
474
|
+
function layoutLines(tokens, firstLimit, restLimit, options) {
|
|
424
475
|
if (options.parentheticalOverflow !== void 0) {
|
|
425
476
|
const grouped = bindParentheticals(tokens, restLimit + options.parentheticalOverflow);
|
|
426
477
|
if (grouped.some((token) => isParenthetical(token))) {
|
|
@@ -454,14 +505,7 @@ function layoutTokens(tokens, firstLimit, restLimit, options) {
|
|
|
454
505
|
return expanded;
|
|
455
506
|
});
|
|
456
507
|
}
|
|
457
|
-
const splitCosts =
|
|
458
|
-
const groups = parentheticalGroups(tokens, restLimit + options.parentheticalOverflow);
|
|
459
|
-
for (const group of groups) {
|
|
460
|
-
const length = lineLength(tokens.slice(group.start, group.end));
|
|
461
|
-
for (let at = group.start + 1; at < group.end; at += 1) {
|
|
462
|
-
splitCosts.set(at, length * PARENTHETICAL_SPLIT_WEIGHT);
|
|
463
|
-
}
|
|
464
|
-
}
|
|
508
|
+
const splitCosts = splitCostsOf(tokens, restLimit + options.parentheticalOverflow);
|
|
465
509
|
const preferred = wrapTokens(tokens, firstLimit, restLimit, { ...options, parentheticalOverflow: void 0 });
|
|
466
510
|
for (let count = minimumLines; count <= Math.max(preferred.length + 1, preserved.length); count += 1) {
|
|
467
511
|
const balanced2 = balanceTokens(
|
|
@@ -491,6 +535,19 @@ function layoutTokens(tokens, firstLimit, restLimit, options) {
|
|
|
491
535
|
return lines;
|
|
492
536
|
}
|
|
493
537
|
}
|
|
538
|
+
if (options.tolerance > 0 && greedy.length > 2) {
|
|
539
|
+
const fewer = balanceTokens(
|
|
540
|
+
tokens,
|
|
541
|
+
firstLimit + options.tolerance,
|
|
542
|
+
restLimit + options.tolerance,
|
|
543
|
+
greedy.length - 1,
|
|
544
|
+
options,
|
|
545
|
+
restLimit
|
|
546
|
+
);
|
|
547
|
+
if (fewer && !hasStep(fewer, restLimit - firstLimit)) {
|
|
548
|
+
return fewer;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
494
551
|
const balanced = balanceTokens(tokens, firstLimit, restLimit, greedy.length, options);
|
|
495
552
|
if (balanced) {
|
|
496
553
|
return balanced;
|
|
@@ -980,11 +1037,11 @@ function analyzeParagraph(paragraph, options) {
|
|
|
980
1037
|
parentheticalOverflow: options.maxWidth === void 0 ? void 0 : options.maxWidth - options.width,
|
|
981
1038
|
keepFirstLine: paragraph.kind === "tag"
|
|
982
1039
|
};
|
|
983
|
-
const layOut = (from) => {
|
|
984
|
-
const even2 = layoutTokens(from, firstLimit, restLimit,
|
|
985
|
-
return { even: even2, wrapped: breakAfterSentence(even2, firstLimit, restLimit,
|
|
1040
|
+
const layOut = (from, settings) => {
|
|
1041
|
+
const even2 = layoutTokens(from, firstLimit, restLimit, settings);
|
|
1042
|
+
return { even: even2, wrapped: breakAfterSentence(even2, firstLimit, restLimit, settings) };
|
|
986
1043
|
};
|
|
987
|
-
|
|
1044
|
+
const units = bindLineStarts(paragraph.kind === "tag" ? bindTagHead(tokens) : tokens, startsLine);
|
|
988
1045
|
const hardLimit = restLimit + (options.maxWidth === void 0 ? options.tolerance : options.maxWidth - options.width);
|
|
989
1046
|
const written = currentLines.map((words) => ` ${words.join(" ")} `);
|
|
990
1047
|
const staysInLimit = (unit) => {
|
|
@@ -993,29 +1050,38 @@ function analyzeParagraph(paragraph, options) {
|
|
|
993
1050
|
if (!units.every((unit) => staysInLimit(unit))) {
|
|
994
1051
|
return keep({ tier: "manual", reason: "unbreakable text across lines" });
|
|
995
1052
|
}
|
|
996
|
-
let { even, wrapped } = layOut(units);
|
|
997
1053
|
const bodyOf = (lines) => {
|
|
998
1054
|
return lines.map((words, position) => {
|
|
999
1055
|
const text = `${position === 0 ? paragraph.marker : hang}${words.join(" ")}`;
|
|
1000
1056
|
return { ...first, text, verbatim: false, hardBreak: HARD_BREAK.test(text) };
|
|
1001
1057
|
});
|
|
1002
1058
|
};
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
const
|
|
1014
|
-
|
|
1059
|
+
const settle = (settings) => {
|
|
1060
|
+
let current = units;
|
|
1061
|
+
let { even: even2, wrapped: wrapped2 } = layOut(current, settings);
|
|
1062
|
+
for (; ; ) {
|
|
1063
|
+
const body = bodyOf(wrapped2);
|
|
1064
|
+
const rewrap = structureOf(body);
|
|
1065
|
+
if (!rewrap) {
|
|
1066
|
+
return { even: even2, wrapped: wrapped2 };
|
|
1067
|
+
}
|
|
1068
|
+
const tipping = body.findIndex((_, position) => structureOf(body.slice(0, position + 1)) !== void 0);
|
|
1069
|
+
const start = wrapped2.slice(0, Math.max(tipping, 1)).flat().length;
|
|
1070
|
+
const pair = `${current[start - 1]} ${current[start]}`;
|
|
1071
|
+
if (body.length < 2 || !staysInLimit(pair)) {
|
|
1072
|
+
const reading = rewrap.tier === "code-like" ? "code" : rewrap.reason;
|
|
1073
|
+
return { tier: "manual", reason: `rewrap would read as ${reading}` };
|
|
1074
|
+
}
|
|
1075
|
+
current = current.toSpliced(start - 1, 2, pair);
|
|
1076
|
+
({ even: even2, wrapped: wrapped2 } = layOut(current, settings));
|
|
1015
1077
|
}
|
|
1016
|
-
|
|
1017
|
-
|
|
1078
|
+
};
|
|
1079
|
+
const settled = settle(layoutOptions);
|
|
1080
|
+
const layout = "wrapped" in settled ? settled : settle({ ...layoutOptions, keepSteps: true });
|
|
1081
|
+
if (!("wrapped" in layout)) {
|
|
1082
|
+
return keep(layout);
|
|
1018
1083
|
}
|
|
1084
|
+
const { even, wrapped } = layout;
|
|
1019
1085
|
const matchesLayout = sameLayout(wrapped, currentLines);
|
|
1020
1086
|
const lineIssues = [];
|
|
1021
1087
|
const overflow = options.maxWidth === void 0 ? [] : overflowIssues(paragraph.lines, options);
|
|
@@ -1229,7 +1295,7 @@ When rules pull in different directions, the earlier one wins.
|
|
|
1229
1295
|
|
|
1230
1296
|
## Layout
|
|
1231
1297
|
|
|
1232
|
-
- After you finish, the tool rewraps prose paragraphs, list items, and JSDoc tag descriptions. The width is a preferred target. A parenthetical may extend a line up to the configured maximum so it stays together. In longer paragraphs, balanced lines take priority over keeping every parenthetical on one line. The tool also avoids short last lines where possible. Leave these line breaks to the tool, except for the sentence-orphan case below.
|
|
1298
|
+
- After you finish, the tool rewraps prose paragraphs, list items, and JSDoc tag descriptions. The width is a preferred target. A parenthetical may extend a line up to the configured maximum so it stays together, and lines may go up to the configured tolerance past the width when that saves a line. In longer paragraphs, balanced lines take priority over keeping every parenthetical on one line. The tool also avoids short last lines where possible. Leave these line breaks to the tool, except for the sentence-orphan case below.
|
|
1233
1299
|
- Don't end a line with the first word of a new sentence, clause, or parenthetical, like \`This\` after a period, \`the\` after a comma, or \`(the\`. Move it to the next line instead.
|
|
1234
1300
|
- In a paragraph of two lines, the first line ends with a sentence whenever the rest fits on the second line and is no longer than the first. Don't end it with the start of the next sentence, like \`A wrap\` in \`...lay out differently. A wrap\`. Move those words to the second line instead.
|
|
1235
1301
|
- A comment whose whole text is one paragraph stays on a single line when that line fits a separate, larger single-line width, even past the width. Only a longer comment wraps to the width.
|