diff --git a/changelog_unreleased/javascript/10938.md b/changelog_unreleased/javascript/10938.md new file mode 100644 index 000000000..bd98f47d8 --- /dev/null +++ b/changelog_unreleased/javascript/10938.md @@ -0,0 +1,19 @@ +#### Track cursor position properly when it’s at the end of the range to format (#10938 by @j-f1) + +Previously, if the cursor was at the end of the range to format, it would simply be placed back at the end of the updated range. +Now, it will be repositioned if Prettier decides to add additional code to the end of the range (such as a semicolon). + + +```jsx +// Input (<|> represents the cursor) +const someVariable = myOtherVariable<|> +// range to format: ^^^^^^^^^^^^^^^ + +// Prettier stable +const someVariable = myOtherVariable;<|> +// range to format: ^^^^^^^^^^^^^^^ + +// Prettier main +const someVariable = myOtherVariable<|>; +// range to format: ^^^^^^^^^^^^^^^ +``` diff --git a/src/main/core.js b/src/main/core.js index feb3f169a..059f95da4 100644 --- a/src/main/core.js +++ b/src/main/core.js @@ -168,7 +168,7 @@ function formatRange(originalText, opts) { rangeEnd: Number.POSITIVE_INFINITY, // Track the cursor offset only if it's within our range cursorOffset: - opts.cursorOffset > rangeStart && opts.cursorOffset < rangeEnd + opts.cursorOffset > rangeStart && opts.cursorOffset <= rangeEnd ? opts.cursorOffset - rangeStart : -1, // Always use `lf` to format, we'll replace it later @@ -182,7 +182,7 @@ function formatRange(originalText, opts) { const rangeTrimmed = rangeResult.formatted.trimEnd(); let { cursorOffset } = opts; - if (cursorOffset >= rangeEnd) { + if (cursorOffset > rangeEnd) { // handle the case where the cursor was past the end of the range cursorOffset += rangeTrimmed.length - rangeString.length; } else if (rangeResult.cursorOffset >= 0) { diff --git a/tests/format/js/cursor/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/cursor/__snapshots__/jsfmt.spec.js.snap index 459e006ec..0690c25f0 100644 --- a/tests/format/js/cursor/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/js/cursor/__snapshots__/jsfmt.spec.js.snap @@ -445,3 +445,86 @@ thisWontBeFormatted ( 1 ,3) ================================================================================ `; + +exports[`range-5.js format 1`] = ` +====================================options===================================== +cursorOffset: 23 +parsers: ["babel", "typescript", "flow"] +printWidth: 80 +rangeEnd: 23 +rangeStart: 14 + | | printWidth +=====================================input====================================== +> 1 | const myVar = aFunction<|> + | ^^^^^^^^^ + 2 | +=====================================output===================================== +const myVar = aFunction<|>; + +================================================================================ +`; + +exports[`range-6.js format 1`] = ` +====================================options===================================== +cursorOffset: 24 +parsers: ["babel", "typescript", "flow"] +printWidth: 80 +rangeEnd: 24 +rangeStart: 14 + | | printWidth +=====================================input====================================== +> 1 | const myVar = aFunction;<|> + | ^^^^^^^^^^ + 2 | +=====================================output===================================== +const myVar = aFunction;<|> + +================================================================================ +`; + +exports[`range-7.js format 1`] = ` +====================================options===================================== +cursorOffset: 23 +parsers: ["babel", "typescript", "flow"] +printWidth: 80 +rangeEnd: 24 +rangeStart: 14 + | | printWidth +=====================================input====================================== +> 1 | const myVar = aFunction<|>; + | ^^^^^^^^^^^^^ + 2 | +=====================================output===================================== +const myVar = aFunction<|>; + +================================================================================ +`; + +exports[`range-8.js format 1`] = ` +====================================options===================================== +cursorOffset: 69 +parsers: ["babel", "typescript", "flow"] +printWidth: 80 +rangeEnd: 72 +rangeStart: 30 + | | printWidth +=====================================input====================================== + 1 | thisWontBeFormatted ( 1 ,3) +> 2 | + | ^ +> 3 | thisWillBeFormatted (2 ,3, )<|> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +> 4 | + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +> 5 | thisWontBeFormatted (2, 90 ,) + | ^ + 6 | +=====================================output===================================== +thisWontBeFormatted ( 1 ,3) + + thisWillBeFormatted(2, 3)<|>; + + thisWontBeFormatted (2, 90 ,) + +================================================================================ +`; diff --git a/tests/format/js/cursor/range-5.js b/tests/format/js/cursor/range-5.js new file mode 100644 index 000000000..ff0f0b4b8 --- /dev/null +++ b/tests/format/js/cursor/range-5.js @@ -0,0 +1 @@ +const myVar = <<>>aFunction<|><<>> diff --git a/tests/format/js/cursor/range-6.js b/tests/format/js/cursor/range-6.js new file mode 100644 index 000000000..0582cc2cf --- /dev/null +++ b/tests/format/js/cursor/range-6.js @@ -0,0 +1 @@ +const myVar = <<>>aFunction;<|><<>> diff --git a/tests/format/js/cursor/range-7.js b/tests/format/js/cursor/range-7.js new file mode 100644 index 000000000..1fdb3c3b5 --- /dev/null +++ b/tests/format/js/cursor/range-7.js @@ -0,0 +1 @@ +const myVar = <<>>aFunction<|>;<<>> diff --git a/tests/format/js/cursor/range-8.js b/tests/format/js/cursor/range-8.js new file mode 100644 index 000000000..621a066a4 --- /dev/null +++ b/tests/format/js/cursor/range-8.js @@ -0,0 +1,5 @@ +thisWontBeFormatted ( 1 ,3) +<<>> + thisWillBeFormatted (2 ,3, )<|> + + <<>> thisWontBeFormatted (2, 90 ,)