/// <summary> /// Gets the analysis entry for the given view. /// /// For files on disk this is pretty easy - we analyze each file on it's own in a buffer parser. /// Therefore we map filename -> analyzer and then get the analysis from the analyzer. If we /// determine an analyzer but the file isn't loaded into it for some reason this would return null. /// We can also apply some policy to buffers depending upon the view that they're hosted in. For /// example if a buffer is outside of any projects, but hosted in a difference view with a buffer /// that is in a project, then we'll look in the view that has the project. /// /// For interactive windows we will use the analyzer that's configured for the window. /// </summary> public bool TryGetAnalysisEntry(ITextView textView, out AnalysisEntry entry) { if (textView == null) { throw new ArgumentNullException(nameof(textView)); } if (TryGetAnalysisEntry(textView.TextBuffer, out entry)) { return(true); } if (textView != null) { // If we have a difference viewer we'll match the LHS w/ the RHS var viewer = _diffService?.TryGetViewerForTextView(textView); if (viewer != null) { if (TryGetAnalysisEntry(viewer.DifferenceBuffer.RightBuffer, out entry)) { return(true); } if (TryGetAnalysisEntry(viewer.DifferenceBuffer.LeftBuffer, out entry)) { return(true); } } } entry = null; return(false); }
/// <summary> /// Tries to get the analyzer and filename of the specified text view. This is /// equivalent to using the view's default text buffer, with some added checks /// for non-standard editors. /// </summary> /// <returns>True if an analyzer and filename are found.</returns> /// <exception cref="ArgumentNullException"><paramref name="textView"/> is null.</exception> public bool TryGetAnalyzer(ITextView textView, out ProjectAnalyzer analyzer, out string filename) { if (textView == null) { throw new ArgumentNullException(nameof(textView)); } // Try to get the analyzer from the main text buffer if (TryGetAnalyzer(textView.TextBuffer, out analyzer, out filename)) { return(true); } // If we have a difference viewer we'll match the LHS w/ the RHS var viewer = _diffService?.TryGetViewerForTextView(textView); if (viewer != null) { if (TryGetAnalyzer(viewer.DifferenceBuffer.RightBuffer, out analyzer, out filename)) { return(true); } if (TryGetAnalyzer(viewer.DifferenceBuffer.LeftBuffer, out analyzer, out filename)) { return(true); } } return(false); }
/// <summary> /// Gets the best analyzer for this text view, accounting for things like REPL windows and /// difference windows. /// </summary> internal static VsProjectAnalyzer GetBestAnalyzer(this ITextView textView, IServiceProvider serviceProvider) { // If we have set an analyzer explicitly, return that VsProjectAnalyzer analyzer = null; if (textView.TextBuffer.Properties.TryGetProperty(typeof(VsProjectAnalyzer), out analyzer)) { return(analyzer); } // If we have a REPL evaluator we'll use it's analyzer var evaluator = textView.TextBuffer.GetInteractiveWindow()?.Evaluator as IPythonInteractiveIntellisense; if (evaluator != null) { return(evaluator.Analyzer); } // If we have a difference viewer we'll match the LHS w/ the RHS IWpfDifferenceViewerFactoryService diffService = null; try { diffService = serviceProvider.GetComponentModel().GetService <IWpfDifferenceViewerFactoryService>(); } catch (System.ComponentModel.Composition.CompositionException) { } catch (System.ComponentModel.Composition.ImportCardinalityMismatchException) { } if (diffService != null) { var viewer = diffService.TryGetViewerForTextView(textView); if (viewer != null) { var entry = GetAnalysisEntry(null, viewer.DifferenceBuffer.LeftBuffer, serviceProvider) ?? GetAnalysisEntry(null, viewer.DifferenceBuffer.RightBuffer, serviceProvider); if (entry != null) { return(entry.Analyzer); } } } return(serviceProvider.GetPythonToolsService().DefaultAnalyzer); }
//public void SetAnalyzer(ITextBuffer textBuffer, VsProjectAnalyzer analyzer) { // if (textBuffer == null) { // throw new ArgumentNullException(nameof(textBuffer)); // } // // if (analyzer == null) { // textBuffer.Properties.RemoveProperty(typeof(VsProjectAnalyzer)); // return; // } // // textBuffer.Properties[typeof(VsProjectAnalyzer)] = analyzer; // // TaskCompletionSource<object> tcs; // if (textBuffer.Properties.TryGetProperty(_waitForAnalyzerKey, out tcs)) { // tcs.TrySetResult(null); // textBuffer.Properties.RemoveProperty(_waitForAnalyzerKey); // } //} /// <summary> /// Gets the analysis entry for the given view and buffer. /// /// For files on disk this is pretty easy - we analyze each file on it's own in a buffer parser. /// Therefore we map filename -> analyzer and then get the analysis from the analyzer. If we /// determine an analyzer but the file isn't loaded into it for some reason this would return null. /// We can also apply some policy to buffers depending upon the view that they're hosted in. For /// example if a buffer is outside of any projects, but hosted in a difference view with a buffer /// that is in a project, then we'll look in the view that has the project. /// /// For interactive windows we will use the analyzer that's configured for the window. /// </summary> public bool TryGetAnalysisEntry(ITextView textView, ITextBuffer textBuffer, out AnalysisEntry entry) { var bi = PythonTextBufferInfo.TryGetForBuffer(textBuffer ?? textView?.TextBuffer); if (bi == null && textView != null) { // If we have a difference viewer we'll match the LHS w/ the RHS var viewer = _diffService?.TryGetViewerForTextView(textView); if (viewer != null) { if (TryGetAnalysisEntry(viewer.DifferenceBuffer.RightBuffer, out entry)) { return(true); } if (TryGetAnalysisEntry(viewer.DifferenceBuffer.LeftBuffer, out entry)) { return(true); } } } entry = bi?.AnalysisEntry; return(entry != null); }