public void SubjectBuffersDisconnected(IWpfTextView wpfTextView, ConnectionReason reason, Collection <ITextBuffer> subjectBuffers) { try { if (wpfTextView == null || !wpfTextView.HasValidRoles()) { return; } if (!wpfTextView.Properties.TryGetProperty(PropertyNames.TextViewFilePath, out string filePath)) { return; } lock (WeakTableLock) { // we need to check all buffers reported since we will be called after actual changes have happened. // for example, if content type of a buffer changed, we will be called after it is changed, rather than before it. foreach (var buffer in subjectBuffers) { if (TextBufferTable.TryGetValue(buffer, out HashSet <IWpfTextView> textViews)) { textViews.Remove(wpfTextView); TextViewCache.Remove(filePath, wpfTextView); if (textViews.Count == 0) { TextBufferTable.Remove(buffer); wpfTextView.LayoutChanged -= OnTextViewLayoutChanged; wpfTextView.Caret.PositionChanged -= Caret_PositionChanged; wpfTextView.GotAggregateFocus -= TextView_GotAggregateFocus; wpfTextView.Selection.SelectionChanged += Selection_SelectionChanged; wpfTextView.ZoomLevelChanged -= OnZoomLevelChanged; wpfTextView.Properties.RemovePropertySafe(PropertyNames.TextViewFilePath); wpfTextView.Properties.RemovePropertySafe(PropertyNames.TextViewState); wpfTextView.Properties.RemovePropertySafe(PropertyNames.DocumentMarkers); wpfTextView.Properties.RemovePropertySafe(PropertyNames.DocumentMarkerManager); wpfTextView.Properties.RemovePropertySafe(PropertyNames.TextViewMarginProviders); wpfTextView.Properties.TryDisposeProperty <HighlightAdornmentManager>(PropertyNames.AdornmentManager); wpfTextView.Properties.TryDisposeProperty <Subject <TextViewLayoutChangedSubject> >(PropertyNames.TextViewLayoutChangedSubject); wpfTextView.Properties.TryDisposeProperty <Subject <CaretPositionChangedSubject> >(PropertyNames.CaretPositionChangedSubject); wpfTextView.Properties.TryDisposeProperty <Subject <TextSelectionChangedSubject> >(PropertyNames.TextSelectionChangedSubject); wpfTextView.Properties.TryDisposeListProperty(PropertyNames.TextViewEvents); wpfTextView.Properties.TryDisposeListProperty(PropertyNames.TextViewLocalEvents); Log.Verbose($"{nameof(SubjectBuffersDisconnected)} FilePath={filePath}"); } } } if (TextViewCache.Count() == 0) { ResetActiveEditor(); } } } catch (Exception ex) { Log.Error(ex, nameof(SubjectBuffersDisconnected)); } }
/// <summary> /// SubjectBuffersConnected happens first /// </summary> /// <param name="wpfTextView"></param> /// <param name="reason"></param> /// <param name="subjectBuffers"></param> public void SubjectBuffersConnected(IWpfTextView wpfTextView, ConnectionReason reason, Collection <ITextBuffer> subjectBuffers) { try { var logPrefix = $"{nameof(SubjectBuffersConnected)}"; using (var metrics = Log.WithMetrics($"{logPrefix} ")) { if (wpfTextView == null || !wpfTextView.HasValidDocumentRoles()) { return; } IVirtualTextDocument virtualTextDocument = null; if (!TextDocumentExtensions.TryGetTextDocument(TextDocumentFactoryService, wpfTextView, out virtualTextDocument)) { Log.Warning($"{logPrefix} Could not create virtualTextDocument"); return; } Log.Verbose($"{logPrefix} pre-Lock"); lock (WeakTableLock) { Log.Verbose($"{logPrefix} in-Lock"); foreach (var buffer in subjectBuffers) { if (!TextBufferTable.TryGetValue(buffer, out HashSet <IWpfTextView> textViews)) { textViews = new HashSet <IWpfTextView>(); TextBufferTable.Add(buffer, textViews); } textViews.Add(wpfTextView); } using (metrics.Measure($"{logPrefix} Building properties")) { if (virtualTextDocument.SupportsMarkers) { wpfTextView.Properties.GetOrCreateSingletonProperty(PropertyNames.DocumentMarkerManager, () => new DocumentMarkerManager(CodeStreamAgentServiceFactory.Create(), wpfTextView, virtualTextDocument)); } wpfTextView.Properties.GetOrCreateSingletonProperty(PropertyNames.TextViewDocument, () => virtualTextDocument); wpfTextView.Properties.GetOrCreateSingletonProperty(PropertyNames.TextViewState, () => new TextViewState()); #if DEBUG if (TextViewCache == null) { System.Diagnostics.Debugger.Break(); } #endif } TextViewCache.Add(virtualTextDocument, wpfTextView); } Log.Verbose($"{logPrefix} Uri={virtualTextDocument.Uri}"); } } catch (Exception ex) { Log.Error(ex, nameof(SubjectBuffersConnected)); } }
/// <summary> /// SubjectBuffersConnected happens first /// </summary> /// <param name="wpfTextView"></param> /// <param name="reason"></param> /// <param name="subjectBuffers"></param> public void SubjectBuffersConnected(IWpfTextView wpfTextView, ConnectionReason reason, Collection <ITextBuffer> subjectBuffers) { try { if (wpfTextView == null || !wpfTextView.HasValidRoles()) { return; } if (!TextDocumentExtensions.TryGetTextDocument(TextDocumentFactoryService, wpfTextView.TextBuffer, out var textDocument)) { return; } lock (WeakTableLock) { foreach (var buffer in subjectBuffers) { if (!TextBufferTable.TryGetValue(buffer, out HashSet <IWpfTextView> textViews)) { textViews = new HashSet <IWpfTextView>(); TextBufferTable.Add(buffer, textViews); } textViews.Add(wpfTextView); } wpfTextView.Properties.GetOrCreateSingletonProperty(PropertyNames.DocumentMarkerManager, () => new DocumentMarkerManager(CodeStreamAgentServiceFactory.Create(), wpfTextView, textDocument)); wpfTextView.Properties.AddProperty(PropertyNames.TextViewFilePath, textDocument.FilePath); wpfTextView.Properties.AddProperty(PropertyNames.TextViewState, new TextViewState()); #if DEBUG if (TextViewCache == null) { Debugger.Break(); } #endif TextViewCache.Add(textDocument.FilePath, wpfTextView); } Log.Verbose($"{nameof(SubjectBuffersConnected)} FilePath={textDocument.FilePath}"); } catch (Exception ex) { Log.Error(ex, nameof(SubjectBuffersConnected)); } }