diff --git a/index.js b/index.js index b4568a1a6..7cc33b1db 100644 --- a/index.js +++ b/index.js @@ -8,6 +8,14 @@ const normalizeOptions = require("./src/options").normalize; const parser = require("./src/parser"); const printDocToDebug = require("./src/doc-debug").printDocToDebug; +function guessLineEnding(text) { + const index = text.indexOf("\n"); + if (index >= 0 && text.charAt(index - 1) === "\r") { + return "\r\n"; + } + return "\n"; +} + function parse(text, opts) { const parseFunction = opts.parser === "flow" ? parser.parseWithFlow @@ -42,7 +50,7 @@ function format(text, opts) { const ast = parse(text, opts); attachComments(text, ast, opts); const doc = printAstToDoc(ast, opts); - const str = printDocToString(doc, opts.printWidth); + const str = printDocToString(doc, opts.printWidth, guessLineEnding(text)); return str; } @@ -55,9 +63,9 @@ function formatWithShebang(text, opts) { const shebang = text.slice(0, index + 1); const programText = text.slice(index + 1); const nextChar = text.charAt(index + 1); - const addNewline = nextChar == "\n" || nextChar == "\r"; + const newLine = nextChar === "\n" ? "\n" : (nextChar === "\r" ? "\r\n" : ""); - return shebang + (addNewline ? "\n" : "") + format(programText, opts); + return shebang + newLine + format(programText, opts); } module.exports = { diff --git a/src/doc-printer.js b/src/doc-printer.js index 33fb06b1e..49963078a 100644 --- a/src/doc-printer.js +++ b/src/doc-printer.js @@ -76,7 +76,9 @@ function fits(next, restCommands, width) { return false; } -function printDocToString(doc, w) { +function printDocToString(doc, width, newLine) { + newLine = newLine || "\n"; + let pos = 0; // cmds is basically a stack. We've turned a recursive call into a // while loop which is much faster. The while loop below adds new @@ -126,7 +128,7 @@ function printDocToString(doc, w) { shouldRemeasure = false; const next = [ ind, MODE_FLAT, doc.contents ]; - let rem = w - pos; + let rem = width - pos; if (!doc.break && fits(next, cmds, rem)) { cmds.push(next); @@ -212,7 +214,7 @@ function printDocToString(doc, w) { case MODE_BREAK: if (doc.literal) { - out.push(lineSuffix + "\n"); + out.push(lineSuffix + newLine); pos = 0; } else { if (out.length > 0) { @@ -223,7 +225,7 @@ function printDocToString(doc, w) { ); } - out.push(lineSuffix + "\n" + " ".repeat(ind)); + out.push(lineSuffix + newLine + " ".repeat(ind)); pos = ind; } diff --git a/tests/windows/__snapshots__/jsfmt.spec.js.snap b/tests/windows/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..59f5cdfa5 --- /dev/null +++ b/tests/windows/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,14 @@ +exports[`test line-ending.js 1`] = ` +"this; +has; +windows; +line; +endings; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +this; +has; +windows; +line; +endings; +" +`; diff --git a/tests/windows/jsfmt.spec.js b/tests/windows/jsfmt.spec.js new file mode 100644 index 000000000..989047bcc --- /dev/null +++ b/tests/windows/jsfmt.spec.js @@ -0,0 +1 @@ +run_spec(__dirname); diff --git a/tests/windows/line-ending.js b/tests/windows/line-ending.js new file mode 100644 index 000000000..65eb8ff78 --- /dev/null +++ b/tests/windows/line-ending.js @@ -0,0 +1,5 @@ +this; +has; +windows; +line; +endings;