Repository: jlongster/prettier (js)

Issue:
Add escape hatch
`prettier` at this point is still outputting invalid JavaScript or badly formatted output in many cases. This will go down as time goes but in the meantime, it would be great to be able to disable it for just an expression.

Proposal:

```js
// prettier-ignore-next-block
function a() { 
  iCanDoWhateverIdent
    (a, b,); }
```

and prettier will keep the next AST node as is.

Pull request description:
[RFC] Introduce prettier-ignore
This was surprisingly easy to write!

`prettier-ignore` will leave the expression the comment is attached to printed as it was before.

Fixes #120

Patch:
diff --git a/src/printer.js b/src/printer.js
index 7d9080080..bca622e86 100644
--- a/src/printer.js
+++ b/src/printer.js
@@ -46,6 +46,16 @@ function genericPrint(path, options, printPath) {
     return linesWithoutParens;
   }
 
+  // Escape hatch
+  if (node.comments &&
+      node.comments.length > 0 &&
+      node.comments[0].value.trim() === 'prettier-ignore') {
+    return options.originalText.slice(
+      util.locStart(node),
+      util.locEnd(node)
+    );
+  }
+
   if (
     node.decorators &&
       node.decorators.length > 0 &&


Test patch:
diff --git a/tests/ignore/__snapshots__/jsfmt.spec.js.snap b/tests/ignore/__snapshots__/jsfmt.spec.js.snap
new file mode 100644
index 000000000..86da34b2f
--- /dev/null
+++ b/tests/ignore/__snapshots__/jsfmt.spec.js.snap
@@ -0,0 +1,103 @@
+exports[`test ignore.js 1`] = `
+"function a() {
+  // prettier-ignore
+  var fnString =
+    \'\"\' + this.USE + \' \' + this.STRICT + \'\";\\n\' +
+    this.filterPrefix() +
+    \'var fn=\' + this.generateFunction(\'fn\', \'s,l,a,i\') +
+    extra +
+    this.watchFns() +
+    \'return fn;\';
+
+  // prettier-ignore
+  const identity = Matrix.create(
+    1, 0, 0,
+    0, 1, 0,
+    0, 0, 0
+  );
+
+  // prettier-ignore
+  console.error(
+    \'In order to use \' + prompt + \', you need to configure a \' +
+    \'few environment variables to be able to commit to the \' +
+    \'repository. Follow those steps to get you setup:\\n\' +
+    \'\\n\' +
+    \'Go to https://github.com/settings/tokens/new\\n\' +
+    \' - Fill \"Token description\" with \"\' + prompt + \' for \' +
+      repoSlug + \'\"\\n\' +
+    \' - Check \"public_repo\"\\n\' +
+    \' - Press \"Generate Token\"\\n\' +
+    \'\\n\' +
+    \'In a different tab, go to https://travis-ci.org/\' +
+      repoSlug + \'/settings\\n\' +
+    \' - Make sure \"Build only if .travis.yml is present\" is ON\\n\' +
+    \' - Fill \"Name\" with \"GITHUB_USER\" and \"Value\" with the name of the \' +
+      \'account you generated the token with. Press \"Add\"\\n\' +
+    \'\\n\' +
+    \'Once this is done, commit anything to the repository to restart \' +
+      \'Travis and it should work :)\'
+  );
+
+  // Incorrectly indented on purpose
+      function f</* prettier-ignore */ T    :    B>(
+        a : Array  <   number   > // prettier-ignore
+      ) {
+
+        call(
+          f(         1          )
+          // prettier-ignore
+        )
+      }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+function a() {
+  // prettier-ignore
+  var fnString =
+    \'\"\' + this.USE + \' \' + this.STRICT + \'\";\\n\' +
+    this.filterPrefix() +
+    \'var fn=\' + this.generateFunction(\'fn\', \'s,l,a,i\') +
+    extra +
+    this.watchFns() +
+    \'return fn;\';
+
+  // prettier-ignore
+  const identity = Matrix.create(
+    1, 0, 0,
+    0, 1, 0,
+    0, 0, 0
+  );
+
+  // prettier-ignore
+  console.error(
+    \'In order to use \' + prompt + \', you need to configure a \' +
+    \'few environment variables to be able to commit to the \' +
+    \'repository. Follow those steps to get you setup:\\n\' +
+    \'\\n\' +
+    \'Go to https://github.com/settings/tokens/new\\n\' +
+    \' - Fill \"Token description\" with \"\' + prompt + \' for \' +
+      repoSlug + \'\"\\n\' +
+    \' - Check \"public_repo\"\\n\' +
+    \' - Press \"Generate Token\"\\n\' +
+    \'\\n\' +
+    \'In a different tab, go to https://travis-ci.org/\' +
+      repoSlug + \'/settings\\n\' +
+    \' - Make sure \"Build only if .travis.yml is present\" is ON\\n\' +
+    \' - Fill \"Name\" with \"GITHUB_USER\" and \"Value\" with the name of the \' +
+      \'account you generated the token with. Press \"Add\"\\n\' +
+    \'\\n\' +
+    \'Once this is done, commit anything to the repository to restart \' +
+      \'Travis and it should work :)\'
+  );
+
+  // Incorrectly indented on purpose
+  function f</* prettier-ignore */ T    :    B>(
+    a : Array  <   number   > // prettier-ignore
+  ) {
+    call(
+      f(         1          )
+      // prettier-ignore
+    );
+  }
+}
+"
+`;
diff --git a/tests/ignore/ignore.js b/tests/ignore/ignore.js
new file mode 100644
index 000000000..737a0688c
--- /dev/null
+++ b/tests/ignore/ignore.js
@@ -0,0 +1,50 @@
+function a() {
+  // prettier-ignore
+  var fnString =
+    '"' + this.USE + ' ' + this.STRICT + '";\n' +
+    this.filterPrefix() +
+    'var fn=' + this.generateFunction('fn', 's,l,a,i') +
+    extra +
+    this.watchFns() +
+    'return fn;';
+
+  // prettier-ignore
+  const identity = Matrix.create(
+    1, 0, 0,
+    0, 1, 0,
+    0, 0, 0
+  );
+
+  // prettier-ignore
+  console.error(
+    'In order to use ' + prompt + ', you need to configure a ' +
+    'few environment variables to be able to commit to the ' +
+    'repository. Follow those steps to get you setup:\n' +
+    '\n' +
+    'Go to https://github.com/settings/tokens/new\n' +
+    ' - Fill "Token description" with "' + prompt + ' for ' +
+      repoSlug + '"\n' +
+    ' - Check "public_repo"\n' +
+    ' - Press "Generate Token"\n' +
+    '\n' +
+    'In a different tab, go to https://travis-ci.org/' +
+      repoSlug + '/settings\n' +
+    ' - Make sure "Build only if .travis.yml is present" is ON\n' +
+    ' - Fill "Name" with "GITHUB_USER" and "Value" with the name of the ' +
+      'account you generated the token with. Press "Add"\n' +
+    '\n' +
+    'Once this is done, commit anything to the repository to restart ' +
+      'Travis and it should work :)'
+  );
+
+  // Incorrectly indented on purpose
+      function f</* prettier-ignore */ T    :    B>(
+        a : Array  <   number   > // prettier-ignore
+      ) {
+
+        call(
+          f(         1          )
+          // prettier-ignore
+        )
+      }
+}
diff --git a/tests/ignore/jsfmt.spec.js b/tests/ignore/jsfmt.spec.js
new file mode 100644
index 000000000..989047bcc
--- /dev/null
+++ b/tests/ignore/jsfmt.spec.js
@@ -0,0 +1,1 @@
+run_spec(__dirname);