prettier/bin/prettier.js

490 lines
14 KiB
JavaScript
Raw Normal View History

2016-11-29 20:14:10 +03:00
#!/usr/bin/env node
2017-01-10 20:18:22 +03:00
"use strict";
2017-01-28 18:50:22 +03:00
const chalk = require("chalk");
const dashify = require("dashify");
2016-11-29 20:14:10 +03:00
const fs = require("fs");
const getStream = require("get-stream");
const globby = require("globby");
const minimist = require("minimist");
const path = require("path");
const readline = require("readline");
const ignore = require("ignore");
2016-11-29 20:14:10 +03:00
const prettier = eval("require")("../index");
const cleanAST = require("../src/clean-ast").cleanAST;
const resolver = require("../src/resolve-config");
const args = process.argv.slice(2);
const booleanOptionNames = [
"use-tabs",
"semi",
"single-quote",
"bracket-spacing",
"jsx-bracket-same-line",
// Deprecated in 0.0.10
"flow-parser"
];
const stringOptionNames = [
"print-width",
"tab-width",
"parser",
"trailing-comma"
];
const argv = minimist(args, {
2017-01-13 23:03:53 +03:00
boolean: [
"write",
"stdin",
// The supports-color package (a sub sub dependency) looks directly at
// `process.argv` for `--no-color` and such-like options. The reason it is
// listed here is to avoid "Ignored unknown option: --no-color" warnings.
// See https://github.com/chalk/supports-color/#info for more information.
"color",
"list-different",
"help",
"version",
"debug-print-doc",
"debug-check",
"with-node-modules"
].concat(booleanOptionNames),
string: [
Add `cursorOffset` option for cursor translation (#1637) * Add `formatWithCursor` API with `cursorOffset` option This addresses https://github.com/prettier/prettier/issues/93 by adding a new option, `cursorOffset`, that tells prettier to determine the location of the cursor after the code has been formatted. This is accessible through the API via a new function, `formatWithCursor`, which returns a `{formatted: string, cursorOffset: ?number}`. Here's a usage example: ```js require("prettier").formatWithCursor(" 1", { cursorOffset: 2 }); // -> { formatted: '1;\n', cursorOffset: 1 } ``` * Add `--cursor-offset` CLI option It will print out the offset instead of the formatted output. This makes it easier to test. For example: echo ' 1' | prettier --stdin --cursor-offset 2 # prints 1 * Add basic test of cursor translation * Document `cursorOffset` option and `formatWithCursor()` * Print translated cursor offset to stderr when --cursor-offset is given This lets us continue to print the formatted code, while also communicating the updated cursor position. See https://github.com/prettier/prettier/pull/1637#discussion_r119735496 * doc-print cursor placeholder in comments.printComments() See https://github.com/prettier/prettier/pull/1637#discussion_r119735149 * Compare array index to -1 instead of >= 0 to determine element presence See https://github.com/prettier/prettier/pull/1637#discussion_r119736623 * Return {formatted, cursor} from printDocToString() instead of mutating options See https://github.com/prettier/prettier/pull/1637#discussion_r119737354
2017-06-02 01:52:29 +03:00
"cursor-offset",
"range-start",
"range-end",
"stdin-filepath",
"config",
"find-config-path",
"ignore-path"
].concat(stringOptionNames),
default: {
color: true,
"ignore-path": ".prettierignore"
},
alias: {
help: "h",
version: "v",
"list-different": "l"
},
unknown: param => {
if (param.startsWith("-")) {
console.warn("Ignored unknown option: " + param + "\n");
return false;
}
}
});
if (argv["version"]) {
2017-01-22 03:42:13 +03:00
console.log(prettier.version);
process.exit(0);
}
const filepatterns = argv["_"];
2017-01-10 23:45:04 +03:00
const write = argv["write"];
2017-02-23 20:57:51 +03:00
const stdin = argv["stdin"] || (!filepatterns.length && !process.stdin.isTTY);
const ignoreNodeModules = argv["with-node-modules"] === false;
const ignoreNodeModulesGlobs = ["!**/node_modules/**", "!./node_modules/**"];
const ignorePath = argv["ignore-path"];
const globOptions = {
dot: true
};
2016-11-29 20:14:10 +03:00
if (write && argv["debug-check"]) {
console.error("Cannot use --write and --debug-check together.");
process.exit(1);
}
if (argv["find-config-path"] && filepatterns.length) {
console.error("Cannot use --find-config-path with multiple files");
process.exit(1);
}
function getOptionsForFile(filePath) {
const options =
argv["config"] === false ? null : resolver.resolveConfig.sync(filePath);
try {
const parsedArgs = minimist(args, {
boolean: booleanOptionNames,
string: stringOptionNames,
default: Object.assign(
{
semi: true,
"bracket-spacing": true,
parser: "babylon"
},
dashifyObject(options)
)
});
return getOptions(Object.assign({}, argv, parsedArgs));
} catch (error) {
console.error("Invalid configuration file:", error.toString());
process.exit(2);
}
}
function getOptions(argv) {
return {
cursorOffset: getIntOption(argv, "cursor-offset"),
rangeStart: getIntOption(argv, "range-start"),
rangeEnd: getIntOption(argv, "range-end"),
useTabs: argv["use-tabs"],
semi: argv["semi"],
printWidth: getIntOption(argv, "print-width"),
tabWidth: getIntOption(argv, "tab-width"),
bracketSpacing: argv["bracket-spacing"],
singleQuote: argv["single-quote"],
jsxBracketSameLine: argv["jsx-bracket-same-line"],
filepath: argv["stdin-filepath"],
trailingComma: getTrailingComma(argv),
parser: getParserOption(argv)
};
}
function getParserOption(argv) {
const value = argv.parser;
if (value === undefined) {
return value;
}
// For backward compatibility. Deprecated in 0.0.10
if (argv["flow-parser"]) {
console.warn("`--flow-parser` is deprecated. Use `--parser flow` instead.");
return "flow";
}
return value;
}
function getIntOption(argv, optionName) {
const value = argv[optionName];
if (value === undefined) {
return value;
}
if (/^\d+$/.test(value)) {
return Number(value);
}
console.error(
"Invalid --" +
optionName +
" value. Expected an integer, but received: " +
JSON.stringify(value)
);
process.exit(1);
}
function getTrailingComma(argv) {
switch (argv["trailing-comma"]) {
case undefined:
case "none":
return "none";
case "":
2017-02-23 20:57:51 +03:00
console.warn(
"Warning: `--trailing-comma` was used without an argument. This is deprecated. " +
'Specify "none", "es5", or "all".'
);
return "es5";
case "es5":
return "es5";
case "all":
return "all";
default:
throw new Error("Invalid option for --trailing-comma");
}
}
function dashifyObject(object) {
return Object.keys(object || {}).reduce((output, key) => {
output[dashify(key)] = object[key];
return output;
}, {});
}
function diff(a, b) {
return require("diff").createTwoFilesPatch("", "", a, b, "", "", {
context: 2
});
}
function format(input, opt) {
if (argv["debug-print-doc"]) {
const doc = prettier.__debug.printToDoc(input, opt);
return { formatted: prettier.__debug.formatDoc(doc) };
}
if (argv["debug-check"]) {
const pp = prettier.format(input, opt);
const pppp = prettier.format(pp, opt);
if (pp !== pppp) {
throw "prettier(input) !== prettier(prettier(input))\n" + diff(pp, pppp);
} else {
const ast = cleanAST(prettier.__debug.parse(input, opt));
const past = cleanAST(prettier.__debug.parse(pp, opt));
if (ast !== past) {
const MAX_AST_SIZE = 2097152; // 2MB
const astDiff =
ast.length > MAX_AST_SIZE || past.length > MAX_AST_SIZE
? "AST diff too large to render"
: diff(ast, past);
throw "ast(input) !== ast(prettier(input))\n" +
astDiff +
"\n" +
diff(input, pp);
}
}
return { formatted: opt.filepath || "(stdin)\n" };
}
Add `cursorOffset` option for cursor translation (#1637) * Add `formatWithCursor` API with `cursorOffset` option This addresses https://github.com/prettier/prettier/issues/93 by adding a new option, `cursorOffset`, that tells prettier to determine the location of the cursor after the code has been formatted. This is accessible through the API via a new function, `formatWithCursor`, which returns a `{formatted: string, cursorOffset: ?number}`. Here's a usage example: ```js require("prettier").formatWithCursor(" 1", { cursorOffset: 2 }); // -> { formatted: '1;\n', cursorOffset: 1 } ``` * Add `--cursor-offset` CLI option It will print out the offset instead of the formatted output. This makes it easier to test. For example: echo ' 1' | prettier --stdin --cursor-offset 2 # prints 1 * Add basic test of cursor translation * Document `cursorOffset` option and `formatWithCursor()` * Print translated cursor offset to stderr when --cursor-offset is given This lets us continue to print the formatted code, while also communicating the updated cursor position. See https://github.com/prettier/prettier/pull/1637#discussion_r119735496 * doc-print cursor placeholder in comments.printComments() See https://github.com/prettier/prettier/pull/1637#discussion_r119735149 * Compare array index to -1 instead of >= 0 to determine element presence See https://github.com/prettier/prettier/pull/1637#discussion_r119736623 * Return {formatted, cursor} from printDocToString() instead of mutating options See https://github.com/prettier/prettier/pull/1637#discussion_r119737354
2017-06-02 01:52:29 +03:00
return prettier.formatWithCursor(input, opt);
2017-01-11 18:57:16 +03:00
}
2017-01-10 07:03:35 +03:00
function handleError(filename, e) {
const isParseError = Boolean(e && e.loc);
const isValidationError = /Validation Error/.test(e && e.message);
// For parse errors and validation errors, we only want to show the error
// message formatted in a nice way. `String(e)` takes care of that. Other
// (unexpected) errors are passed as-is as a separate argument to
// `console.error`. That includes the stack trace (if any), and shows a nice
// `util.inspect` of throws things that aren't `Error` objects. (The Flow
// parser has mistakenly thrown arrays sometimes.)
if (isParseError) {
console.error(filename + ": " + String(e));
} else if (isValidationError) {
console.error(String(e));
// If validation fails for one file, it will fail for all of them.
process.exit(1);
} else {
2017-05-28 23:54:54 +03:00
console.error(filename + ":", e.stack || e);
}
// Don't exit the process if one file failed
process.exitCode = 2;
}
if (
argv["help"] ||
(!filepatterns.length && !stdin && !argv["find-config-path"])
) {
console.log(
"Usage: prettier [opts] [filename ...]\n\n" +
"Available options:\n" +
" --write Edit the file in-place. (Beware!)\n" +
" --list-different or -l Print filenames of files that are different from Prettier formatting.\n" +
" --config Path to a prettier configuration file (.prettierrc, package.json, prettier.config.js).\n" +
" --no-config Do not look for a configuration file.\n" +
" --find-config-path <path>\n" +
" Finds and prints the path to a configuration file for a given input file.\n" +
" --ignore-path <path> Path to a file containing patterns that describe files to ignore.\n" +
" Defaults to ./.prettierignore.\n" +
" --stdin Read input from stdin.\n" +
" --stdin-filepath Path to the file used to read from stdin.\n" +
" --print-width <int> Specify the length of line that the printer will wrap on. Defaults to 80.\n" +
" --tab-width <int> Specify the number of spaces per indentation-level. Defaults to 2.\n" +
" --use-tabs Indent lines with tabs instead of spaces.\n" +
" --no-semi Do not print semicolons, except at the beginning of lines which may need them.\n" +
" --single-quote Use single quotes instead of double quotes.\n" +
" --no-bracket-spacing Do not print spaces between brackets.\n" +
" --jsx-bracket-same-line Put > on the last line instead of at a new line.\n" +
" --trailing-comma <none|es5|all>\n" +
" Print trailing commas wherever possible when multi-line. Defaults to none.\n" +
" --parser <flow|babylon|typescript|postcss|json|graphql>\n" +
" Specify which parse to use. Defaults to babylon.\n" +
Add `cursorOffset` option for cursor translation (#1637) * Add `formatWithCursor` API with `cursorOffset` option This addresses https://github.com/prettier/prettier/issues/93 by adding a new option, `cursorOffset`, that tells prettier to determine the location of the cursor after the code has been formatted. This is accessible through the API via a new function, `formatWithCursor`, which returns a `{formatted: string, cursorOffset: ?number}`. Here's a usage example: ```js require("prettier").formatWithCursor(" 1", { cursorOffset: 2 }); // -> { formatted: '1;\n', cursorOffset: 1 } ``` * Add `--cursor-offset` CLI option It will print out the offset instead of the formatted output. This makes it easier to test. For example: echo ' 1' | prettier --stdin --cursor-offset 2 # prints 1 * Add basic test of cursor translation * Document `cursorOffset` option and `formatWithCursor()` * Print translated cursor offset to stderr when --cursor-offset is given This lets us continue to print the formatted code, while also communicating the updated cursor position. See https://github.com/prettier/prettier/pull/1637#discussion_r119735496 * doc-print cursor placeholder in comments.printComments() See https://github.com/prettier/prettier/pull/1637#discussion_r119735149 * Compare array index to -1 instead of >= 0 to determine element presence See https://github.com/prettier/prettier/pull/1637#discussion_r119736623 * Return {formatted, cursor} from printDocToString() instead of mutating options See https://github.com/prettier/prettier/pull/1637#discussion_r119737354
2017-06-02 01:52:29 +03:00
" --cursor-offset <int> Print (to stderr) where a cursor at the given position would move to after formatting.\n" +
" This option cannot be used with --range-start and --range-end\n" +
Find nearest node when formatting range (#1659) * Move range extension code into helper functions * Add findNodeByOffset() helper This was adapted from https://github.com/prettier/prettier/pull/1637/commits/cbc1929c64db558b4e444500bca3d2ce1d550359 * Test extending formatted range to entire node * Fix extending formatted range to entire node * Fix style errors * Add run_file test function This makes it possible to use different options on a per-file basis, which is useful for things like range formatting tests. * Test extending the format range to nearest parseable node This means you can select the range of a `catch` clause, attempt to format it, and have the `try` formatted as well, rather than throwing an error. * Fix extending the format range to nearest parseable node This means you can select the range of a `catch` clause, attempt to format it, and have the `try` formatted as well, rather than throwing an error. * Test that external indentation is left alone when formatting a range * Preserve external indentation when formatting a range * Dedupe range formatting traversal callbacks * Simplify range formatting traversal using ast-types See https://github.com/prettier/prettier/pull/1659#issuecomment-302974798 * Make range formatting traversal more efficient There's less unnecessary parsing now. * Fix style errors * Add test where range expanding fails * Fix test where range expanding fails This makes sure that the range contains the entirety of the nodes containing each of the range's endpoints. * Add test for expanding range to beginning of line * Pass test for expanding range to beginning of line This makes it so that indentation before the range is added to the formatted range. * Don't parse/stringify AST to detect pre-range indentation See https://github.com/prettier/prettier/pull/1659#discussion_r117790671 * When formatting a range, find closest statement rather than parsing The `isStatement` implementation came from `docs/prettier.min.js`. See https://github.com/prettier/prettier/pull/1659#issuecomment-303154770 * Add test for range-formatting a FunctionDeclaration's argument object * Include FunctionDeclaration when searching for nearest node to range-format From the spec, a Program is a series of SourceElements, each of which is either a Statement or a FunctionDeclaration. See https://www.ecma-international.org/ecma-262/5.1/#sec-A.5 * Remove unnecessary try-catch See https://github.com/prettier/prettier/pull/1659#discussion_r117810096 * Add tests with multiple statements See https://github.com/prettier/prettier/pull/1659#discussion_r117810753 * Remove unnecessary arguments from findNodeByOffset() * Contract format range to ensure it starts/ends on nodes * Specify test ranges in the fixtures See https://github.com/prettier/prettier/pull/1659#discussion_r117811186 * Remove unnecessary comments from range fixtures * Remove run_file test function It's no longer used. This essentially reverts 8241216e68f2e0da997a4f558b03658d642c89a2 * Update range formatting docs Clarify that the range expands to the nearest statement, and not to the end of the line. * Don't overwrite test options when detecting range Now that multiple files share the same object again, we shouldn't be re-assigning to it. * Reuse already-read fixtures for AST_COMPARE=1 tests * Remove `run_file` global from test eslintrc * Undo package.json churn `yarn` reformatted it before, but the whitespace visually sets off the comment, so let's put it back how it was before. See https://github.com/prettier/prettier/pull/1659#discussion_r117864655 * Remove misleading comments from isSourceElement See https://github.com/prettier/prettier/pull/1659#discussion_r117865196 * Loop backwards through string instead of reversing it See https://github.com/prettier/prettier/pull/1659#discussion_r117865759 * Don't recompute indent string when formatting range See https://github.com/prettier/prettier/pull/1659#discussion_r117867268 * Rename findNodeByOffset to findNodeAtOffset "Find x by y" is the common usage for finding an `x` by a key `y`. However, since "by" has positional meaning, let's use "at" instead. See https://github.com/prettier/prettier/pull/1659#discussion_r117865121 * Always trimRight() in formatRange and explain why See https://github.com/prettier/prettier/pull/1659#discussion_r117864635 * Test formatting a range that crosses AST levels See https://github.com/prettier/prettier/pull/1659#issuecomment-303243688 * Fix formatting a range that crosses AST levels See https://github.com/prettier/prettier/pull/1659#issuecomment-303243688 * Remove unnecessary try-catch See https://github.com/prettier/prettier/pull/1659/files/e52db5e9f9ec4af599f658da03739e206dd4578c#r117878763 * Add test demonstrating range formatting indent detection * Detect alignment from text on line before range, but don't reformat it This avoids reformatting non-indentation that happens to precede the range on the same line, while still correctly indenting the range based on it. See https://github.com/prettier/prettier/pull/1659#discussion_r117881430
2017-05-23 17:43:58 +03:00
" --range-start <int> Format code starting at a given character offset.\n" +
" The range will extend backwards to the start of the first line containing the selected statement.\n" +
Add `cursorOffset` option for cursor translation (#1637) * Add `formatWithCursor` API with `cursorOffset` option This addresses https://github.com/prettier/prettier/issues/93 by adding a new option, `cursorOffset`, that tells prettier to determine the location of the cursor after the code has been formatted. This is accessible through the API via a new function, `formatWithCursor`, which returns a `{formatted: string, cursorOffset: ?number}`. Here's a usage example: ```js require("prettier").formatWithCursor(" 1", { cursorOffset: 2 }); // -> { formatted: '1;\n', cursorOffset: 1 } ``` * Add `--cursor-offset` CLI option It will print out the offset instead of the formatted output. This makes it easier to test. For example: echo ' 1' | prettier --stdin --cursor-offset 2 # prints 1 * Add basic test of cursor translation * Document `cursorOffset` option and `formatWithCursor()` * Print translated cursor offset to stderr when --cursor-offset is given This lets us continue to print the formatted code, while also communicating the updated cursor position. See https://github.com/prettier/prettier/pull/1637#discussion_r119735496 * doc-print cursor placeholder in comments.printComments() See https://github.com/prettier/prettier/pull/1637#discussion_r119735149 * Compare array index to -1 instead of >= 0 to determine element presence See https://github.com/prettier/prettier/pull/1637#discussion_r119736623 * Return {formatted, cursor} from printDocToString() instead of mutating options See https://github.com/prettier/prettier/pull/1637#discussion_r119737354
2017-06-02 01:52:29 +03:00
" This option cannot be used with --cursor-offset.\n" +
Find nearest node when formatting range (#1659) * Move range extension code into helper functions * Add findNodeByOffset() helper This was adapted from https://github.com/prettier/prettier/pull/1637/commits/cbc1929c64db558b4e444500bca3d2ce1d550359 * Test extending formatted range to entire node * Fix extending formatted range to entire node * Fix style errors * Add run_file test function This makes it possible to use different options on a per-file basis, which is useful for things like range formatting tests. * Test extending the format range to nearest parseable node This means you can select the range of a `catch` clause, attempt to format it, and have the `try` formatted as well, rather than throwing an error. * Fix extending the format range to nearest parseable node This means you can select the range of a `catch` clause, attempt to format it, and have the `try` formatted as well, rather than throwing an error. * Test that external indentation is left alone when formatting a range * Preserve external indentation when formatting a range * Dedupe range formatting traversal callbacks * Simplify range formatting traversal using ast-types See https://github.com/prettier/prettier/pull/1659#issuecomment-302974798 * Make range formatting traversal more efficient There's less unnecessary parsing now. * Fix style errors * Add test where range expanding fails * Fix test where range expanding fails This makes sure that the range contains the entirety of the nodes containing each of the range's endpoints. * Add test for expanding range to beginning of line * Pass test for expanding range to beginning of line This makes it so that indentation before the range is added to the formatted range. * Don't parse/stringify AST to detect pre-range indentation See https://github.com/prettier/prettier/pull/1659#discussion_r117790671 * When formatting a range, find closest statement rather than parsing The `isStatement` implementation came from `docs/prettier.min.js`. See https://github.com/prettier/prettier/pull/1659#issuecomment-303154770 * Add test for range-formatting a FunctionDeclaration's argument object * Include FunctionDeclaration when searching for nearest node to range-format From the spec, a Program is a series of SourceElements, each of which is either a Statement or a FunctionDeclaration. See https://www.ecma-international.org/ecma-262/5.1/#sec-A.5 * Remove unnecessary try-catch See https://github.com/prettier/prettier/pull/1659#discussion_r117810096 * Add tests with multiple statements See https://github.com/prettier/prettier/pull/1659#discussion_r117810753 * Remove unnecessary arguments from findNodeByOffset() * Contract format range to ensure it starts/ends on nodes * Specify test ranges in the fixtures See https://github.com/prettier/prettier/pull/1659#discussion_r117811186 * Remove unnecessary comments from range fixtures * Remove run_file test function It's no longer used. This essentially reverts 8241216e68f2e0da997a4f558b03658d642c89a2 * Update range formatting docs Clarify that the range expands to the nearest statement, and not to the end of the line. * Don't overwrite test options when detecting range Now that multiple files share the same object again, we shouldn't be re-assigning to it. * Reuse already-read fixtures for AST_COMPARE=1 tests * Remove `run_file` global from test eslintrc * Undo package.json churn `yarn` reformatted it before, but the whitespace visually sets off the comment, so let's put it back how it was before. See https://github.com/prettier/prettier/pull/1659#discussion_r117864655 * Remove misleading comments from isSourceElement See https://github.com/prettier/prettier/pull/1659#discussion_r117865196 * Loop backwards through string instead of reversing it See https://github.com/prettier/prettier/pull/1659#discussion_r117865759 * Don't recompute indent string when formatting range See https://github.com/prettier/prettier/pull/1659#discussion_r117867268 * Rename findNodeByOffset to findNodeAtOffset "Find x by y" is the common usage for finding an `x` by a key `y`. However, since "by" has positional meaning, let's use "at" instead. See https://github.com/prettier/prettier/pull/1659#discussion_r117865121 * Always trimRight() in formatRange and explain why See https://github.com/prettier/prettier/pull/1659#discussion_r117864635 * Test formatting a range that crosses AST levels See https://github.com/prettier/prettier/pull/1659#issuecomment-303243688 * Fix formatting a range that crosses AST levels See https://github.com/prettier/prettier/pull/1659#issuecomment-303243688 * Remove unnecessary try-catch See https://github.com/prettier/prettier/pull/1659/files/e52db5e9f9ec4af599f658da03739e206dd4578c#r117878763 * Add test demonstrating range formatting indent detection * Detect alignment from text on line before range, but don't reformat it This avoids reformatting non-indentation that happens to precede the range on the same line, while still correctly indenting the range based on it. See https://github.com/prettier/prettier/pull/1659#discussion_r117881430
2017-05-23 17:43:58 +03:00
" Defaults to 0.\n" +
" --range-end <int> Format code ending at a given character offset (exclusive).\n" +
" The range will extend forwards to the end of the selected statement.\n" +
Add `cursorOffset` option for cursor translation (#1637) * Add `formatWithCursor` API with `cursorOffset` option This addresses https://github.com/prettier/prettier/issues/93 by adding a new option, `cursorOffset`, that tells prettier to determine the location of the cursor after the code has been formatted. This is accessible through the API via a new function, `formatWithCursor`, which returns a `{formatted: string, cursorOffset: ?number}`. Here's a usage example: ```js require("prettier").formatWithCursor(" 1", { cursorOffset: 2 }); // -> { formatted: '1;\n', cursorOffset: 1 } ``` * Add `--cursor-offset` CLI option It will print out the offset instead of the formatted output. This makes it easier to test. For example: echo ' 1' | prettier --stdin --cursor-offset 2 # prints 1 * Add basic test of cursor translation * Document `cursorOffset` option and `formatWithCursor()` * Print translated cursor offset to stderr when --cursor-offset is given This lets us continue to print the formatted code, while also communicating the updated cursor position. See https://github.com/prettier/prettier/pull/1637#discussion_r119735496 * doc-print cursor placeholder in comments.printComments() See https://github.com/prettier/prettier/pull/1637#discussion_r119735149 * Compare array index to -1 instead of >= 0 to determine element presence See https://github.com/prettier/prettier/pull/1637#discussion_r119736623 * Return {formatted, cursor} from printDocToString() instead of mutating options See https://github.com/prettier/prettier/pull/1637#discussion_r119737354
2017-06-02 01:52:29 +03:00
" This option cannot be used with --cursor-offset.\n" +
Find nearest node when formatting range (#1659) * Move range extension code into helper functions * Add findNodeByOffset() helper This was adapted from https://github.com/prettier/prettier/pull/1637/commits/cbc1929c64db558b4e444500bca3d2ce1d550359 * Test extending formatted range to entire node * Fix extending formatted range to entire node * Fix style errors * Add run_file test function This makes it possible to use different options on a per-file basis, which is useful for things like range formatting tests. * Test extending the format range to nearest parseable node This means you can select the range of a `catch` clause, attempt to format it, and have the `try` formatted as well, rather than throwing an error. * Fix extending the format range to nearest parseable node This means you can select the range of a `catch` clause, attempt to format it, and have the `try` formatted as well, rather than throwing an error. * Test that external indentation is left alone when formatting a range * Preserve external indentation when formatting a range * Dedupe range formatting traversal callbacks * Simplify range formatting traversal using ast-types See https://github.com/prettier/prettier/pull/1659#issuecomment-302974798 * Make range formatting traversal more efficient There's less unnecessary parsing now. * Fix style errors * Add test where range expanding fails * Fix test where range expanding fails This makes sure that the range contains the entirety of the nodes containing each of the range's endpoints. * Add test for expanding range to beginning of line * Pass test for expanding range to beginning of line This makes it so that indentation before the range is added to the formatted range. * Don't parse/stringify AST to detect pre-range indentation See https://github.com/prettier/prettier/pull/1659#discussion_r117790671 * When formatting a range, find closest statement rather than parsing The `isStatement` implementation came from `docs/prettier.min.js`. See https://github.com/prettier/prettier/pull/1659#issuecomment-303154770 * Add test for range-formatting a FunctionDeclaration's argument object * Include FunctionDeclaration when searching for nearest node to range-format From the spec, a Program is a series of SourceElements, each of which is either a Statement or a FunctionDeclaration. See https://www.ecma-international.org/ecma-262/5.1/#sec-A.5 * Remove unnecessary try-catch See https://github.com/prettier/prettier/pull/1659#discussion_r117810096 * Add tests with multiple statements See https://github.com/prettier/prettier/pull/1659#discussion_r117810753 * Remove unnecessary arguments from findNodeByOffset() * Contract format range to ensure it starts/ends on nodes * Specify test ranges in the fixtures See https://github.com/prettier/prettier/pull/1659#discussion_r117811186 * Remove unnecessary comments from range fixtures * Remove run_file test function It's no longer used. This essentially reverts 8241216e68f2e0da997a4f558b03658d642c89a2 * Update range formatting docs Clarify that the range expands to the nearest statement, and not to the end of the line. * Don't overwrite test options when detecting range Now that multiple files share the same object again, we shouldn't be re-assigning to it. * Reuse already-read fixtures for AST_COMPARE=1 tests * Remove `run_file` global from test eslintrc * Undo package.json churn `yarn` reformatted it before, but the whitespace visually sets off the comment, so let's put it back how it was before. See https://github.com/prettier/prettier/pull/1659#discussion_r117864655 * Remove misleading comments from isSourceElement See https://github.com/prettier/prettier/pull/1659#discussion_r117865196 * Loop backwards through string instead of reversing it See https://github.com/prettier/prettier/pull/1659#discussion_r117865759 * Don't recompute indent string when formatting range See https://github.com/prettier/prettier/pull/1659#discussion_r117867268 * Rename findNodeByOffset to findNodeAtOffset "Find x by y" is the common usage for finding an `x` by a key `y`. However, since "by" has positional meaning, let's use "at" instead. See https://github.com/prettier/prettier/pull/1659#discussion_r117865121 * Always trimRight() in formatRange and explain why See https://github.com/prettier/prettier/pull/1659#discussion_r117864635 * Test formatting a range that crosses AST levels See https://github.com/prettier/prettier/pull/1659#issuecomment-303243688 * Fix formatting a range that crosses AST levels See https://github.com/prettier/prettier/pull/1659#issuecomment-303243688 * Remove unnecessary try-catch See https://github.com/prettier/prettier/pull/1659/files/e52db5e9f9ec4af599f658da03739e206dd4578c#r117878763 * Add test demonstrating range formatting indent detection * Detect alignment from text on line before range, but don't reformat it This avoids reformatting non-indentation that happens to precede the range on the same line, while still correctly indenting the range based on it. See https://github.com/prettier/prettier/pull/1659#discussion_r117881430
2017-05-23 17:43:58 +03:00
" Defaults to Infinity.\n" +
" --no-color Do not colorize error messages.\n" +
" --with-node-modules Process files inside `node_modules` directory.\n" +
" --version or -v Print Prettier version.\n" +
"\n"
);
process.exit(argv["help"] ? 0 : 1);
}
if (argv["find-config-path"]) {
resolveConfig(argv["find-config-path"]);
} else if (stdin) {
getStream(process.stdin).then(input => {
const options = getOptionsForFile(process.cwd());
if (listDifferent(input, options, "(stdin)")) {
return;
}
try {
writeOutput(format(input, options), options);
} catch (e) {
handleError("stdin", e);
}
2017-01-11 18:57:16 +03:00
});
} else {
eachFilename(filepatterns, (filename, options) => {
if (write) {
// Don't use `console.log` here since we need to replace this line.
process.stdout.write(filename);
}
let input;
try {
input = fs.readFileSync(filename, "utf8");
} catch (e) {
// Add newline to split errors from filename line.
process.stdout.write("\n");
console.error("Unable to read file: " + filename + "\n" + e);
// Don't exit the process if one file failed
process.exitCode = 2;
return;
}
listDifferent(input, options, filename);
const start = Date.now();
2017-01-11 18:57:16 +03:00
Add `cursorOffset` option for cursor translation (#1637) * Add `formatWithCursor` API with `cursorOffset` option This addresses https://github.com/prettier/prettier/issues/93 by adding a new option, `cursorOffset`, that tells prettier to determine the location of the cursor after the code has been formatted. This is accessible through the API via a new function, `formatWithCursor`, which returns a `{formatted: string, cursorOffset: ?number}`. Here's a usage example: ```js require("prettier").formatWithCursor(" 1", { cursorOffset: 2 }); // -> { formatted: '1;\n', cursorOffset: 1 } ``` * Add `--cursor-offset` CLI option It will print out the offset instead of the formatted output. This makes it easier to test. For example: echo ' 1' | prettier --stdin --cursor-offset 2 # prints 1 * Add basic test of cursor translation * Document `cursorOffset` option and `formatWithCursor()` * Print translated cursor offset to stderr when --cursor-offset is given This lets us continue to print the formatted code, while also communicating the updated cursor position. See https://github.com/prettier/prettier/pull/1637#discussion_r119735496 * doc-print cursor placeholder in comments.printComments() See https://github.com/prettier/prettier/pull/1637#discussion_r119735149 * Compare array index to -1 instead of >= 0 to determine element presence See https://github.com/prettier/prettier/pull/1637#discussion_r119736623 * Return {formatted, cursor} from printDocToString() instead of mutating options See https://github.com/prettier/prettier/pull/1637#discussion_r119737354
2017-06-02 01:52:29 +03:00
let result;
let output;
try {
Add `cursorOffset` option for cursor translation (#1637) * Add `formatWithCursor` API with `cursorOffset` option This addresses https://github.com/prettier/prettier/issues/93 by adding a new option, `cursorOffset`, that tells prettier to determine the location of the cursor after the code has been formatted. This is accessible through the API via a new function, `formatWithCursor`, which returns a `{formatted: string, cursorOffset: ?number}`. Here's a usage example: ```js require("prettier").formatWithCursor(" 1", { cursorOffset: 2 }); // -> { formatted: '1;\n', cursorOffset: 1 } ``` * Add `--cursor-offset` CLI option It will print out the offset instead of the formatted output. This makes it easier to test. For example: echo ' 1' | prettier --stdin --cursor-offset 2 # prints 1 * Add basic test of cursor translation * Document `cursorOffset` option and `formatWithCursor()` * Print translated cursor offset to stderr when --cursor-offset is given This lets us continue to print the formatted code, while also communicating the updated cursor position. See https://github.com/prettier/prettier/pull/1637#discussion_r119735496 * doc-print cursor placeholder in comments.printComments() See https://github.com/prettier/prettier/pull/1637#discussion_r119735149 * Compare array index to -1 instead of >= 0 to determine element presence See https://github.com/prettier/prettier/pull/1637#discussion_r119736623 * Return {formatted, cursor} from printDocToString() instead of mutating options See https://github.com/prettier/prettier/pull/1637#discussion_r119737354
2017-06-02 01:52:29 +03:00
result = format(
input,
Object.assign({}, options, { filepath: filename })
);
Add `cursorOffset` option for cursor translation (#1637) * Add `formatWithCursor` API with `cursorOffset` option This addresses https://github.com/prettier/prettier/issues/93 by adding a new option, `cursorOffset`, that tells prettier to determine the location of the cursor after the code has been formatted. This is accessible through the API via a new function, `formatWithCursor`, which returns a `{formatted: string, cursorOffset: ?number}`. Here's a usage example: ```js require("prettier").formatWithCursor(" 1", { cursorOffset: 2 }); // -> { formatted: '1;\n', cursorOffset: 1 } ``` * Add `--cursor-offset` CLI option It will print out the offset instead of the formatted output. This makes it easier to test. For example: echo ' 1' | prettier --stdin --cursor-offset 2 # prints 1 * Add basic test of cursor translation * Document `cursorOffset` option and `formatWithCursor()` * Print translated cursor offset to stderr when --cursor-offset is given This lets us continue to print the formatted code, while also communicating the updated cursor position. See https://github.com/prettier/prettier/pull/1637#discussion_r119735496 * doc-print cursor placeholder in comments.printComments() See https://github.com/prettier/prettier/pull/1637#discussion_r119735149 * Compare array index to -1 instead of >= 0 to determine element presence See https://github.com/prettier/prettier/pull/1637#discussion_r119736623 * Return {formatted, cursor} from printDocToString() instead of mutating options See https://github.com/prettier/prettier/pull/1637#discussion_r119737354
2017-06-02 01:52:29 +03:00
output = result.formatted;
} catch (e) {
// Add newline to split errors from filename line.
process.stdout.write("\n");
handleError(filename, e);
return;
}
if (write) {
// Remove previously printed filename to log it with duration.
readline.clearLine(process.stdout, 0);
readline.cursorTo(process.stdout, 0, null);
2017-01-11 18:57:16 +03:00
// Don't write the file if it won't change in order not to invalidate
// mtime based caches.
if (output === input) {
if (!argv["list-different"]) {
console.log(chalk.grey("%s %dms"), filename, Date.now() - start);
}
2017-01-11 18:57:16 +03:00
} else {
if (argv["list-different"]) {
console.log(filename);
} else {
console.log("%s %dms", filename, Date.now() - start);
}
try {
fs.writeFileSync(filename, output, "utf8");
} catch (err) {
console.error("Unable to write file: " + filename + "\n" + err);
// Don't exit the process if one file failed
process.exitCode = 2;
}
2017-01-11 18:57:16 +03:00
}
} else if (argv["debug-check"]) {
if (output) {
console.log(output);
} else {
process.exitCode = 2;
}
} else if (!argv["list-different"]) {
writeOutput(result, options);
}
2017-01-10 23:45:04 +03:00
});
2017-01-11 18:57:16 +03:00
}
function listDifferent(input, options, filename) {
if (!argv["list-different"]) {
return;
}
options = Object.assign({}, options, { filepath: filename });
if (!prettier.check(input, options)) {
if (!write) {
console.log(filename);
}
process.exitCode = 1;
}
return true;
}
function resolveConfig(filePath) {
const configFile = resolver.resolveConfigFile.sync(filePath);
if (configFile) {
console.log(path.relative(process.cwd(), configFile));
} else {
process.exitCode = 1;
}
}
function writeOutput(result, options) {
Add `cursorOffset` option for cursor translation (#1637) * Add `formatWithCursor` API with `cursorOffset` option This addresses https://github.com/prettier/prettier/issues/93 by adding a new option, `cursorOffset`, that tells prettier to determine the location of the cursor after the code has been formatted. This is accessible through the API via a new function, `formatWithCursor`, which returns a `{formatted: string, cursorOffset: ?number}`. Here's a usage example: ```js require("prettier").formatWithCursor(" 1", { cursorOffset: 2 }); // -> { formatted: '1;\n', cursorOffset: 1 } ``` * Add `--cursor-offset` CLI option It will print out the offset instead of the formatted output. This makes it easier to test. For example: echo ' 1' | prettier --stdin --cursor-offset 2 # prints 1 * Add basic test of cursor translation * Document `cursorOffset` option and `formatWithCursor()` * Print translated cursor offset to stderr when --cursor-offset is given This lets us continue to print the formatted code, while also communicating the updated cursor position. See https://github.com/prettier/prettier/pull/1637#discussion_r119735496 * doc-print cursor placeholder in comments.printComments() See https://github.com/prettier/prettier/pull/1637#discussion_r119735149 * Compare array index to -1 instead of >= 0 to determine element presence See https://github.com/prettier/prettier/pull/1637#discussion_r119736623 * Return {formatted, cursor} from printDocToString() instead of mutating options See https://github.com/prettier/prettier/pull/1637#discussion_r119737354
2017-06-02 01:52:29 +03:00
// Don't use `console.log` here since it adds an extra newline at the end.
process.stdout.write(result.formatted);
if (options.cursorOffset) {
process.stderr.write(result.cursorOffset + "\n");
}
}
function eachFilename(patterns, callback) {
// The ignorer will be used to filter file paths after the glob is checked,
// before any files are actually read
const ignoreFilePath = path.resolve(ignorePath);
let ignoreText = "";
try {
ignoreText = fs.readFileSync(ignoreFilePath, "utf8");
} catch (readError) {
if (readError.code !== "ENOENT") {
console.error(`Unable to read ${ignoreFilePath}:`, readError);
process.exit(2);
}
}
const ignorer = ignore().add(ignoreText);
if (ignoreNodeModules) {
patterns = patterns.concat(ignoreNodeModulesGlobs);
}
return globby(patterns, globOptions)
.then(filePaths => {
if (filePaths.length === 0) {
console.error(
"No matching files. Patterns tried: " + patterns.join(" ")
);
process.exitCode = 2;
return;
}
ignorer
.filter(filePaths)
.forEach(filePath => callback(filePath, getOptionsForFile(filePath)));
})
.catch(err => {
console.error(
"Unable to expand glob patterns: " + patterns.join(" ") + "\n" + err
);
// Don't exit the process if one pattern failed
process.exitCode = 2;
});
}