Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Virtual concat document with extra lines #25

Merged
merged 18 commits into from
Nov 19, 2021

Conversation

rchiodo
Copy link
Contributor

@rchiodo rchiodo commented Nov 18, 2021

This change is a new way to handle magics in the concat document. This is a prerequisite to solving bugs like:

microsoft/vscode-jupyter#6987
microsoft/vscode-jupyter#1510

Essentially there are two parallel documents - the real text entered by the user, and the text we send to pylance.

These are tracked with a series of spans. Spans are in order from top of notebook to bottom with each span tracking:

  • User entered (real) text
  • Text for pylance (concat) text
  • Offset in each set of text

These spans are then used to translate edits between the two different variations of the text.

Edits were particularly difficult because they don't map to the edits in the original (real) text. I used something called fast myers diff to compute new offsets.

@rchiodo rchiodo requested a review from a team as a code owner November 18, 2021 18:03
@rchiodo
Copy link
Contributor Author

rchiodo commented Nov 18, 2021

/cc @heejaechang @bschnurr

Hopefully you can merge this change into your version.

@heejaechang
Copy link
Contributor

thank you!

}
return symbols ?? undefined;
}

public toIncomingWorkspaceEdit(workspaceEdit: WorkspaceEdit | null | undefined): WorkspaceEdit | undefined {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

A lot of the change is changing 'toIncoming' to 'toNotebook' and 'toOutgoing' to 'toConcat'. I kept forgetting which was 'outgoing' and which was 'incoming'

Copy link
Member

Choose a reason for hiding this comment

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

Smart, feels much clearer to me this way.

// Diff should have an array of numbers. These are
// offsets in the old text translating to offsets in the new text
if (diff.length > 0) {
const oldTextStart = diff[0][0];
Copy link
Member

Choose a reason for hiding this comment

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

Is there a way to maybe document what the fastMyersDiff returns? Even with the comment I'm not fully sure on what our diff indexes are here.

Copy link
Member

Choose a reason for hiding this comment

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

Like having this in from the documentation on npm "it produces a sequence of quadruples [sx, ex, sy, ey], where [sx, ex) indicates a range to delete from xs and [sy, ey) indicates a range from ys to replace the deleted material with. Simple deletions are indicated when sy === ey and simple insertions when sx === ex"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It does have docs? Do you mean put a link to the docs here? Otherwise the comment would be rather large.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I put more comments and a link.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks that helps. It was reading a bit funny to me since it was looking at the individual diffs all as one big diff here (taking the start of the first diff to the end of the last diff) but that works for what this is doing.

public realRangeOf(cellUri: vscode.Uri) {
// Get all the real spans
const realSpans = this._spans.filter((s) => s.uri.toString() == cellUri.toString() && s.inRealCell);
const startOffset = realSpans[0].startOffset | 0;
Copy link
Member

Choose a reason for hiding this comment

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

Do you want logical OR here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. Good catch.

public locationAt(positionOrRange: vscode.Range | vscode.Position): vscode.Location {

public notebookLocationAt(positionOrRange: vscode.Range | vscode.Position): vscode.Location {
// positionOrRange should be in concat ranges
Copy link
Member

Choose a reason for hiding this comment

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

Minor suggestion:
const range = (positionOrRange instanceof vscode.Position) ? new vscode.Range(positionOrRange, positionOrRange) : positionOrRange;

Maybe pedantic, but then you could use range for the rest of the function instead of positionOrRange when you are assuring that you have a Range here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes that's clearer, will fix

): NotebookSpan {
// Compute fragment based on cell uri
const fragment =
cellUri.scheme === InteractiveInputScheme ? -1 : parseInt(cellUri.fragment.substring(2) || '0');
Copy link
Member

Choose a reason for hiding this comment

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

Doesn't the fallback need to be 0 not '0'?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No actually it's inside the parse. So it has to parse the '0'

Copy link
Member

Choose a reason for hiding this comment

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

Whoops totally missed that. It just looked odd, I see it now.

Copy link
Member

@IanMatthewHuff IanMatthewHuff left a comment

Choose a reason for hiding this comment

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

Added a few comments to check out, but looks good.

@rchiodo rchiodo merged commit a3805f7 into main Nov 19, 2021
@rchiodo rchiodo deleted the dev/rchiodo/replace_magics_spans branch November 19, 2021 01:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants