Translate cursor relative to nearest node, not SourceElement (#1989)

* Add test demonstrating SourceElement-relative cursor translation

See https://github.com/prettier/prettier/issues/1981#issuecomment-306326739

* Translate cursor relative to nearest node, not SourceElement

This partially address https://github.com/prettier/prettier/issues/1981

See https://github.com/prettier/prettier/issues/1981#issuecomment-306326739

* Add test demonstrating incorrect cursor translation

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

See https://github.com/prettier/prettier/issues/1981
master
Joseph Frazier 2017-06-05 21:51:53 -04:00 committed by Christopher Chedeau
parent 19bd2a3f7c
commit c863cbeac8
2 changed files with 30 additions and 4 deletions

View File

@ -125,7 +125,8 @@ function findSiblingAncestors(startNodeAndParents, endNodeAndParents) {
};
}
function findNodeAtOffset(node, offset, parentNodes) {
function findNodeAtOffset(node, offset, predicate, parentNodes) {
predicate = predicate || (() => true);
parentNodes = parentNodes || [];
const start = util.locStart(node);
const end = util.locEnd(node);
@ -134,6 +135,7 @@ function findNodeAtOffset(node, offset, parentNodes) {
const childResult = findNodeAtOffset(
childNode,
offset,
predicate,
[node].concat(parentNodes)
);
if (childResult) {
@ -141,7 +143,7 @@ function findNodeAtOffset(node, offset, parentNodes) {
}
}
if (isSourceElement(node)) {
if (predicate(node)) {
return {
node: node,
parentNodes: parentNodes
@ -199,8 +201,16 @@ function calculateRange(text, opts, ast) {
}
}
const startNodeAndParents = findNodeAtOffset(ast, startNonWhitespace);
const endNodeAndParents = findNodeAtOffset(ast, endNonWhitespace);
const startNodeAndParents = findNodeAtOffset(
ast,
startNonWhitespace,
isSourceElement
);
const endNodeAndParents = findNodeAtOffset(
ast,
endNonWhitespace,
isSourceElement
);
const siblingAncestors = findSiblingAncestors(
startNodeAndParents,
endNodeAndParents

View File

@ -6,3 +6,19 @@ test("translates cursor correctly in basic case", () => {
cursorOffset: 1
});
});
test("positions cursor relative to closest node, not SourceElement", () => {
const code = "return 15";
expect(prettier.formatWithCursor(code, { cursorOffset: 15 })).toEqual({
formatted: "return 15;\n",
cursorOffset: 7
});
});
test("keeps cursor inside formatted node", () => {
const code = "return 15";
expect(prettier.formatWithCursor(code, { cursorOffset: 14 })).toEqual({
formatted: "return 15;\n",
cursorOffset: 14 // TODO fix this
});
});