Skip to content
This repository has been archived by the owner on Dec 14, 2023. It is now read-only.

Format on save issue #1008

Open
lukehaas opened this issue Feb 4, 2022 · 0 comments
Open

Format on save issue #1008

lukehaas opened this issue Feb 4, 2022 · 0 comments
Labels

Comments

@lukehaas
Copy link

lukehaas commented Feb 4, 2022

The following code, when formatted on save will cause duplicate lines to be inserted:

Before:


let arr = [1,2,3];


arr.indexOf(1)

let cplxArr = [
  {id: 1},
  {id: 2},
  {id: 3}
];

cplxArr.findIndex(el => el.id === 1);

after:


let arr = [1, 2, 3];

arr.indexOf(1);
arr.indexOf(1)
let cplxArr = [{ id: 1 }, { id: 2 }, { id: 3 }];
let cplxArr = [
cplxArr.findIndex((el) => el.id === 1);

This is possibly due to the diffing code here:

ICEcoder/assets/js/icecoder.js

Lines 2180 to 2227 in 51cf24b

editorText = difflib.stringAsLines(this.getThisCM().getValue());
prettierText = difflib.stringAsLines(prettierVersion.formatted);
// Create a SequenceMatcher instance that diffs the two sets of lines
sm = new difflib.SequenceMatcher(editorText, prettierText);
// Get the opcodes from the SequenceMatcher instance
// Opcodes is a list of 3-tuples describing what changes should be made to the base text in order to yield the new text
opcodes = sm.get_opcodes();
docShift = 0;
for (let i = 0; i < opcodes.length; i++) {
// opcode events may be:
// equal = do nothing for this range
// replace = replace [1]-[2] with [3]-[4]
// insert = replace [1]-[2] with [3]-[4]
// delete = replace [1]-[2] with [3]-[4]
// Params to determine if we need to set 1 or 0 shift the start line and end line
startShift = "delete" === opcodes[i][0] && editorText.length === opcodes[i][2] ? 1 : 0;
endShift = "replace" === opcodes[i][0] ? 1 : 0;
if ("equal" !== opcodes[i][0]) {
// Replace or insert
if ("replace" === opcodes[i][0] || "insert" === opcodes[i][0]) {
newContent = "";
// For each of the replace/insert lines in Prettier's version
for (let j = opcodes[i][3]; j < opcodes[i][4]; j++) {
// Build up newContent lines and end with a new line char if not the last line in the range
newContent += prettierText[j];
if (j < opcodes[i][4] - 1) {
newContent += "\n";
}
}
}
// Delete
if ("delete" === opcodes[i][0]) {
// Not the last line in doc, the newContent is the line after the section we're deleting in editors version
// Else if it's the last line in doc, the content after the section we're deleting is nothing
newContent = editorText.length > opcodes[i][2]
? editorText[opcodes[i][2]]
: "";
}
// Replace the range with newContent. The range start line and end line adjust according to
// startShift and endShift 1/0 values plus also the +/- docShift which is how much the
// editor document has shifted so far during replace ranges
this.getThisCM().replaceRange(newContent, {line: opcodes[i][1] - docShift - startShift, ch: 0}, {line: opcodes[i][2] - docShift - endShift, ch: 1000000}, "+input");
// Work out the +/- document shift based on difference between the editors last line in
// this diff range and Prettiers last line in this diff range
docShift = opcodes[i][2] - opcodes[i][4];

@lukehaas lukehaas added the Bug label Feb 4, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

1 participant