import { TSESTree } from "@typescript-eslint/experimental-utils"; import { createRule } from "./utils"; export = createRule({ name: "simple-indent", meta: { docs: { description: "Enforce consistent indentation", category: "Stylistic Issues", recommended: "error", }, messages: { simpleIndentError: "4 space indentation expected", }, fixable: "whitespace", schema: [], type: "layout", }, defaultOptions: [], create(context) { const TAB_SIZE = 4; const TAB_REGEX = /\t/g; const sourceCode = context.getSourceCode(); const linebreaks = sourceCode.getText().match(/\r\n|[\r\n\u2028\u2029]/gu); const checkIndent = (node: TSESTree.Program) => { const lines = sourceCode.getLines(); const linesLen = lines.length; let totalLen = 0; for (let i = 0; i < linesLen; i++) { const lineNumber = i + 1; const line = lines[i]; const linebreaksLen = linebreaks && linebreaks[i] ? linebreaks[i].length : 1; const lineLen = line.length + linebreaksLen; const matches = /\S/.exec(line); if (matches && matches.index) { const indentEnd = matches.index; const whitespace = line.slice(0, indentEnd); if (!TAB_REGEX.test(whitespace)) { totalLen += lineLen; continue; } context.report({ messageId: "simpleIndentError", node, loc: { column: indentEnd, line: lineNumber }, fix(fixer) { const rangeStart = totalLen; const rangeEnd = rangeStart + indentEnd; return fixer .replaceTextRange([rangeStart, rangeEnd], whitespace.replace(TAB_REGEX, " ".repeat(TAB_SIZE))); } }); } totalLen += lineLen; } }; return { Program: checkIndent, }; }, });