internal int Unregister(IVsDropdownBarManager manager) { _textView.Caret.PositionChanged -= CaretPositionChanged; // A buffer may have multiple DropDownBarClients, given one may open multiple CodeWindows // over a single buffer using Window/New Window List <DropDownBarClient> clients; if (_textView.Properties.TryGetProperty(typeof(DropDownBarClient), out clients)) { clients.Remove(this); if (clients.Count == 0) { _textView.Properties.RemoveProperty(typeof(DropDownBarClient)); } } _services.GetBufferInfo(_textView.TextBuffer).OnNewParseTree -= ParserOnNewParseTree; #if DEBUG IVsDropdownBar existing; IVsDropdownBarClient existingClient; if (ErrorHandler.Succeeded(manager.GetDropdownBar(out existing)) && ErrorHandler.Succeeded(existing.GetClient(out existingClient))) { Debug.Assert(existingClient == this, "Unregistering the wrong dropdown client"); } #endif return(manager.RemoveDropdownBar()); }
internal AnalysisEntry GetAnalysisEntry() { var bi = _services.GetBufferInfo(TextBuffer); Debug.Assert(bi?.AnalysisEntry != null, "Failed to get project entry for buffer " + TextBuffer.ToString()); return(bi?.AnalysisEntry); }
public async void VsTextViewCreated(VisualStudio.TextManager.Interop.IVsTextView textViewAdapter) { // TODO: We should probably only track text views in Python projects or loose files. var textView = _services.EditorAdaptersFactoryService.GetWpfTextView(textViewAdapter); if (textView != null) { var analyzer = _services.AnalysisEntryService.GetVsAnalyzer(textView, null); var bi = _services.GetBufferInfo(textView.TextBuffer); if (analyzer != null && bi != null && bi.AnalysisEntry == null) { var entry = await analyzer.AnalyzeFileAsync(bi.Filename); if (bi.TrySetAnalysisEntry(entry, null) != entry) { // Failed to start analyzing Debug.Fail("Failed to analyze xaml file"); return; } await entry.EnsureCodeSyncedAsync(bi.Buffer); textView.Closed += TextView_Closed; } } }
public Task WaitForAnalyzerAsync(ITextBuffer textBuffer, CancellationToken cancellationToken) { if (textBuffer == null) { throw new ArgumentNullException(nameof(textBuffer)); } return(_services.GetBufferInfo(textBuffer).WaitForAnalysisEntryAsync(cancellationToken)); }
internal static ClassificationTypeDefinition BuiltinClassificationDefinition = null; // Set via MEF #endregion #region IDlrClassifierProvider public IClassifier GetClassifier(ITextBuffer buffer) { if (_categoryMap == null) { _categoryMap = FillCategoryMap(_services.ClassificationTypeRegistryService); } return(_services.GetBufferInfo(buffer).GetOrCreateClassifier(b => new PythonClassifier(this, b))); }
public async void VsTextViewCreated(VisualStudio.TextManager.Interop.IVsTextView textViewAdapter) { var textView = _editorAdaptersFactory.GetWpfTextView(textViewAdapter); if (textView == null) { return; } // Only track text views in Python projects (we don't get called for loose files) // For example, we may get called for xaml files in UWP projects, in which case we do nothing if (!IsInPythonProject(textView)) { return; } // Load Python services now that we know we'll need them if (_services == null) { _services = _site.GetComponentModel().GetService <PythonEditorServices>(); if (_services == null) { return; } } var bi = _services.GetBufferInfo(textView.TextBuffer); if (bi == null) { return; } var entry = bi.AnalysisEntry ?? await AnalyzeXamlFileAsync(textView, bi); for (int retries = 3; retries > 0 && entry == null; --retries) { // Likely in the process of changing analyzer, so we'll delay slightly and retry. await Task.Delay(100); entry = bi.AnalysisEntry ?? await AnalyzeXamlFileAsync(textView, bi); } if (entry == null) { Debug.Fail($"Failed to analyze XAML file {bi.Filename}"); return; } if (bi.TrySetAnalysisEntry(entry, null) != entry) { // Failed to start analyzing Debug.Fail("Failed to analyze xaml file"); return; } await entry.EnsureCodeSyncedAsync(bi.Buffer); }
public static Task <AnalysisEntry> GetAnalysisEntryAsync(this ITextBuffer buffer, PythonEditorServices services = null, CancellationToken cancellationToken = default(CancellationToken)) { var bi = services == null?PythonTextBufferInfo.TryGetForBuffer(buffer) : services.GetBufferInfo(buffer); if (bi != null) { return(bi.GetAnalysisEntryAsync(cancellationToken)); } return(Task.FromResult <AnalysisEntry>(null)); }
internal static ClassificationTypeDefinition RegularExpressionClassificationDefinition = null; // Set via MEF #endregion #region IDlrClassifierProvider public IClassifier GetClassifier(ITextBuffer buffer) { if (_categoryMap == null) { _categoryMap = FillCategoryMap(_classificationRegistry); } return(_services.GetBufferInfo(buffer) .GetOrCreateSink(typeof(PythonAnalysisClassifier), _ => new PythonAnalysisClassifier(this))); }
private void BufferGraph_GraphBuffersChanged(object sender, VisualStudio.Text.Projection.GraphBuffersChangedEventArgs e) { foreach (var b in e.RemovedBuffers) { PythonTextBufferInfo.TryGetForBuffer(b)?.RemoveSink(typeof(DropDownBarClient)); } foreach (var b in e.AddedBuffers) { _services.GetBufferInfo(b).AddSink(typeof(DropDownBarClient), this); } }
public PythonSuggestedActionsSource( PythonEditorServices services, ITextView textView, ITextBuffer textBuffer ) { _services = services; _view = textView; _textBuffer = _services.GetBufferInfo(textBuffer); _textBuffer.OnNewAnalysisEntry += OnNewAnalysisEntry; _uiThread = _services.Site.GetUIThread(); }
private static AP.FileUpdate GetUpdateForSnapshot(PythonEditorServices services, ITextSnapshot snapshot) { var buffer = services.GetBufferInfo(snapshot.TextBuffer); if (buffer.DoNotParse || snapshot.IsReplBufferWithCommand() || buffer.AnalysisBufferId < 0) { return(null); } var lastSent = buffer.LastSentSnapshot; if (lastSent?.Version == snapshot.Version) { // this snapshot is up to date... return(null); } // Update last sent snapshot and the analysis cookie to our // current snapshot. buffer.LastSentSnapshot = snapshot; var entry = buffer.AnalysisEntry; if (entry != null) { entry.AnalysisCookie = new SnapshotCookie(snapshot); } if (lastSent == null || lastSent.TextBuffer != buffer.Buffer) { // First time parsing from a live buffer, send the entire // file and set our initial snapshot. We'll roll forward // to new snapshots when we receive the errors event. This // just makes sure that the content is in sync. return(new AP.FileUpdate { content = snapshot.GetText(), version = snapshot.Version.VersionNumber, bufferId = buffer.AnalysisBufferId, kind = AP.FileUpdateKind.reset }); } var versions = GetVersions(lastSent.Version, snapshot.Version).Select(v => new AP.VersionChanges { changes = GetChanges(v) }).ToArray(); return(new AP.FileUpdate() { versions = versions, version = snapshot.Version.VersionNumber, bufferId = buffer.AnalysisBufferId, kind = AP.FileUpdateKind.changes }); }
public bool TryCreateContext(ITextView textView, SnapshotPoint openingPoint, char openingBrace, char closingBrace, out IBraceCompletionContext context) { if (IsValidBraceCompletionContext(EditorServices.GetBufferInfo(openingPoint.Snapshot.TextBuffer), openingPoint)) { context = new BraceCompletionContext(); return(true); } else { context = null; return(false); } }
internal static ClassificationTypeDefinition ModuleClassificationDefinition = null; // Set via MEF #endregion #region IDlrClassifierProvider public IClassifier GetClassifier(ITextBuffer buffer) { if (buffer.Properties.ContainsProperty(typeof(IInteractiveEvaluator))) { return(null); } if (_categoryMap == null) { _categoryMap = FillCategoryMap(_classificationRegistry); } return(_services.GetBufferInfo(buffer).GetOrCreateAnalysisClassifier(b => new PythonAnalysisClassifier(this, b))); }
private void AddMissingImports(List <string> importList, SnapshotPoint point) { if (importList.Count == 0) { return; } var bi = _services.GetBufferInfo(_textView.TextBuffer); var entry = bi?.AnalysisEntry; if (entry == null) { return; } SourceLocation loc; try { var line = point.GetContainingLine(); loc = new SourceLocation( point.Position, line.LineNumber + 1, point.Position - line.Start + 1 ); } catch (ArgumentException ex) { Debug.Fail(ex.ToUnhandledExceptionMessage(GetType())); return; } foreach (var import in importList) { var isMissing = entry.Analyzer.WaitForRequest( entry.Analyzer.IsMissingImportAsync(entry, import, loc), "ExpansionClient.IsMissingImportAsync", false ); if (isMissing) { VsProjectAnalyzer.AddImport( entry, null, import, _textView, _textView.TextBuffer ); } } }
public ISuggestedActionsSource CreateSuggestedActionsSource( ITextView textView, ITextBuffer textBuffer ) { if (textView == null || textBuffer == null) { return(null); } return(_services.GetBufferInfo(textBuffer).GetOrCreateSink( typeof(PythonSuggestedActionsSource), _ => new PythonSuggestedActionsSource(_services) )); }
internal static ClassificationTypeDefinition BuiltinClassificationDefinition = null; // Set via MEF #endregion #region IDlrClassifierProvider public IClassifier GetClassifier(ITextBuffer buffer) { if (_categoryMap == null) { _categoryMap = FillCategoryMap(_services.ClassificationTypeRegistryService); } if (buffer.ContentType.IsOfType(CodeRemoteContentDefinition.CodeRemoteContentTypeName)) { return(null); } return(_services.GetBufferInfo(buffer) .GetOrCreateSink(typeof(PythonClassifier), _ => new PythonClassifier(this))); }
public DropDownBarClient(IServiceProvider serviceProvider, IWpfTextView textView, AnalysisEntry analysisEntry) { Utilities.ArgumentNotNull(nameof(serviceProvider), serviceProvider); Utilities.ArgumentNotNull(nameof(textView), textView); Utilities.ArgumentNotNull(nameof(analysisEntry), analysisEntry); _serviceProvider = serviceProvider; _uiThread = _serviceProvider.GetUIThread(); _services = _serviceProvider.GetComponentModel().GetService <PythonEditorServices>(); _analysisEntry = analysisEntry; _textView = textView; _services.GetBufferInfo(_textView.TextBuffer).OnNewParseTree += ParserOnNewParseTree; _dispatcher = Dispatcher.CurrentDispatcher; _textView.Caret.PositionChanged += CaretPositionChanged; for (int i = 0; i < NavigationLevels; i++) { _curSelection[i] = -1; } }
public async void VsTextViewCreated(VisualStudio.TextManager.Interop.IVsTextView textViewAdapter) { // TODO: We should probably only track text views in Python projects or loose files. var textView = _services.EditorAdaptersFactoryService.GetWpfTextView(textViewAdapter); if (textView == null) { return; } var bi = _services.GetBufferInfo(textView.TextBuffer); if (bi == null) { return; } var entry = bi.AnalysisEntry ?? await AnalyzeXamlFileAsync(textView, bi); for (int retries = 3; retries > 0 && entry == null; --retries) { // Likely in the process of changing analyzer, so we'll delay slightly and retry. await Task.Delay(100); entry = await AnalyzeXamlFileAsync(textView, bi); } if (entry == null) { Debug.Fail($"Failed to analyze XAML file {bi.Filename}"); return; } if (bi.TrySetAnalysisEntry(entry, null) != entry) { // Failed to start analyzing Debug.Fail("Failed to analyze xaml file"); return; } await entry.EnsureCodeSyncedAsync(bi.Buffer); }
public PythonTextBufferInfo GetBuffer(ITextBuffer buffer) { return(buffer == null ? null : _services.GetBufferInfo(buffer)); }
public async Task <bool> ExtractMethod(IExtractMethodInput input) { var buffer = _view.GetPythonBufferAtCaret(); var bi = _services.GetBufferInfo(buffer); var entry = bi?.AnalysisEntry; if (entry?.Analyzer == null) { return(false); } var snapshot = buffer.CurrentSnapshot; // extract once to validate the selection var extract = await entry.Analyzer.ExtractMethodAsync( bi, _view, "method_name", null, null ); if (extract == null) { return(false); } if (extract.cannotExtractMsg != null) { input.CannotExtract(extract.cannotExtractMsg); return(false); } if (extract.wasExpanded && !input.ShouldExpandSelection()) { return(false); } if (extract.startLine > 0 && extract.endLine > 0) { var selectionSpan = _view.BufferGraph.MapUpToBuffer( new SourceSpan( new SourceLocation(extract.startLine, extract.startCol), new SourceLocation(extract.endLine, extract.endCol) ).ToSnapshotSpan(snapshot), SpanTrackingMode.EdgeInclusive, _view.TextBuffer ); foreach (var span in selectionSpan) { _view.Selection.Select(span, false); break; } } var info = input.GetExtractionInfo(new ExtractedMethodCreator(bi, _view, extract)); if (info == null) { // user cancelled extract method return(false); } // extract again to get the final result... extract = await entry.Analyzer.ExtractMethodAsync( bi, _view, info.Name, info.Parameters, info.TargetScope?.Scope.id ); if (extract == null) { return(false); } VsProjectAnalyzer.ApplyChanges( extract.changes, buffer, bi.LocationTracker, extract.version ); return(true); }
public async Task <bool> HasSuggestedActionsAsync(ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken) { var textBuffer = range.Snapshot.TextBuffer; var bi = _services.GetBufferInfo(textBuffer); var entry = bi.AnalysisEntry; if (entry == null) { return(false); } var needSuggestion = new List <SnapshotSpan>(); var tokens = textBuffer.GetPythonClassifier()?.GetClassificationSpans(range); foreach (var t in tokens.MaybeEnumerate()) { if (t.ClassificationType.IsOfType(PredefinedClassificationTypeNames.Identifier)) { var isMissing = await entry.Analyzer.IsMissingImportAsync( entry, t.Span.GetText(), t.Span.Start.ToSourceLocation() ); if (isMissing) { needSuggestion.Add(t.Span); } } } if (!needSuggestion.Any()) { return(false); } var suggestions = new List <SuggestedActionSet>(); foreach (var span in needSuggestion) { var available = await entry.Analyzer.FindNameInAllModulesAsync(span.GetText()); var actions = available.Select(s => new PythonSuggestedImportAction(this, textBuffer, s)) .OrderBy(k => k) .Distinct() .ToArray(); if (actions.Any()) { suggestions.Add(new SuggestedActionSet(actions)); } } if (!suggestions.Any()) { return(false); } cancellationToken.ThrowIfCancellationRequested(); lock (_currentLock) { cancellationToken.ThrowIfCancellationRequested(); _current = suggestions; _currentSpan = range; } return(true); }