UNPKG

eslint-plugin-complete

Version:

An ESLint plugin that contains useful rules.

141 lines (140 loc) 5.06 kB
export var ListKind; (function (ListKind) { ListKind["Hyphen"] = "Hyphen"; ListKind["NumberParenthesis"] = "NumberParenthesis"; ListKind["NumberPeriod"] = "NumberPeriod"; ListKind["JSDocTag"] = "JSDocTag"; })(ListKind || (ListKind = {})); /** * When using the `getList` function, the returned list may not be accurate if this is a line that * is continuing from the previous line. For example: * * ```text * This method will crash the game if you provide it an invalid number, such as 10000000000000000 or * 43. (Using 0 will not cause a crash.) * ``` * * Here, "43. " is incorrectly interpreted as the beginning of a list. In order to work around this * problem, use the `getAdjustedList` function instead. */ export function getAdjustedList(line, previousLineWasBlank, previousLineEndedInColon, insideList) { const list = getList(line); if (list === undefined) { return undefined; } switch (list.kind) { case ListKind.Hyphen: { return list; } case ListKind.NumberPeriod: case ListKind.NumberParenthesis: { // If we are already inside of a numbered list, then do not require blank lines in between the // bullets. if (list.kind === insideList?.kind) { return list; } // If the previous line had a colon, then do not require blank lines in between the bullets. if (previousLineEndedInColon) { return list; } // Otherwise, only interpret this as a bulleted list if the previous line was blank. return previousLineWasBlank ? list : undefined; } case ListKind.JSDocTag: { return list; } } } function getList(line) { const originalLength = line.length; line = line.trimStart(); const trimmedLength = line.length; const numLeadingSpaces = originalLength - trimmedLength; // e.g. "- A bullet point can start with a hyphen." if (line.startsWith("- ")) { return { kind: ListKind.Hyphen, numLeadingSpaces, markerSize: "- ".length, }; } /** e.g. "1. A bullet point can start with a number and a period." */ const numberPeriodMatch = line.match(/^(\d+)\. /); if (numberPeriodMatch !== null && numberPeriodMatch[1] !== undefined && numberPeriodMatch[1] !== "0") { return { kind: ListKind.NumberPeriod, numLeadingSpaces, markerSize: numberPeriodMatch[1].length + ". ".length, }; } /** e.g. "1) A bullet point can start with a number and a parenthesis." */ const numberParenthesisMatch = line.match(/^(\d+)\) /); if (numberParenthesisMatch !== null && numberParenthesisMatch[1] !== undefined && numberParenthesisMatch[1] !== "0") { return { kind: ListKind.NumberParenthesis, numLeadingSpaces, markerSize: numberParenthesisMatch[1].length + ") ".length, }; } const jsDocTagName = getJSDocTagName(line); if (jsDocTagName !== undefined) { return { kind: ListKind.JSDocTag, numLeadingSpaces, markerSize: jsDocTagName.length + " ".length, jsDocTagName, }; } return undefined; } /** * Returns a string containing the param header, if any. For example, "@returns Foo" would return * "@returns". * * For "@param" tags, the returned tag string will include the variable name, if any. For example, * "@param foo Foo" would return "@param foo". */ function getJSDocTagName(text) { text = text.trimStart(); if (!text.startsWith("@")) { return undefined; } const tagMatch = text.match(/^@(?<tagName>\w+)/); if (tagMatch === null || tagMatch.groups === undefined) { return undefined; } const { tagName } = tagMatch.groups; if (tagName === undefined) { return undefined; } // Specific JSDoc tags have words after them that should be part of the tag for indenting // purposes. if (tagName === "param") { const paramMatch = text.match(/^(?<tagWithVariableName>@\w+ \w+)/); if (paramMatch === null || paramMatch.groups === undefined) { return "@param"; } const { tagWithVariableName } = paramMatch.groups; if (tagWithVariableName === undefined) { return "@param"; } return tagWithVariableName; } return `@${tagName}`; } /** * When iterating over lines of text, by default, we want to keep the existing list object, if any. */ export function reachedNewList(insideList, list) { if (list === undefined) { return false; } return (insideList === undefined // Going from a non-list to list || insideList.numLeadingSpaces !== list.numLeadingSpaces // Going from a list to a sub-list || insideList.jsDocTagName !== list.jsDocTagName // Going from a JSDoc to a different JSDoc tag ); }