private void ApplyEdits(Document document, ITextView textView, ITextBuffer subjectBuffer, ICommentSelectionService service, string title, CommentSelectionResult edits) { // Create tracking spans to track the text changes. var currentSnapshot = subjectBuffer.CurrentSnapshot; var trackingSpans = edits.TrackingSpans .SelectAsArray(textSpan => (originalSpan: textSpan, trackingSpan: CreateTrackingSpan(edits.ResultOperation, currentSnapshot, textSpan.TrackingTextSpan))); // Apply the text changes. using (var transaction = new CaretPreservingEditTransaction(title, textView, _undoHistoryRegistry, _editorOperationsFactoryService)) { document.Project.Solution.Workspace.ApplyTextChanges(document.Id, edits.TextChanges.Distinct(), CancellationToken.None); transaction.Complete(); } // Convert the tracking spans into snapshot spans for formatting and selection. var trackingSnapshotSpans = trackingSpans.Select(s => CreateSnapshotSpan(subjectBuffer.CurrentSnapshot, s.trackingSpan, s.originalSpan)); if (trackingSnapshotSpans.Any()) { if (edits.ResultOperation == Operation.Uncomment) { // Format the document only during uncomment operations. Use second transaction so it can be undone. using var transaction = new CaretPreservingEditTransaction(title, textView, _undoHistoryRegistry, _editorOperationsFactoryService); var formattedDocument = Format(service, subjectBuffer.CurrentSnapshot, trackingSnapshotSpans, CancellationToken.None); if (formattedDocument != null) { formattedDocument.Project.Solution.Workspace.ApplyDocumentChanges(formattedDocument, CancellationToken.None); transaction.Complete(); } } // Set the multi selection after edits have been applied. textView.SetMultiSelection(trackingSnapshotSpans); } }
private void ApplyEdits(Document document, ITextView textView, ITextBuffer subjectBuffer, string title, CommentSelectionResult edits, CancellationToken cancellationToken) { var originalSnapshot = subjectBuffer.CurrentSnapshot; // Apply the text changes. using (var transaction = new CaretPreservingEditTransaction(title, textView, _undoHistoryRegistry, _editorOperationsFactoryService)) { subjectBuffer.ApplyChanges(edits.TextChanges); transaction.Complete(); } if (edits.TrackingSpans.Any()) { // Create tracking spans to track the text changes. var trackingSpans = edits.TrackingSpans .SelectAsArray(textSpan => (originalSpan: textSpan, trackingSpan: CreateTrackingSpan(edits.ResultOperation, originalSnapshot, textSpan.TrackingTextSpan))); // Convert the tracking spans into snapshot spans for formatting and selection. var trackingSnapshotSpans = trackingSpans.Select(s => CreateSnapshotSpan(subjectBuffer.CurrentSnapshot, s.trackingSpan, s.originalSpan)); if (edits.ResultOperation == Operation.Uncomment && document.SupportsSyntaxTree) { // Format the document only during uncomment operations. Use second transaction so it can be undone. using var transaction = new CaretPreservingEditTransaction(title, textView, _undoHistoryRegistry, _editorOperationsFactoryService); var newText = subjectBuffer.CurrentSnapshot.AsText(); var oldSyntaxTree = document.GetSyntaxTreeSynchronously(cancellationToken); var newRoot = oldSyntaxTree.WithChangedText(newText).GetRoot(cancellationToken); var formattingOptions = subjectBuffer.GetSyntaxFormattingOptions(_editorOptionsService, document.Project.LanguageServices, explicitFormat: false); var formattingSpans = trackingSnapshotSpans.Select(change => CommonFormattingHelpers.GetFormattingSpan(newRoot, change.Span.ToTextSpan())); var formattedChanges = Formatter.GetFormattedTextChanges(newRoot, formattingSpans, document.Project.Solution.Services, formattingOptions, rules: null, cancellationToken); subjectBuffer.ApplyChanges(formattedChanges); transaction.Complete(); } // Set the multi selection after edits have been applied. textView.SetMultiSelection(trackingSnapshotSpans); } }