UNPKG

eslint-plugin-comment-length

Version:

An ESLint plugin that provides rules that limit the line length of your comments

170 lines (152 loc) 4.77 kB
import type { Context } from "../../typings.context.js"; import { isLineOverflowing } from "../../utils/is-line-overflowing.js"; import type { MultilineBlock } from "./typings.block.js"; /** * captures the next logical group/block in the provided multi-line comment * content, based on a set of rules. * * 1) Everything within a set of back-ticks (``) is ignored, as this is used * to explicitly declare that the content should not be auto-fixed. * * 2) Lines that are not on the same indentation-level will not be recognized * as part of the same block. * * 3) Lines separated by a new-line will not be considered as part of the same * block. * * 4) Lines will only be grouped in case the current line of the block to be * constructed actually is overflowing. This avoids issues where auto-fixing * 'sucks' a line up even though the previous line should have been considered * a logical end to a block. */ export function captureNextBlock( ignoreFollowingLines: boolean, initialStartIndex: number, context: Context, ): [Omit<MultilineBlock, "value">, boolean] { let ignoreLines = ignoreFollowingLines; let startIndex = initialStartIndex; // the provided startIndex may not necessarily indicate the startIndex of the // next logical block. (it may e.g. just point to a blank line) // as such we need to determine the actual start of the next block. for (let i = initialStartIndex; i < context.comment.lines.length; i++) { const line = context.comment.lines[i]; // ensure that lines within backticks is skipped (and that the line itself // is ignored as it acts as a marker). if ( line?.trimStart().startsWith("` ") || line?.trimStart().startsWith("``") ) { ignoreLines = !ignoreLines; continue; } startIndex = i; if (line && line.trim() !== "" && !ignoreLines) { break; } } const blockLines: string[] = context.comment.lines.slice( startIndex, startIndex + 1, ); // In case we could not resolve the start of a new block, then we cannot // continue... if (blockLines.length === 0) { return [ { lines: blockLines, startIndex, endIndex: startIndex, lineOffsets: [], }, ignoreLines, ]; } // ... else we can begin analysing the following lines to determine if they // are to be added to the current group for (let i = startIndex; i < context.comment.lines.length; i++) { const currLine = context.comment.lines[i]; const nextLine = context.comment.lines[i + 1]; if (!currLine) { break; } const currLineOffset = currLine .match(/^( |\t)*/)?.[0] ?.split("") .reduce( (acc, curr) => acc + (curr === "\t" ? context.tabSize : 1), 0, ) ?? 0; const nextLineOffset = nextLine ?.match(/^( |\t)*/)?.[0] ?.split("") .reduce( (acc, curr) => acc + (curr === "\t" ? context.tabSize : 1), 0, ) ?? 0; if ( !nextLine || nextLine.trim() === "" || currLineOffset !== nextLineOffset || (context.mode === "overflow-only" && !isLineOverflowing( `${currLine} ${nextLine.trimStart().split(" ")[0] ?? ""}`.trimEnd(), context, )) ) { return [ { lines: blockLines, startIndex, endIndex: i, lineOffsets: blockLines.map((it, lineIndex) => { const whitespaceString = context.comment.value .split("\n") [startIndex + lineIndex]?.includes("*") ? (it.match(/^( |\t)*/)?.[0] ?? "") : " "; return { string: whitespaceString, size: whitespaceString .split("") .reduce( (acc, curr) => acc + (curr === "\t" ? context.tabSize : 1), 0, ) ?? 0, }; }), }, ignoreLines, ]; } blockLines.push(nextLine); } return [ { lines: blockLines, startIndex, endIndex: context.comment.lines.length, lineOffsets: blockLines.map((it, lineIndex) => { const whitespaceString = context.comment.value .split("\n") [startIndex + lineIndex]?.includes("*") ? (it.match(/^( |\t)*/)?.[0] ?? "") : " "; return { string: whitespaceString, size: whitespaceString .split("") .reduce( (acc, curr) => acc + (curr === "\t" ? context.tabSize : 1), 0, ) ?? 0, }; }), }, ignoreLines, ]; }