Skip to content

Conversation

@CyrusNajmabadi
Copy link
Member

No description provided.

var newSolution = document.Project.Solution.WithDocumentText(
document.Project.Solution.GetRelatedDocumentIds(documentId),
clonedBuffer.AsTextContainer().CurrentText,
PreservationMode.PreserveIdentity);
Copy link
Member Author

Choose a reason for hiding this comment

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

same here. this is what AbstractPreviewFactoryService does to fork and get the new roslyn solution.

Copy link
Member

Choose a reason for hiding this comment

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

This is quite fishy since we're doing the OpenDocument call which will probably do the same thing...? Or I guess this is forking all linked copies?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes. WithDocumentText just sets the doc text for everything. .OpenDocument ensures all of the following runs:

            onAfterUpdate: static (oldSolution, newSolution, data) =>
            {
                var (@this, documentId, textContainer, isCurrentContext, requireDocumentPresentAndClosed) = data;

                @this.AddToOpenDocumentMap(documentId);
                @this.SignupForTextChanges(documentId, textContainer, isCurrentContext, (w, id, text, mode) => w.OnDocumentTextChanged(id, text, mode));

                var newDoc = newSolution.GetRequiredDocument(documentId);
                @this.OnDocumentTextChanged(newDoc);

                // Fire and forget that the workspace is changing.
                @this.RaiseWorkspaceChangedEventAsync(WorkspaceChangeKind.DocumentChanged, oldSolution, newSolution, documentId: documentId);

                // We fire 2 events on source document opened.
                @this.RaiseDocumentOpenedEventAsync(newDoc);
                @this.RaiseTextDocumentOpenedEventAsync(newDoc);
            });

Now, how important it is for that to run is unclear to me. However, this is what the lightbulb does for its preview buffers, so i figured i would eliminate chances for strangeness and keep in sync.

Copy link
Member

Choose a reason for hiding this comment

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

Maybe file a bug to investigate, but if this is what PreviewWorkspace is doing then we can fix them all up at once.

@CyrusNajmabadi CyrusNajmabadi changed the base branch from main to features/next June 2, 2025 19:45
<PackageReference Include="Microsoft.VisualStudio.LanguageServer.Client" PrivateAssets="all" />
<PackageReference Include="Microsoft.VisualStudio.LanguageServer.Client.Implementation" PrivateAssets="all" />
<PackageReference Include="Microsoft.VisualStudio.Text.UI.Wpf" />
<PackageReference Include="Microsoft.VisualStudio.Text.Internal" />
Copy link
Member

Choose a reason for hiding this comment

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

Not sure if we have to mark this as private dependency or something. It doesn't appear we upload this package to NuGet (and haven't in quite some time), but check if the editor team has a special requirement here.

Copy link
Member Author

Choose a reason for hiding this comment

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

@jasonmalinowski is this a blocking concern on your part? or ca this be merged in and this poitn be resolved later?

Copy link

Choose a reason for hiding this comment

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

text.internal is not part of the vssdk and we don't publish it to nuget

Comment on lines 68 to 69
// Now take the cloned buffer and apply the edits to it the caller wants to speculate about.
ApplyEditsToClonedBuffer(options, clonedBuffer);
Copy link
Member

Choose a reason for hiding this comment

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

We specifically put a method on the base type to do the cloning so we didn't have to reinvent this bit -- was that not usable?

Copy link
Member Author

Choose a reason for hiding this comment

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

That guy doesn't ensure that we get an ITextDocument with a proper .cs path.

@CyrusNajmabadi
Copy link
Member Author

I wouldn't expect us to have to do this in this case since I don't think we're expecting an LSP hookup to this? This might actually cause problems?

If we don't have LSP hookup, then things like classification through LSP would not work.

@CyrusNajmabadi
Copy link
Member Author

@jasonmalinowski anything remaining that needs to change in this PR for you?

// Clone the existing text into a new editor snapshot/buffer that we can fork independently of the original.
var clonedSnapshotBeforeEdits = this.CloneWithEdits(options);

// Grab the ITextSnapshot of this cloned buffer before making any changes. The SpeculativeEdit api needs it
Copy link
Member

Choose a reason for hiding this comment

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

This comment seems backwards from the code -- the comment says we're grabbing the snapshot from the buffer, but the code is grabbing the buffer from the snapshot.

var documentId = document.Id;

// Clone the existing text into a new editor snapshot/buffer that we can fork independently of the original.
var clonedSnapshotBeforeEdits = this.CloneWithEdits(options);
Copy link
Member

Choose a reason for hiding this comment

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

Why "beforeEdits" in the name -- it's representing after the edits, right?

var newSolution = document.Project.Solution.WithDocumentText(
document.Project.Solution.GetRelatedDocumentIds(documentId),
clonedBuffer.AsTextContainer().CurrentText,
PreservationMode.PreserveIdentity);
Copy link
Member

Choose a reason for hiding this comment

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

Maybe file a bug to investigate, but if this is what PreviewWorkspace is doing then we can fix them all up at once.

// is consistent.
var newSolution = document.Project.Solution.WithDocumentText(
document.Project.Solution.GetRelatedDocumentIds(documentId),
clonedBuffer.AsTextContainer().CurrentText,
Copy link
Member

Choose a reason for hiding this comment

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

This could just be clonedSnapshotBeforeEdits.AsText() rather than jumping to the container and back.

@CyrusNajmabadi
Copy link
Member Author

Will fix all feedback in followup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants