diff --git a/docs/api.md b/docs/api.md index bb0726932..da66b0d36 100644 --- a/docs/api.md +++ b/docs/api.md @@ -51,6 +51,7 @@ prettier.resolveConfig(filePath).then(options => { If `options.editorconfig` is `true` and an [`.editorconfig` file](http://editorconfig.org/) is in your project, Prettier will parse it and convert its properties to the corresponding prettier configuration. This configuration will be overridden by `.prettierrc`, etc. Currently, the following EditorConfig properties are supported: +- `end_of_line` - `indent_style` - `indent_size`/`tab_width` - `max_line_length` diff --git a/docs/options.md b/docs/options.md index 85c293311..d2efb0276 100644 --- a/docs/options.md +++ b/docs/options.md @@ -271,3 +271,45 @@ Valid options: | Default | CLI Override | API Override | | ------------ | ----------------------------------------------------------- | ----------------------------------------------------------- | | `"preserve"` | --prose-wrap | proseWrap: "" | + + diff --git a/package.json b/package.json index 0fb27e731..8a6f371aa 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "dedent": "0.7.0", "diff": "3.2.0", "editorconfig": "0.15.2", - "editorconfig-to-prettier": "0.0.6", + "editorconfig-to-prettier": "0.1.0", "emoji-regex": "6.5.1", "escape-string-regexp": "1.0.5", "esutils": "2.0.2", diff --git a/src/common/end-of-line.js b/src/common/end-of-line.js new file mode 100644 index 000000000..a9a565cb5 --- /dev/null +++ b/src/common/end-of-line.js @@ -0,0 +1,25 @@ +"use strict"; + +function guessEndOfLine(text) { + const index = text.indexOf("\r"); + if (index >= 0) { + return text.charAt(index + 1) === "\n" ? "crlf" : "cr"; + } + return "lf"; +} + +function convertEndOfLineToChars(value) { + switch (value) { + case "cr": + return "\r"; + case "crlf": + return "\r\n"; + default: + return "\n"; + } +} + +module.exports = { + guessEndOfLine, + convertEndOfLineToChars +}; diff --git a/src/doc/doc-printer.js b/src/doc/doc-printer.js index 5d2e511ba..6050b7b75 100644 --- a/src/doc/doc-printer.js +++ b/src/doc/doc-printer.js @@ -1,6 +1,7 @@ "use strict"; const { getStringWidth } = require("../common/util"); +const { convertEndOfLineToChars } = require("../common/end-of-line"); const { concat, fill, cursor } = require("./doc-builders"); /** @type {{[groupId: PropertyKey]: MODE}} */ @@ -241,7 +242,7 @@ function printDocToString(doc, options) { groupModeMap = {}; const width = options.printWidth; - const newLine = options.newLine || "\n"; + const newLine = convertEndOfLineToChars(options.endOfLine); 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 diff --git a/src/language-js/pragma.js b/src/language-js/pragma.js index 031359a8f..6bd14660c 100644 --- a/src/language-js/pragma.js +++ b/src/language-js/pragma.js @@ -10,10 +10,12 @@ function hasPragma(text) { function insertPragma(text) { const parsedDocblock = docblock.parseWithComments(docblock.extract(text)); const pragmas = Object.assign({ format: "" }, parsedDocblock.pragmas); - const newDocblock = docblock.print({ - pragmas, - comments: parsedDocblock.comments.replace(/^(\s+?\r?\n)+/, "") // remove leading newlines - }); + const newDocblock = docblock + .print({ + pragmas, + comments: parsedDocblock.comments.replace(/^(\s+?\r?\n)+/, "") // remove leading newlines + }) + .replace(/(\r\n|\r)/g, "\n"); // normalise newlines (mitigate use of os.EOL by jest-docblock) const strippedText = docblock.strip(text); const separatingNewlines = strippedText.startsWith("\n") ? "\n" : "\n\n"; return newDocblock + separatingNewlines + strippedText; diff --git a/src/main/core-options.js b/src/main/core-options.js index ab88c571a..1f466910c 100644 --- a/src/main/core-options.js +++ b/src/main/core-options.js @@ -62,6 +62,36 @@ const options = { `, cliCategory: CATEGORY_EDITOR }, + endOfLine: { + since: "1.15.0", + category: CATEGORY_GLOBAL, + type: "choice", + default: "auto", + description: "Which end of line characters to apply.", + choices: [ + { + value: "auto", + description: dedent` + Maintain existing + (mixed values within one file are normalised by looking at what's used after the first line) + ` + }, + { + value: "lf", + description: + "Line Feed only (\\n), common on Linux and macOS as well as inside git repos" + }, + { + value: "crlf", + description: + "Carriage Return + Line Feed characters (\\r\\n), common on Windows" + }, + { + value: "cr", + description: "Carriage Return character only (\\r), used very rarely" + } + ] + }, filepath: { since: "1.4.0", category: CATEGORY_SPECIAL, diff --git a/src/main/core.js b/src/main/core.js index b92e97cb6..fc4ee7724 100644 --- a/src/main/core.js +++ b/src/main/core.js @@ -7,6 +7,10 @@ const massageAST = require("./massage-ast"); const comments = require("./comments"); const parser = require("./parser"); const printAstToDoc = require("./ast-to-doc"); +const { + guessEndOfLine, + convertEndOfLineToChars +} = require("../common/end-of-line"); const rangeUtil = require("./range-util"); const privateUtil = require("../common/util"); const { @@ -18,14 +22,6 @@ const UTF8BOM = 0xfeff; const CURSOR = Symbol("cursor"); -function guessLineEnding(text) { - const index = text.indexOf("\n"); - if (index >= 0 && text.charAt(index - 1) === "\r") { - return "\r\n"; - } - return "\n"; -} - function ensureAllCommentsPrinted(astComments) { if (!astComments) { return; @@ -84,7 +80,9 @@ function coreFormat(text, opts, addAlignmentSize) { const astComments = attachComments(text, ast, opts); const doc = printAstToDoc(ast, opts, addAlignmentSize); - opts.newLine = guessLineEnding(originalText); + if (opts.endOfLine === "auto") { + opts.endOfLine = guessEndOfLine(originalText); + } const result = printDocToString(doc, opts); @@ -97,7 +95,7 @@ function coreFormat(text, opts, addAlignmentSize) { result.cursorNodeStart -= result.formatted.indexOf(trimmed); } - result.formatted = trimmed + opts.newLine; + result.formatted = trimmed + convertEndOfLineToChars(opts.endOfLine); } if (opts.cursorOffset >= 0) { diff --git a/tests/end_of_line/__snapshots__/jsfmt.spec.js.snap b/tests/end_of_line/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..10f269b4c --- /dev/null +++ b/tests/end_of_line/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,83 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`usingCrlf.js - babylon-verify 1`] = ` +function f() { + console.log("testing line endings"); +} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +function f() { + console.log("testing line endings"); +} + +`; + +exports[`usingCrlf.js - babylon-verify 2`] = ` +function f() { + console.log("testing line endings"); +} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +function f() {/*CR*/ console.log("testing line endings");/*CR*/}/*CR*/ +`; + +exports[`usingCrlf.js - babylon-verify 3`] = ` +function f() { + console.log("testing line endings"); +} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +function f() {/*CR*/ + console.log("testing line endings");/*CR*/ +}/*CR*/ + +`; + +exports[`usingCrlf.js - babylon-verify 4`] = ` +function f() { + console.log("testing line endings"); +} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +function f() { + console.log("testing line endings"); +} + +`; + +exports[`usingLf.js - babylon-verify 1`] = ` +function f() { + console.log("testing line endings"); +} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +function f() { + console.log("testing line endings"); +} + +`; + +exports[`usingLf.js - babylon-verify 2`] = ` +function f() { + console.log("testing line endings"); +} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +function f() {/*CR*/ console.log("testing line endings");/*CR*/}/*CR*/ +`; + +exports[`usingLf.js - babylon-verify 3`] = ` +function f() { + console.log("testing line endings"); +} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +function f() {/*CR*/ + console.log("testing line endings");/*CR*/ +}/*CR*/ + +`; + +exports[`usingLf.js - babylon-verify 4`] = ` +function f() { + console.log("testing line endings"); +} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +function f() { + console.log("testing line endings"); +} + +`; diff --git a/tests/end_of_line/jsfmt.spec.js b/tests/end_of_line/jsfmt.spec.js new file mode 100644 index 000000000..ebf669258 --- /dev/null +++ b/tests/end_of_line/jsfmt.spec.js @@ -0,0 +1,4 @@ +run_spec(__dirname, ["babylon"]); +run_spec(__dirname, ["babylon"], { endOfLine: "cr" }); +run_spec(__dirname, ["babylon"], { endOfLine: "crlf" }); +run_spec(__dirname, ["babylon"], { endOfLine: "lf" }); diff --git a/tests/end_of_line/usingCrlf.js b/tests/end_of_line/usingCrlf.js new file mode 100644 index 000000000..d5059e10d --- /dev/null +++ b/tests/end_of_line/usingCrlf.js @@ -0,0 +1,3 @@ +function f() { + console.log("testing line endings"); +} diff --git a/tests/end_of_line/usingLf.js b/tests/end_of_line/usingLf.js new file mode 100644 index 000000000..9f2e33648 --- /dev/null +++ b/tests/end_of_line/usingLf.js @@ -0,0 +1,3 @@ +function f() { + console.log("testing line endings"); +} diff --git a/tests/end_of_line_in_css/__snapshots__/jsfmt.spec.js.snap b/tests/end_of_line_in_css/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..83c2e719c --- /dev/null +++ b/tests/end_of_line_in_css/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,75 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`usingCrlf.css - css-verify 1`] = ` +.foo { + margin: 42px; +}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.foo { + margin: 42px; +} + +`; + +exports[`usingCrlf.css - css-verify 2`] = ` +.foo { + margin: 42px; +}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.foo {/*CR*/ margin: 42px;/*CR*/}/*CR*/ +`; + +exports[`usingCrlf.css - css-verify 3`] = ` +.foo { + margin: 42px; +}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.foo {/*CR*/ + margin: 42px;/*CR*/ +}/*CR*/ + +`; + +exports[`usingCrlf.css - css-verify 4`] = ` +.foo { + margin: 42px; +}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.foo { + margin: 42px; +} + +`; + +exports[`usingLf.css - css-verify 1`] = ` +.foo { + margin: 42px; +}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.foo { + margin: 42px; +} + +`; + +exports[`usingLf.css - css-verify 2`] = ` +.foo { + margin: 42px; +}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.foo {/*CR*/ margin: 42px;/*CR*/}/*CR*/ +`; + +exports[`usingLf.css - css-verify 3`] = ` +.foo { + margin: 42px; +}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.foo {/*CR*/ + margin: 42px;/*CR*/ +}/*CR*/ + +`; + +exports[`usingLf.css - css-verify 4`] = ` +.foo { + margin: 42px; +}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.foo { + margin: 42px; +} + +`; diff --git a/tests/end_of_line_in_css/jsfmt.spec.js b/tests/end_of_line_in_css/jsfmt.spec.js new file mode 100644 index 000000000..60e474ddd --- /dev/null +++ b/tests/end_of_line_in_css/jsfmt.spec.js @@ -0,0 +1,4 @@ +run_spec(__dirname, ["css"]); +run_spec(__dirname, ["css"], { endOfLine: "cr" }); +run_spec(__dirname, ["css"], { endOfLine: "crlf" }); +run_spec(__dirname, ["css"], { endOfLine: "lf" }); diff --git a/tests/end_of_line_in_css/usingCrlf.css b/tests/end_of_line_in_css/usingCrlf.css new file mode 100644 index 000000000..f03735f1c --- /dev/null +++ b/tests/end_of_line_in_css/usingCrlf.css @@ -0,0 +1,3 @@ +.foo { + margin: 42px; +} \ No newline at end of file diff --git a/tests/end_of_line_in_css/usingLf.css b/tests/end_of_line_in_css/usingLf.css new file mode 100644 index 000000000..bba7583ec --- /dev/null +++ b/tests/end_of_line_in_css/usingLf.css @@ -0,0 +1,3 @@ +.foo { + margin: 42px; +} \ No newline at end of file diff --git a/tests/end_of_line_in_markdown/__snapshots__/jsfmt.spec.js.snap b/tests/end_of_line_in_markdown/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..b569d7521 --- /dev/null +++ b/tests/end_of_line_in_markdown/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,75 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`usingCrlf.md - markdown-verify 1`] = ` +# Markdown file + +testing line endings~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Markdown file + +testing line endings + +`; + +exports[`usingCrlf.md - markdown-verify 2`] = ` +# Markdown file + +testing line endings~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Markdown file/*CR*//*CR*/testing line endings/*CR*/ +`; + +exports[`usingCrlf.md - markdown-verify 3`] = ` +# Markdown file + +testing line endings~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Markdown file/*CR*/ +/*CR*/ +testing line endings/*CR*/ + +`; + +exports[`usingCrlf.md - markdown-verify 4`] = ` +# Markdown file + +testing line endings~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Markdown file + +testing line endings + +`; + +exports[`usingLf.md - markdown-verify 1`] = ` +# Markdown file + +testing line endings~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Markdown file + +testing line endings + +`; + +exports[`usingLf.md - markdown-verify 2`] = ` +# Markdown file + +testing line endings~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Markdown file/*CR*//*CR*/testing line endings/*CR*/ +`; + +exports[`usingLf.md - markdown-verify 3`] = ` +# Markdown file + +testing line endings~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Markdown file/*CR*/ +/*CR*/ +testing line endings/*CR*/ + +`; + +exports[`usingLf.md - markdown-verify 4`] = ` +# Markdown file + +testing line endings~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Markdown file + +testing line endings + +`; diff --git a/tests/end_of_line_in_markdown/jsfmt.spec.js b/tests/end_of_line_in_markdown/jsfmt.spec.js new file mode 100644 index 000000000..ed5182283 --- /dev/null +++ b/tests/end_of_line_in_markdown/jsfmt.spec.js @@ -0,0 +1,4 @@ +run_spec(__dirname, ["markdown"]); +run_spec(__dirname, ["markdown"], { endOfLine: "cr" }); +run_spec(__dirname, ["markdown"], { endOfLine: "crlf" }); +run_spec(__dirname, ["markdown"], { endOfLine: "lf" }); diff --git a/tests/end_of_line_in_markdown/usingCrlf.md b/tests/end_of_line_in_markdown/usingCrlf.md new file mode 100644 index 000000000..96f32548f --- /dev/null +++ b/tests/end_of_line_in_markdown/usingCrlf.md @@ -0,0 +1,3 @@ +# Markdown file + +testing line endings \ No newline at end of file diff --git a/tests/end_of_line_in_markdown/usingLf.md b/tests/end_of_line_in_markdown/usingLf.md new file mode 100644 index 000000000..f17751517 --- /dev/null +++ b/tests/end_of_line_in_markdown/usingLf.md @@ -0,0 +1,3 @@ +# Markdown file + +testing line endings \ No newline at end of file diff --git a/tests_config/run_spec.js b/tests_config/run_spec.js index 8880de75f..386d8da4d 100644 --- a/tests_config/run_spec.js +++ b/tests_config/run_spec.js @@ -83,7 +83,10 @@ function run_spec(dirname, parsers, options) { expect(() => { ppastMassaged = parse( - prettyprint(input, path, compareOptions), + prettyprint(input, path, compareOptions) + // \r has been replaced with /*CR*/ to test presence of CR in jest snapshots; + // reverting this to get the right AST + .replace(/\/\*CR\*\//g, "\r"), compareOptions ); }).not.toThrow(); @@ -120,7 +123,10 @@ function prettyprint(src, filename, options) { "<|>" + result.formatted.slice(result.cursorOffset); } - return result.formatted; + + // \r is trimmed from jest snapshots by default; + // manually replacing this character with /*CR*/ to test its true presence + return result.formatted.replace(/\r/g, "/*CR*/"); } function read(filename) { diff --git a/tests_integration/__tests__/__snapshots__/config-resolution.js.snap b/tests_integration/__tests__/__snapshots__/config-resolution.js.snap index 96d3dec43..0e3519797 100644 --- a/tests_integration/__tests__/__snapshots__/config-resolution.js.snap +++ b/tests_integration/__tests__/__snapshots__/config-resolution.js.snap @@ -3,7 +3,17 @@ exports[`CLI overrides take precedence (stderr) 1`] = `""`; exports[`CLI overrides take precedence (stdout) 1`] = ` -"function f() { +"function f() {/*CR*/ console.log(/*CR*/ \\"line endings should be CR\\"/*CR*/ )/*CR*/}/*CR*/function f() {/*CR*/ + console.log(/*CR*/ + \\"line endings should be CRLF\\"/*CR*/ + )/*CR*/ +}/*CR*/ +function f() { + console.log( + \\"line endings should be LF\\" + ) +} +function f() { console.log( \\"should have tab width 8\\" ) @@ -114,7 +124,13 @@ exports[`resolves configuration file with --find-config-path file (write) 1`] = exports[`resolves configuration from external files (stderr) 1`] = `""`; exports[`resolves configuration from external files (stdout) 1`] = ` -"function f() { +"function f() {/*CR*/ console.log(\\"line endings should be CR\\")/*CR*/}/*CR*/function f() {/*CR*/ + console.log(\\"line endings should be CRLF\\")/*CR*/ +}/*CR*/ +function f() { + console.log(\\"line endings should be LF\\") +} +function f() { console.log(\\"should have tab width 8\\") } function f() { diff --git a/tests_integration/__tests__/__snapshots__/early-exit.js.snap b/tests_integration/__tests__/__snapshots__/early-exit.js.snap index 572f147af..290a7fff3 100644 --- a/tests_integration/__tests__/__snapshots__/early-exit.js.snap +++ b/tests_integration/__tests__/__snapshots__/early-exit.js.snap @@ -60,6 +60,9 @@ Format options: Include parentheses around a sole arrow function parameter. Defaults to avoid. --no-bracket-spacing Do not print spaces between brackets. + --end-of-line + Which end of line characters to apply. + Defaults to auto. --html-whitespace-sensitivity How to handle whitespaces in HTML. Defaults to css. @@ -203,6 +206,9 @@ Format options: Include parentheses around a sole arrow function parameter. Defaults to avoid. --no-bracket-spacing Do not print spaces between brackets. + --end-of-line + Which end of line characters to apply. + Defaults to auto. --html-whitespace-sensitivity How to handle whitespaces in HTML. Defaults to css. diff --git a/tests_integration/__tests__/__snapshots__/help-options.js.snap b/tests_integration/__tests__/__snapshots__/help-options.js.snap index e45689f10..fbf0d2357 100644 --- a/tests_integration/__tests__/__snapshots__/help-options.js.snap +++ b/tests_integration/__tests__/__snapshots__/help-options.js.snap @@ -102,6 +102,27 @@ Default: true exports[`show detailed usage with --help editorconfig (write) 1`] = `Array []`; +exports[`show detailed usage with --help end-of-line (stderr) 1`] = `""`; + +exports[`show detailed usage with --help end-of-line (stdout) 1`] = ` +"--end-of-line + + Which end of line characters to apply. + +Valid options: + + auto Maintain existing + (mixed values within one file are normalised by looking at what's used after the first line) + lf Line Feed only (\\\\n), common on Linux and macOS as well as inside git repos + crlf Carriage Return + Line Feed characters (\\\\r\\\\n), common on Windows + cr Carriage Return character only (\\\\r), used very rarely + +Default: auto +" +`; + +exports[`show detailed usage with --help end-of-line (write) 1`] = `Array []`; + exports[`show detailed usage with --help file-info (stderr) 1`] = `""`; exports[`show detailed usage with --help file-info (stdout) 1`] = ` diff --git a/tests_integration/__tests__/__snapshots__/plugin-options.js.snap b/tests_integration/__tests__/__snapshots__/plugin-options.js.snap index ce7df73e4..1185ec22c 100644 --- a/tests_integration/__tests__/__snapshots__/plugin-options.js.snap +++ b/tests_integration/__tests__/__snapshots__/plugin-options.js.snap @@ -5,12 +5,12 @@ exports[` 1`] = ` - First value + Second value -@@ -12,10 +12,12 @@ - - --arrow-parens - Include parentheses around a sole arrow function parameter. +@@ -15,10 +15,12 @@ Defaults to avoid. --no-bracket-spacing Do not print spaces between brackets. + --end-of-line + Which end of line characters to apply. + Defaults to auto. + --foo-option foo description + Defaults to bar. --html-whitespace-sensitivity diff --git a/tests_integration/__tests__/__snapshots__/schema.js.snap b/tests_integration/__tests__/__snapshots__/schema.js.snap index b2afcf6a6..9b08104b1 100644 --- a/tests_integration/__tests__/__snapshots__/schema.js.snap +++ b/tests_integration/__tests__/__snapshots__/schema.js.snap @@ -43,6 +43,37 @@ Object { This option cannot be used with --range-start and --range-end.", "type": "integer", }, + "endOfLine": Object { + "default": "auto", + "description": "Which end of line characters to apply.", + "oneOf": Array [ + Object { + "description": "Maintain existing +(mixed values within one file are normalised by looking at what's used after the first line)", + "enum": Array [ + "auto", + ], + }, + Object { + "description": "Line Feed only (\\\\n), common on Linux and macOS as well as inside git repos", + "enum": Array [ + "lf", + ], + }, + Object { + "description": "Carriage Return + Line Feed characters (\\\\r\\\\n), common on Windows", + "enum": Array [ + "crlf", + ], + }, + Object { + "description": "Carriage Return character only (\\\\r), used very rarely", + "enum": Array [ + "cr", + ], + }, + ], + }, "filepath": Object { "default": undefined, "description": "Specify the input filepath. This will be used to do parser inference.", diff --git a/tests_integration/__tests__/__snapshots__/support-info.js.snap b/tests_integration/__tests__/__snapshots__/support-info.js.snap index 125e06ccc..afa4ed067 100644 --- a/tests_integration/__tests__/__snapshots__/support-info.js.snap +++ b/tests_integration/__tests__/__snapshots__/support-info.js.snap @@ -489,8 +489,22 @@ exports[`API getSupportInfo() with version 1.8.2 -> undefined 1`] = ` \\"type\\": \\"boolean\\", }, \\"cursorOffset\\": Object { -@@ -56,33 +85,61 @@ +@@ -52,37 +81,75 @@ + \\"start\\": -1, + \\"step\\": 1, + }, + \\"type\\": \\"int\\", }, ++ \\"endOfLine\\": Object { ++ \\"choices\\": Array [ ++ \\"auto\\", ++ \\"lf\\", ++ \\"crlf\\", ++ \\"cr\\", ++ ], ++ \\"default\\": \\"auto\\", ++ \\"type\\": \\"choice\\", ++ }, \\"filepath\\": Object { \\"default\\": undefined, \\"type\\": \\"path\\", @@ -552,7 +566,7 @@ exports[`API getSupportInfo() with version 1.8.2 -> undefined 1`] = ` \\"range\\": Object { \\"end\\": Infinity, \\"start\\": 0, -@@ -90,14 +147,15 @@ +@@ -90,14 +157,15 @@ }, \\"type\\": \\"int\\", }, @@ -980,6 +994,33 @@ exports[`CLI --support-info (stdout) 1`] = ` \\"since\\": \\"1.4.0\\", \\"type\\": \\"int\\" }, + { + \\"category\\": \\"Global\\", + \\"choices\\": [ + { + \\"description\\": \\"Maintain existing\\\\n(mixed values within one file are normalised by looking at what's used after the first line)\\", + \\"value\\": \\"auto\\" + }, + { + \\"description\\": \\"Line Feed only (\\\\\\\\n), common on Linux and macOS as well as inside git repos\\", + \\"value\\": \\"lf\\" + }, + { + \\"description\\": \\"Carriage Return + Line Feed characters (\\\\\\\\r\\\\\\\\n), common on Windows\\", + \\"value\\": \\"crlf\\" + }, + { + \\"description\\": \\"Carriage Return character only (\\\\\\\\r), used very rarely\\", + \\"value\\": \\"cr\\" + } + ], + \\"default\\": \\"auto\\", + \\"description\\": \\"Which end of line characters to apply.\\", + \\"name\\": \\"endOfLine\\", + \\"pluginDefaults\\": {}, + \\"since\\": \\"1.15.0\\", + \\"type\\": \\"choice\\" + }, { \\"category\\": \\"Special\\", \\"description\\": \\"Specify the input filepath. This will be used to do parser inference.\\", diff --git a/tests_integration/__tests__/__snapshots__/with-config-precedence.js.snap b/tests_integration/__tests__/__snapshots__/with-config-precedence.js.snap index c1a87149b..3ff3063e9 100644 --- a/tests_integration/__tests__/__snapshots__/with-config-precedence.js.snap +++ b/tests_integration/__tests__/__snapshots__/with-config-precedence.js.snap @@ -80,7 +80,17 @@ exports[`CLI overrides take lower precedence with --config-precedence file-overr exports[`CLI overrides take precedence with --config-precedence cli-override (stderr) 1`] = `""`; exports[`CLI overrides take precedence with --config-precedence cli-override (stdout) 1`] = ` -"function f() { +"function f() {/*CR*/ console.log(/*CR*/ \\"line endings should be CR\\"/*CR*/ )/*CR*/}/*CR*/function f() {/*CR*/ + console.log(/*CR*/ + \\"line endings should be CRLF\\"/*CR*/ + )/*CR*/ +}/*CR*/ +function f() { + console.log( + \\"line endings should be LF\\" + ) +} +function f() { console.log( \\"should have tab width 8\\" ) @@ -167,7 +177,17 @@ exports[`CLI overrides take precedence with --config-precedence cli-override (wr exports[`CLI overrides take precedence without --config-precedence (stderr) 1`] = `""`; exports[`CLI overrides take precedence without --config-precedence (stdout) 1`] = ` -"function f() { +"function f() {/*CR*/ console.log(/*CR*/ \\"line endings should be CR\\"/*CR*/ )/*CR*/}/*CR*/function f() {/*CR*/ + console.log(/*CR*/ + \\"line endings should be CRLF\\"/*CR*/ + )/*CR*/ +}/*CR*/ +function f() { + console.log( + \\"line endings should be LF\\" + ) +} +function f() { console.log( \\"should have tab width 8\\" ) diff --git a/tests_integration/cli/config/editorconfig/.editorconfig b/tests_integration/cli/config/editorconfig/.editorconfig index 42984e9d6..15ea263a8 100644 --- a/tests_integration/cli/config/editorconfig/.editorconfig +++ b/tests_integration/cli/config/editorconfig/.editorconfig @@ -13,3 +13,13 @@ indent_size = 2 [lib/indent_size=tab.js] indent_size = tab + +# End of line (--eol opition) +[eol/cr.js] +end_of_line = cr + +[eol/crlf.js] +end_of_line = crlf + +[eol/lf.js] +end_of_line = lf diff --git a/tests_integration/cli/config/editorconfig/eol/cr.js b/tests_integration/cli/config/editorconfig/eol/cr.js new file mode 100644 index 000000000..6d366df61 --- /dev/null +++ b/tests_integration/cli/config/editorconfig/eol/cr.js @@ -0,0 +1,3 @@ +function f() { + console.log("line endings should be CR") +} diff --git a/tests_integration/cli/config/editorconfig/eol/crlf.js b/tests_integration/cli/config/editorconfig/eol/crlf.js new file mode 100644 index 000000000..8b25e5fd3 --- /dev/null +++ b/tests_integration/cli/config/editorconfig/eol/crlf.js @@ -0,0 +1,3 @@ +function f() { + console.log("line endings should be CRLF") +} diff --git a/tests_integration/cli/config/editorconfig/eol/lf.js b/tests_integration/cli/config/editorconfig/eol/lf.js new file mode 100644 index 000000000..d17f615db --- /dev/null +++ b/tests_integration/cli/config/editorconfig/eol/lf.js @@ -0,0 +1,3 @@ +function f() { + console.log("line endings should be LF") +} diff --git a/tests_integration/runPrettier.js b/tests_integration/runPrettier.js index 0bb050ea4..b5dd75c62 100644 --- a/tests_integration/runPrettier.js +++ b/tests_integration/runPrettier.js @@ -109,8 +109,10 @@ function runPrettier(dir, args, options) { Object.keys(result).forEach(name => { test(`(${name})`, () => { const value = + // \r is trimmed from jest snapshots by default; + // manually replacing this character with /*CR*/ to test its true presence typeof result[name] === "string" - ? stripAnsi(result[name]) + ? stripAnsi(result[name]).replace(/\r/g, "/*CR*/") : result[name]; if (name in testOptions) { if (name === "status" && testOptions[name] === "non-zero") { diff --git a/yarn.lock b/yarn.lock index 557f05f11..e3a1dc498 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1815,9 +1815,9 @@ ecc-jsbn@~0.1.1: dependencies: jsbn "~0.1.0" -editorconfig-to-prettier@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/editorconfig-to-prettier/-/editorconfig-to-prettier-0.0.6.tgz#d79bc1a2574e0a94315dd43da3275f92f9331b27" +editorconfig-to-prettier@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/editorconfig-to-prettier/-/editorconfig-to-prettier-0.1.0.tgz#c31d2ceea2ef922835c53f6ca0e5ba2930b8940d" editorconfig@0.15.2: version "0.15.2"