2 * @fileoverview Require or disallow newline at the end of files
3 * @author Nodeca Team <https://github.com/nodeca>
7 //------------------------------------------------------------------------------
9 //------------------------------------------------------------------------------
11 const lodash = require("lodash");
13 //------------------------------------------------------------------------------
15 //------------------------------------------------------------------------------
22 description: "require or disallow newline at the end of files",
23 category: "Stylistic Issues",
25 url: "https://eslint.org/docs/rules/eol-last"
28 fixable: "whitespace",
32 enum: ["always", "never", "unix", "windows"]
37 missing: "Newline required at end of file but not found.",
38 unexpected: "Newline not allowed at end of file."
43 //--------------------------------------------------------------------------
45 //--------------------------------------------------------------------------
48 Program: function checkBadEOF(node) {
49 const sourceCode = context.getSourceCode(),
50 src = sourceCode.getText(),
52 column: lodash.last(sourceCode.lines).length,
53 line: sourceCode.lines.length
57 endsWithNewline = src.endsWith(LF);
60 * Empty source is always valid: No content in file so we don't
61 * need to lint for a newline on the last line of content.
67 let mode = context.options[0] || "always",
70 if (mode === "unix") {
72 // `"unix"` should behave exactly as `"always"`
75 if (mode === "windows") {
77 // `"windows"` should behave exactly as `"always"`, but append CRLF in the fixer for backwards compatibility
81 if (mode === "always" && !endsWithNewline) {
83 // File is not newline-terminated, but should be
89 return fixer.insertTextAfterRange([0, src.length], appendCRLF ? CRLF : LF);
92 } else if (mode === "never" && endsWithNewline) {
94 // File is newline-terminated, but shouldn't be
98 messageId: "unexpected",
100 const finalEOLs = /(?:\r?\n)+$/u,
101 match = finalEOLs.exec(sourceCode.text),
103 end = sourceCode.text.length;
105 return fixer.replaceTextRange([start, end], "");