Skip to content

Conversation

@josephfrazier
Copy link
Collaborator

This partially addresses
#1981 by ensuring that the
cursor cannot jump outside of its node upon formatting. It could be
improved upon by keeping track of the offset relative to the end of the
node as well.

Since the `cursorOffset` option (introduced in prettier#1637) works by tracking
the cursor position relative to an AST node (rather than a CST token),
it can produce incorrect results.

See prettier#1981
This partially addresses
prettier#1981 by ensuring that the
cursor cannot jump outside of its node upon formatting. It could be
improved upon by keeping track of the offset relative to the end of the
node as well.
}

if (out.length) {
if (out.length && out[out.length - 1].replace) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a quick/dirty way of getting the tests to pass, and should probably be replaced with more robust logic that skips over cursor placeholder Symbols.

// Trim whitespace at the end of line
while (
out.length > 0 &&
out[out.length - 1].match &&
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a quick/dirty way of getting the tests to pass, and should probably be replaced with more robust logic that skips over cursor placeholder Symbols.

cursorOffset: cursorOffsetResult + cursorOffset
};
} else {
return {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You just need this return right? Math.max should remove the need for the condition right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, maybe. Before this PR, the cursor translation simply applied the offset from the beginning of the node the cursor was on. Now, it tries to do the same thing, unless that would move the cursor outside the node, in which case it applies the offset from the end of the node the cursor was on.

However, if the cursor doesn't escape the node after the beginning-offset is applied, it could be at a different position than if the end-offset is applied, so this logic gets a little complicated. Does that make sense?


Side note: at first, I thought you were talking about simply returning, rather than putting it inside an else block, because the if already has a return. I'll open a separate PR for enforcing that lint rule.

cursorOffsetResult
)
};
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this logic, shouldn't it be

Math.min(cursorNodeEnd, cursorOffsetResult + cursorOffset)

expect(prettier.formatWithCursor(code, { cursorOffset: 15 })).toEqual({
formatted: "return 15;\n",
cursorOffset: 8
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to write a small wrapper where you can add {{cursor}} inside of the string. It would greatly help review those changes.

@vjeux
Copy link
Contributor

vjeux commented Jun 5, 2017

This is an interesting edge case. Just thinking out loud, it looks like the issue here isn't that the offset is > nodeEnd but that it's > identifierStart.

There are two nodes here that are of importance:

  • contained inside of ReturnStatement
  • left of Identifier

and we mess up with the invariants of the second one. I'm not sure what the solution is, but it seems like taking into account the identifier is need to get a correct result.

What do you think?

@vjeux
Copy link
Contributor

vjeux commented Jun 13, 2017

What's the status of this PR?

@josephfrazier
Copy link
Collaborator Author

I've been busy with other things, and haven't done any further work on this.

@vjeux
Copy link
Contributor

vjeux commented Jun 21, 2017

I'm going to close this in order for doing a cleaning, feel free to reopen if you make progress.

@vjeux vjeux closed this Jun 21, 2017
@josephfrazier
Copy link
Collaborator Author

No problem, I've dropped this for now, since some editors (whose plugins could use this feature) already do a pretty good job of preserving cursor location (I've only tried VScode) : prettier/prettier-vscode#12 (comment)

@lock lock bot added the locked-due-to-inactivity Please open a new issue and fill out the template instead of commenting. label Jan 20, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Jan 20, 2019
@josephfrazier josephfrazier deleted the cursor-offset-clamp branch July 9, 2019 02:24
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

locked-due-to-inactivity Please open a new issue and fill out the template instead of commenting.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants