public void Dispose() { // Unsubscribe from events _textView.TextBuffer.PostChanged -= TextBuffer_PostChanged; _debuggerTextView.Cleanup(); // The buffer graph subscribes to events of its source buffers, we're no longer interested _projectionBuffer.DeleteSpans(0, _projectionBuffer.CurrentSnapshot.SpanCount); // The next request will use a new workspace _workspace.Dispose(); }
private async ValueTask <DifferenceViewerPreview> CreateNewDifferenceViewerAsync( PreviewWorkspace?leftWorkspace, PreviewWorkspace?rightWorkspace, IProjectionBuffer originalBuffer, IProjectionBuffer changedBuffer, double zoomLevel, CancellationToken cancellationToken) { // IWpfDifferenceViewerFactoryService is a Visual Studio API which is not documented as free-threaded await ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); // leftWorkspace can be null if the change is adding a document. // rightWorkspace can be null if the change is removing a document. // However both leftWorkspace and rightWorkspace can't be null at the same time. Contract.ThrowIfTrue((leftWorkspace == null) && (rightWorkspace == null)); var diffBuffer = _differenceBufferService.CreateDifferenceBuffer( originalBuffer, changedBuffer, new StringDifferenceOptions(), disableEditing: true); var mode = leftWorkspace == null ? DifferenceViewMode.RightViewOnly : rightWorkspace == null ? DifferenceViewMode.LeftViewOnly : DifferenceViewMode.Inline; var diffViewer = await CreateDifferenceViewAsync(diffBuffer, _previewRoleSet, mode, zoomLevel, cancellationToken).ConfigureAwait(true); diffViewer.Closed += (s, e) => { // Workaround Editor bug. The editor has an issue where they sometimes crash when // trying to apply changes to projection buffer. So, when the user actually invokes // a SuggestedAction we may then edit a text buffer, which the editor will then // try to propagate through the projections we have here over that buffer. To ensure // that that doesn't happen, we clear out the projections first so that this crash // won't happen. originalBuffer.DeleteSpans(0, originalBuffer.CurrentSnapshot.SpanCount); changedBuffer.DeleteSpans(0, changedBuffer.CurrentSnapshot.SpanCount); leftWorkspace?.Dispose(); leftWorkspace = null; rightWorkspace?.Dispose(); rightWorkspace = null; }; if (_globalOptions.GetOption(SolutionCrawlerRegistrationService.EnableSolutionCrawler)) { leftWorkspace?.EnableSolutionCrawler(); rightWorkspace?.EnableSolutionCrawler(); } return(new DifferenceViewerPreview(diffViewer)); }
private async Task <object> CreateNewDifferenceViewerAsync( PreviewWorkspace leftWorkspace, PreviewWorkspace rightWorkspace, IProjectionBuffer originalBuffer, IProjectionBuffer changedBuffer, double zoomLevel, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // leftWorkspace can be null if the change is adding a document. // rightWorkspace can be null if the change is removing a document. // However both leftWorkspace and rightWorkspace can't be null at the same time. Contract.ThrowIfTrue((leftWorkspace == null) && (rightWorkspace == null)); var diffBuffer = _differenceBufferService.CreateDifferenceBuffer( originalBuffer, changedBuffer, new StringDifferenceOptions(), disableEditing: true); var diffViewer = _differenceViewerService.CreateDifferenceView(diffBuffer, _previewRoleSet); diffViewer.Closed += (s, e) => { // Workaround Editor bug. The editor has an issue where they sometimes crash when // trying to apply changes to projection buffer. So, when the user actually invokes // a SuggestedAction we may then edit a text buffer, which the editor will then // try to propagate through the projections we have here over that buffer. To ensure // that that doesn't happen, we clear out the projections first so that this crash // won't happen. originalBuffer.DeleteSpans(0, originalBuffer.CurrentSnapshot.SpanCount); changedBuffer.DeleteSpans(0, changedBuffer.CurrentSnapshot.SpanCount); leftWorkspace?.Dispose(); leftWorkspace = null; rightWorkspace?.Dispose(); rightWorkspace = null; }; const string DiffOverviewMarginName = "deltadifferenceViewerOverview"; if (leftWorkspace == null) { diffViewer.ViewMode = DifferenceViewMode.RightViewOnly; diffViewer.RightView.ZoomLevel *= zoomLevel; diffViewer.RightHost.GetTextViewMargin(DiffOverviewMarginName).VisualElement.Visibility = Visibility.Collapsed; } else if (rightWorkspace == null) { diffViewer.ViewMode = DifferenceViewMode.LeftViewOnly; diffViewer.LeftView.ZoomLevel *= zoomLevel; diffViewer.LeftHost.GetTextViewMargin(DiffOverviewMarginName).VisualElement.Visibility = Visibility.Collapsed; } else { diffViewer.ViewMode = DifferenceViewMode.Inline; diffViewer.InlineView.ZoomLevel *= zoomLevel; diffViewer.InlineHost.GetTextViewMargin(DiffOverviewMarginName).VisualElement.Visibility = Visibility.Collapsed; } // Disable focus / tab stop for the diff viewer. diffViewer.RightView.VisualElement.Focusable = false; diffViewer.LeftView.VisualElement.Focusable = false; diffViewer.InlineView.VisualElement.Focusable = false; // This code path must be invoked on UI thread. AssertIsForeground(); // We use ConfigureAwait(true) to stay on the UI thread. await diffViewer.SizeToFitAsync(ThreadingContext).ConfigureAwait(true); leftWorkspace?.EnableDiagnostic(); rightWorkspace?.EnableDiagnostic(); return(new DifferenceViewerPreview(diffViewer)); }
private async Task<object> CreateNewDifferenceViewerAsync( PreviewWorkspace leftWorkspace, PreviewWorkspace rightWorkspace, IProjectionBuffer originalBuffer, IProjectionBuffer changedBuffer, double zoomLevel, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // leftWorkspace can be null if the change is adding a document. // rightWorkspace can be null if the change is removing a document. // However both leftWorkspace and rightWorkspace can't be null at the same time. Contract.ThrowIfTrue((leftWorkspace == null) && (rightWorkspace == null)); var diffBuffer = _differenceBufferService.CreateDifferenceBuffer( originalBuffer, changedBuffer, new StringDifferenceOptions(), disableEditing: true); var diffViewer = _differenceViewerService.CreateDifferenceView(diffBuffer, _previewRoleSet); diffViewer.Closed += (s, e) => { // Workaround Editor bug. The editor has an issue where they sometimes crash when // trying to apply changes to projection buffer. So, when the user actually invokes // a SuggestedAction we may then edit a text buffer, which the editor will then // try to propagate through the projections we have here over that buffer. To ensure // that that doesn't happen, we clear out the projections first so that this crash // won't happen. originalBuffer.DeleteSpans(0, originalBuffer.CurrentSnapshot.SpanCount); changedBuffer.DeleteSpans(0, changedBuffer.CurrentSnapshot.SpanCount); leftWorkspace?.Dispose(); leftWorkspace = null; rightWorkspace?.Dispose(); rightWorkspace = null; }; const string DiffOverviewMarginName = "deltadifferenceViewerOverview"; if (leftWorkspace == null) { diffViewer.ViewMode = DifferenceViewMode.RightViewOnly; diffViewer.RightView.ZoomLevel *= zoomLevel; diffViewer.RightHost.GetTextViewMargin(DiffOverviewMarginName).VisualElement.Visibility = Visibility.Collapsed; } else if (rightWorkspace == null) { diffViewer.ViewMode = DifferenceViewMode.LeftViewOnly; diffViewer.LeftView.ZoomLevel *= zoomLevel; diffViewer.LeftHost.GetTextViewMargin(DiffOverviewMarginName).VisualElement.Visibility = Visibility.Collapsed; } else { diffViewer.ViewMode = DifferenceViewMode.Inline; diffViewer.InlineView.ZoomLevel *= zoomLevel; diffViewer.InlineHost.GetTextViewMargin(DiffOverviewMarginName).VisualElement.Visibility = Visibility.Collapsed; } // Disable focus / tab stop for the diff viewer. diffViewer.RightView.VisualElement.Focusable = false; diffViewer.LeftView.VisualElement.Focusable = false; diffViewer.InlineView.VisualElement.Focusable = false; // This code path must be invoked on UI thread. AssertIsForeground(); // We use ConfigureAwait(true) to stay on the UI thread. await diffViewer.SizeToFitAsync().ConfigureAwait(true); leftWorkspace?.EnableDiagnostic(); rightWorkspace?.EnableDiagnostic(); return new DifferenceViewerPreview(diffViewer); }