public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (!EnsureTreeInitialized() || session == null || qiContent == null) return; SnapshotPoint? point = session.GetTriggerPoint(_buffer.CurrentSnapshot); if (!point.HasValue) return; ParseItem item = _tree.StyleSheet.ItemBeforePosition(point.Value.Position); if (item == null || !item.IsValid) return; UrlItem urlItem = item.FindType<UrlItem>(); if (urlItem != null && urlItem.UrlString != null && urlItem.UrlString.IsValid) { string url = GetFileName(urlItem.UrlString.Text.Trim('\'', '"')); if (!string.IsNullOrEmpty(url)) { applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(point.Value.Position, 1, SpanTrackingMode.EdgeNegative); var image = CreateImage(url); if (image != null && image.Source != null) { qiContent.Add(image); qiContent.Add(Math.Round(image.Source.Width) + "x" + Math.Round(image.Source.Height)); } } } }
/// <summary> /// Determine which pieces of Quickinfo content should be displayed /// </summary> public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (_disposed) throw new ObjectDisposedException("TestQuickInfoSource"); var triggerPoint = (SnapshotPoint) session.GetTriggerPoint(_buffer.CurrentSnapshot); if (triggerPoint == null) return; foreach (IMappingTagSpan<LuaTokenTag> curTag in _aggregator.GetTags(new SnapshotSpan(triggerPoint, triggerPoint))) { if (curTag.Tag.type == LuaTokenTypes.ReservedWord) { var tagSpan = curTag.Span.GetSpans(_buffer).First(); applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); quickInfoContent.Add("A reserved word"); } else if (curTag.Tag.type == LuaTokenTypes.Operators) { var tagSpan = curTag.Span.GetSpans(_buffer).First(); applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); quickInfoContent.Add("A language operator"); } } }
public void AugmentQuickInfoSession( IQuickInfoSession session, IList<object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; SnapshotPoint? subjectTriggerPoint = session.GetTriggerPoint(textBuffer.CurrentSnapshot); if ( !subjectTriggerPoint.HasValue ) { return; } ITextSnapshot currentSnapshot = subjectTriggerPoint.Value.Snapshot; SnapshotSpan querySpan = new SnapshotSpan(subjectTriggerPoint.Value, 0); var tagAggregator = GetAggregator(session); TextExtent extent = FindExtentAtPoint(subjectTriggerPoint); if ( CheckForPrefixTag(tagAggregator, extent.Span) ) { string text = extent.Span.GetText(); string url = FindNSUri(extent.Span, GetDocText(extent.Span)); applicableToSpan = currentSnapshot.CreateTrackingSpan( extent.Span, SpanTrackingMode.EdgeInclusive ); String toolTipText = String.Format("Prefix: {0}\r\nNamespace: {1}", text, url); quickInfoContent.Add(toolTipText); } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; var triggerPoint = (SnapshotPoint)session.GetTriggerPoint(_buffer.CurrentSnapshot); if (triggerPoint == null) return; // find each span that looks like a token and look it up in the dictionary foreach (IMappingTagSpan<PkgDefTokenTag> curTag in _aggregator.GetTags(new SnapshotSpan(triggerPoint, triggerPoint))) { if (curTag.Tag.type == PkgDefLanguageTokens.Token) { SnapshotSpan tagSpan = curTag.Span.GetSpans(_buffer).First(); if (PkgDefTokenTagger.ValidTokens.Keys.Contains(tagSpan.GetText())) { applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); string quickInfo = PkgDefTokenTagger.ValidTokens[tagSpan.GetText()]; System.Diagnostics.Debug.WriteLine(quickInfo); quickInfoContent.Add(quickInfo); } } } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (session == null || qiContent == null) return; // Map the trigger point down to our buffer. SnapshotPoint? point = session.GetTriggerPoint(_buffer.CurrentSnapshot); if (!point.HasValue) return; var snapshot = _buffer.CurrentSnapshot; var classifier = _classifierService.GetClassifier(_buffer); var doc = new SnapshotSpan(snapshot, 0, snapshot.Length); var line = point.Value.GetContainingLine(); var idents = classifier.GetClassificationSpans(line.Extent); bool handled = HandleVariables(qiContent, ref applicableToSpan, idents, point); if (handled) return; HandleKeywords(qiContent, ref applicableToSpan, idents, point); }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (session == null || qiContent == null) return; // Map the trigger point down to our buffer. SnapshotPoint? point = session.GetTriggerPoint(_buffer.CurrentSnapshot); if (!point.HasValue) return; JSONEditorDocument doc = JSONEditorDocument.FromTextBuffer(_buffer); JSONParseItem item = doc.JSONDocument.ItemBeforePosition(point.Value.Position); if (item == null || !item.IsValid) return; JSONMember dependency = item.FindType<JSONMember>(); if (dependency == null || dependency.Name != item) return; var parent = dependency.Parent.FindType<JSONMember>(); if (parent == null || !parent.UnquotedNameText.EndsWith("dependencies", StringComparison.OrdinalIgnoreCase)) return; applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(item.Start, item.Length, SpanTrackingMode.EdgeNegative); UIElement element = CreateTooltip(dependency.UnquotedNameText, item); if (element != null) qiContent.Add(element); }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; var semanticModelResult = SemanticModelService.SemanticModelResult; if (semanticModelResult == null) { return; } // Map the trigger point down to our buffer. SnapshotPoint? subjectTriggerPoint = session.GetTriggerPoint(semanticModelResult.Snapshot); if (!subjectTriggerPoint.HasValue) { return; } var triggerSymbol = semanticModelResult.CompilationUnit.Symbols.FindAtPosition(subjectTriggerPoint.Value.Position); if (triggerSymbol == null) { return; } foreach(var content in SymbolQuickInfoBuilder.Build(triggerSymbol, SyntaxQuickinfoBuilderService)) { qiContent.Add(content); } var location = triggerSymbol.Location; applicableToSpan = semanticModelResult.Snapshot.CreateTrackingSpan( location.Start, location.Length, SpanTrackingMode.EdgeExclusive); }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; object eventHookupValue; if (quickInfoContent.Count != 0 || session.Properties.TryGetProperty(QuickInfoUtilities.EventHookupKey, out eventHookupValue)) { // No quickinfo if it's the event hookup popup. return; } var position = session.GetTriggerPoint(_subjectBuffer.CurrentSnapshot); if (position.HasValue) { var textView = session.TextView; var args = new InvokeQuickInfoCommandArgs(textView, _subjectBuffer); Controller controller; if (_commandHandler.TryGetController(args, out controller)) { controller.InvokeQuickInfo(position.Value, trackMouse: true, augmentSession: session); } } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (session == null || qiContent == null || qiContent.Count > 0) return; // Map the trigger point down to our buffer. SnapshotPoint? point = session.GetTriggerPoint(_buffer.CurrentSnapshot); if (!point.HasValue) return; var doc = JSONEditorDocument.FromTextBuffer(_buffer); JSONParseItem item = doc.JSONDocument.ItemBeforePosition(point.Value.Position); if (item == null || !item.IsValid) return; JSONMember member = item.FindType<JSONMember>(); if (member == null || member.Name == null) return; IJSONSchema schema = _schemaResolver.DetermineSchemaForTextBuffer(_buffer); if (schema != null) { IJSONSchemaPropertyNameCompletionInfo info = GetInfo(schema, member); if (info != null && !string.IsNullOrEmpty(info.PropertyDocumentation)) { applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(item.Start, item.Length, SpanTrackingMode.EdgeNegative); qiContent.Add(info.DisplayText + Environment.NewLine + info.PropertyDocumentation); } } }
/// <summary> /// Determine which pieces of Quickinfo content should be displayed /// </summary> public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (_disposed) throw new ObjectDisposedException("TestQuickInfoSource"); var triggerPoint = (SnapshotPoint) session.GetTriggerPoint(_buffer.CurrentSnapshot); if (triggerPoint == null) return; foreach (IMappingTagSpan<OokTokenTag> curTag in _aggregator.GetTags(new SnapshotSpan(triggerPoint, triggerPoint))) { if (curTag.Tag.type == OokTokenTypes.OokExclamation) { var tagSpan = curTag.Span.GetSpans(_buffer).First(); applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); quickInfoContent.Add("Exclaimed Ook!"); } else if (curTag.Tag.type == OokTokenTypes.OokQuestion) { var tagSpan = curTag.Span.GetSpans(_buffer).First(); applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); quickInfoContent.Add("Question Ook?"); } else if (curTag.Tag.type == OokTokenTypes.OokPeriod) { var tagSpan = curTag.Span.GetSpans(_buffer).First(); applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); quickInfoContent.Add("Regular Ook."); } } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (!EnsureTreeInitialized() || session == null || qiContent == null) return; // Map the trigger point down to our buffer. SnapshotPoint? point = session.GetTriggerPoint(_buffer.CurrentSnapshot); if (!point.HasValue) return; ParseItem item = _tree.StyleSheet.ItemBeforePosition(point.Value.Position); if (item == null || !item.IsValid) return; RuleSet rule = item.FindType<RuleSet>(); if (rule == null) return; applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(item.Start, item.Length, SpanTrackingMode.EdgeNegative); var fileName = _buffer.GetFileName().ToLowerInvariant(); var unmatchedEntry = UsageRegistry.GetAllUnusedRules().FirstOrDefault(x => x.File == fileName && x.Is(rule)); if(unmatchedEntry == null) { return; } qiContent.Add("No usages of this rule have been found"); }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> quickInfoContent, out ITrackingSpan applicableToSpan) { if (session == null) { throw new ArgumentNullException("session"); } if (quickInfoContent == null) { throw new ArgumentNullException("quickInfoContent"); } TemplateAnalysis analysis = this.analyzer.CurrentAnalysis; SnapshotPoint? triggerPoint = session.GetTriggerPoint(analysis.TextSnapshot); if (triggerPoint != null && analysis.Template != null) { string description; Span applicableTo; if (analysis.Template.TryGetDescription(triggerPoint.Value.Position, out description, out applicableTo)) { quickInfoContent.Add(description); applicableToSpan = analysis.TextSnapshot.CreateTrackingSpan(applicableTo, SpanTrackingMode.EdgeExclusive); return; } } applicableToSpan = null; }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (!EnsureTreeInitialized() || session == null || qiContent == null) return; // Map the trigger point down to our buffer. SnapshotPoint? point = session.GetTriggerPoint(_buffer.CurrentSnapshot); if (!point.HasValue) return; ParseItem item = _tree.StyleSheet.ItemBeforePosition(point.Value.Position); if (item == null || !item.IsValid) return; Declaration dec = item.FindType<Declaration>(); if (dec == null || !dec.IsValid || !_allowed.Contains(dec.PropertyName.Text.ToUpperInvariant())) return; string fontName = item.Text.Trim('\'', '"'); if (fonts.Families.SingleOrDefault(f => f.Name.Equals(fontName, StringComparison.OrdinalIgnoreCase)) != null) { FontFamily font = new FontFamily(fontName); applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(item.Start, item.Length, SpanTrackingMode.EdgeNegative); qiContent.Add(CreateFontPreview(font, 10)); qiContent.Add(CreateFontPreview(font, 11)); qiContent.Add(CreateFontPreview(font, 12)); qiContent.Add(CreateFontPreview(font, 14)); qiContent.Add(CreateFontPreview(font, 25)); qiContent.Add(CreateFontPreview(font, 40)); } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; var modifier = ModifierKeys.Control | ModifierKeys.Shift; if((Keyboard.Modifiers & modifier) != modifier) { return; } var parseResult = ParserService.ParseResult; if (parseResult == null) { return; } // Map the trigger point down to our buffer. SnapshotPoint? subjectTriggerPoint = session.GetTriggerPoint(parseResult.Snapshot); if(!subjectTriggerPoint.HasValue) { return; } var triggerToken = parseResult.SyntaxTree.Tokens.FindAtPosition(subjectTriggerPoint.Value.Position); if(triggerToken.IsMissing || triggerToken.Parent == null) { return; } var location = triggerToken.GetLocation(); qiContent.Add($"{triggerToken.Type} ({triggerToken.Classification}) Ln {location?.StartLine + 1} Ch {location?.StartCharacter + 1}\r\n{triggerToken.Parent?.GetType().Name}"); applicableToSpan = parseResult.Snapshot.CreateTrackingSpan( triggerToken.Start, triggerToken.Length, SpanTrackingMode.EdgeExclusive); }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; SnapshotPoint? point = session.GetTriggerPoint(session.TextView.TextBuffer.CurrentSnapshot); if (!point.HasValue) return; HtmlEditorTree tree = HtmlEditorDocument.FromTextView(session.TextView).HtmlEditorTree; ElementNode node = null; AttributeNode attr = null; tree.GetPositionElement(point.Value.Position, out node, out attr); if (node == null || !node.Name.Equals("img", StringComparison.OrdinalIgnoreCase)) return; if (attr == null || !attr.Name.Equals("src", StringComparison.OrdinalIgnoreCase)) return; string url = ImageQuickInfo.GetFullUrl(attr.Value, session.TextView.TextBuffer); if (string.IsNullOrEmpty(url)) return; applicableToSpan = session.TextView.TextBuffer.CurrentSnapshot.CreateTrackingSpan(point.Value.Position, 1, SpanTrackingMode.EdgeNegative); ImageQuickInfo.AddImageContent(qiContent, url); }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> quickInfoContent, out ITrackingSpan applicableToSpan) { SnapshotPoint? triggerPoint = session.GetTriggerPoint(TextBuffer.CurrentSnapshot); if (!triggerPoint.HasValue) { applicableToSpan = null; return; } JavaQuickInfo qi = null; if (session.Properties.TryGetProperty<JavaQuickInfo>(typeof(JavaQuickInfo), out qi)) { //quickInfoContent.Clear(); foreach (var o in qi.QuickInfoContent) { var display = o; if (display.Contains("{")) display = display.Substring(0, display.IndexOf("{")); if (display.Contains("[in")) display = display.Substring(0, display.IndexOf("[in")); //quickInfoContent.Add(o); quickInfoContent.Add(display); // TODO: Workaround to only show the declaration of the type and not the full location string } // Get whole word under point ITextStructureNavigator navigator = Provider.NavigatorService.GetTextStructureNavigator(TextBuffer); TextExtent extent = navigator.GetExtentOfWord(triggerPoint.Value); applicableToSpan = triggerPoint.Value.Snapshot.CreateTrackingSpan(extent.Span, SpanTrackingMode.EdgeInclusive); } else applicableToSpan = null; }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; var triggerPoint = session.GetTriggerPoint(buffer.CurrentSnapshot); if (triggerPoint == null) return; ITextDocument doc; if (!provider.TextDocumentFactoryService.TryGetTextDocument(buffer, out doc)) return; IOutputWindowPane diagnostics = provider.OutputWindowService.TryGetPane(OutputWindowPanes.DartVSDiagnostics); if (diagnostics != null) diagnostics.WriteLine("Quick info requested for: " + doc.FilePath); // Figure out if this is a recalculate for an existing span (not sure if this is the best way of supporting async...?) if (inProgressPosition != null && inProgressPosition.Value == triggerPoint.Value.Position) { UpdateTooltip(session, quickInfoContent, out applicableToSpan); } else { applicableToSpan = GetApplicableToSpan(triggerPoint); var ignoredTask = StartTooltipRequestAsync(session, quickInfoContent, applicableToSpan, triggerPoint, doc.FilePath); } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (!EnsureTreeInitialized() || session == null || qiContent == null) return; // Map the trigger point down to our buffer. SnapshotPoint? point = session.GetTriggerPoint(_buffer.CurrentSnapshot); if (!point.HasValue) return; ParseItem item = _tree.StyleSheet.ItemBeforePosition(point.Value.Position); if (item == null || !item.IsValid) return; Selector sel = item.FindType<Selector>(); if (sel == null) return; // Mixins don't have specificity if (sel.SimpleSelectors.Count == 1 && sel.SimpleSelectors[0].SubSelectors.Count == 1 && sel.SimpleSelectors[0].SubSelectors[0] is LessMixinDeclaration) return; applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(item.Start, item.Length, SpanTrackingMode.EdgeNegative); string content = GenerateContent(sel); qiContent.Add(content); }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (session == null || qiContent == null || qiContent.Count > 0 || !WESettings.GetBoolean(WESettings.Keys.ShowBrowserTooltip)) return; SnapshotPoint? point = session.GetTriggerPoint(_buffer.CurrentSnapshot); if (!point.HasValue) return; var tree = CssEditorDocument.FromTextBuffer(_buffer); ParseItem item = tree.StyleSheet.ItemBeforePosition(point.Value.Position); if (item == null || !item.IsValid) return; ICssSchemaInstance schema = CssSchemaManager.SchemaManager.GetSchemaForItem(_rootSchema, item); Tuple<ParseItem, ICssCompletionListEntry> tuple = GetEntriesAndPoint(item, point.Value, schema); if (tuple == null) return; ParseItem tipItem = tuple.Item1; ICssCompletionListEntry entry = tuple.Item2; if (tipItem == null || entry == null) return; var ruleSet = item.FindType<RuleSet>(); //If the selector's full name would require computation (it's nested), compute it and add it to the output if (ruleSet != null && ruleSet.Parent.FindType<RuleSet>() != null) { qiContent.Add(LessDocument.GetLessSelectorName(ruleSet)); } applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(tipItem.Start, tipItem.Length, SpanTrackingMode.EdgeNegative); string syntax = entry.GetSyntax(schema.Version); string b = entry.GetAttribute("browsers"); if (string.IsNullOrEmpty(b) && tipItem.Parent != null && tipItem.Parent is Declaration) { b = schema.GetProperty(((Declaration)tipItem.Parent).PropertyName.Text).GetAttribute("browsers"); if (string.IsNullOrEmpty(syntax)) syntax = tipItem.Text; } if (!string.IsNullOrEmpty(syntax)) { //var example = CreateExample(syntax); qiContent.Add("Example: " + syntax); } Dictionary<string, string> browsers = GetBrowsers(b); qiContent.Add(CreateBrowserList(browsers)); }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (_disposed) throw new ObjectDisposedException("TestQuickInfoSource"); var triggerPoint = (SnapshotPoint) session.GetTriggerPoint(_buffer.CurrentSnapshot); if (triggerPoint == null) return; foreach (IMappingTagSpan<ClassificationTag> curTag in _aggregator.GetTags(new SnapshotSpan(triggerPoint, triggerPoint))) { if (curTag.Tag.ClassificationType.Classification == "table") { //var tagSpan = curTag.Span.GetSpans(_buffer).First(); //applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); //quickInfoContent.Add("Lua table no need comment"); } else if (curTag.Tag.ClassificationType.Classification == "function") { //find table name for it var tagSpan = curTag.Span.GetSpans(_buffer).First(); applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); var start = tagSpan.Start; string function = tagSpan.GetText(); string table = "_G"; if (start.Position > 1) { start -= 1; char ch = start.GetChar(); if (ch == '.' || ch == ':') { var pos = start; while (pos.Position > 0 && Help.is_word_char((pos - 1).GetChar())) { pos -= 1; } ITextSnapshot snapshot = _buffer.CurrentSnapshot; table = snapshot.GetText(pos.Position, start.Position - pos.Position); } } var s = Help.Instance.GetTableFunctionComment(table, function); if(s == "") s = ("Lua function"); quickInfoContent.Add(s); } } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> quickInfoContent, out ITrackingSpan applicableToSpan) { ITextSnapshot snapshot = _buffer.CurrentSnapshot; ITrackingPoint triggerPoint = session.GetTriggerPoint(_buffer); SnapshotPoint point = triggerPoint.GetPoint(snapshot); SyntaxTree syntax = snapshot.GetSyntaxTree(); RobotsTxtDocumentSyntax root = syntax.Root as RobotsTxtDocumentSyntax; applicableToSpan = null; // find section RobotsTxtLineSyntax line = root.Records .SelectMany(r => r.Lines) .FirstOrDefault(s => s.NameToken.Span.Span.Contains(point)); if (line != null) { IClassificationFormatMap formatMap = _classificationFormatMapService.GetClassificationFormatMap(session.TextView); string fieldName = line.NameToken.Value; // get glyph var glyph = _glyphService.GetGlyph(StandardGlyphGroup.GlyphGroupProperty, StandardGlyphItem.GlyphItemPublic); var classificationType = _classificationRegistry.GetClassificationType("RobotsTxt/RecordName"); var format = formatMap.GetTextProperties(classificationType); // construct content ISemanticModel model = syntax.GetSemanticModel(); var field = model.GetFieldSymbol(line); var content = new QuickInfoContent { Glyph = glyph, Signature = new Run(field.Name) { Foreground = format.ForegroundBrush }, Documentation = RobotsTxtDocumentation.GetDocumentation(field), }; // add to session quickInfoContent.Add( new ContentPresenter { Content = content, ContentTemplate = Template, } ); applicableToSpan = snapshot.CreateTrackingSpan(line.NameToken.Span.Span, SpanTrackingMode.EdgeInclusive); return; } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (session == null || qiContent == null) return; // Map the trigger point down to our buffer. SnapshotPoint? point = session.GetTriggerPoint(_buffer.CurrentSnapshot); if (!point.HasValue) return; var tree = CssEditorDocument.FromTextBuffer(_buffer); ParseItem item = tree.StyleSheet.ItemBeforePosition(point.Value.Position); if (item == null || !item.IsValid) return; Selector sel = item.FindType<Selector>(); if (sel == null) return; // Mixins don't have specificity if (sel.SimpleSelectors.Count == 1) { var subSelectors = sel.SimpleSelectors[0].SubSelectors; if (subSelectors.Count == 1 && subSelectors[0] is LessMixinDeclaration && subSelectors[0] is ScssMixinDeclaration) return; } applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(item.Start, item.Length, SpanTrackingMode.EdgeNegative); if (_buffer.ContentType.DisplayName.Equals("css", StringComparison.OrdinalIgnoreCase)) { qiContent.Add(GenerateContent(sel)); return; } HandlePreprocessor(session, point.Value, item.FindType<Selector>(), qiContent); }
/// <summary> /// Generates the tooltip text /// </summary> /// <param name="session"></param> /// <param name="applicableToSpan"></param> /// <returns></returns> /// <remarks>the quick info session will be automatically dismissed /// when mouse cursor leaves the 'applicable to' span. The size of the span is /// calculated based on the size of the nodes supplying the info to be shown /// </remarks> public ReadOnlyCollection<object> GetToolTipContent(IQuickInfoSession session, out ITrackingSpan applicableToSpan) { StringBuilder message = new StringBuilder(); int position = textBuffer.CurrentSnapshot.Length; int length = 0; SnapshotPoint point = session.GetTriggerPoint(textBuffer).GetPoint(textBuffer.CurrentSnapshot); List<DesignerNode> quickInfoNodes = nodeProvider .GetNodes(point, node => node.NodeType != NodeType.ParsingContext); if (quickInfoNodes.Count > 0 && !session.Properties.ContainsProperty(typeof(Source))) { string errorSeparator = "\nError:"; quickInfoNodes.ForEach( node => { // include the node description at the top of the list if (!String.IsNullOrEmpty(node.Description)) message.Insert(0, node.Description + "\n"); if (node.ErrorMessage.Severity >= 0) { // include the error message text at the bottom message.Append(errorSeparator + "\n\t" + node.ErrorMessage.Message); errorSeparator = ""; } if (node.SnapshotSpan.Length > length) length = node.SnapshotSpan.Length; if (node.SnapshotSpan.Start < position) position = node.SnapshotSpan.Start; } ); session.Properties.AddProperty(typeof(Source), null); } applicableToSpan = session.TextView.TextBuffer.CurrentSnapshot.CreateTrackingSpan( position, length, Microsoft.VisualStudio.Text.SpanTrackingMode.EdgeExclusive); if (message.Length > 0) return new ReadOnlyCollection<object>(new string[] { message.ToString() }); else return null; }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; var triggerPoint = session.GetTriggerPoint(textView.TextSnapshot); if (triggerPoint == null) return; var tagSpan = UriHelper.GetUri(viewTagAggregatorFactoryService, textView, triggerPoint.Value); if (tagSpan == null) return; if (!tagSpan.Tag.Url.IsAbsoluteUri) return; var spans = tagSpan.Span.GetSpans(textView.TextSnapshot); if (spans.Count != 1) return; var span = spans[0]; applicableToSpan = span.Snapshot.CreateTrackingSpan(span, SpanTrackingMode.EdgeInclusive); quickInfoContent.Add(tagSpan.Tag.Url.AbsoluteUri + "\r\n" + dnSpy_Resources.UriFollowLinkMessage); }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> qiContent, out ITrackingSpan applicableToSpan) { // Map the trigger point down to our buffer. SnapshotPoint? subjectTriggerPoint = session.GetTriggerPoint(m_subjectBuffer.CurrentSnapshot); if (!subjectTriggerPoint.HasValue) { applicableToSpan = null; return; } ITextSnapshot currentSnapshot = subjectTriggerPoint.Value.Snapshot; SnapshotSpan querySpan = new SnapshotSpan(subjectTriggerPoint.Value, 0); //look for occurrences of our QuickInfo words in the span ITextStructureNavigator navigator = m_provider.NavigatorService.GetTextStructureNavigator(m_subjectBuffer); TextExtent extent = navigator.GetExtentOfWord(subjectTriggerPoint.Value); string searchText = extent.Span.GetText(); foreach (string key in m_dictionary.Keys) { int foundIndex = searchText.IndexOf(key, StringComparison.CurrentCultureIgnoreCase); if (foundIndex > -1) { applicableToSpan = currentSnapshot.CreateTrackingSpan ( //querySpan.Start.Add(foundIndex).Position, 9, SpanTrackingMode.EdgeInclusive extent.Span.Start + foundIndex, key.Length, SpanTrackingMode.EdgeInclusive ); string value; m_dictionary.TryGetValue(key, out value); if (value != null) qiContent.Add(value); else qiContent.Add(""); return; } } applicableToSpan = null; }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; SnapshotPoint? triggerPoint = session.GetTriggerPoint(_subjectBuffer.CurrentSnapshot); if (triggerPoint.HasValue) { int position = triggerPoint.Value; if (_lastPosition != position) { _lastPosition = position; ITextSnapshot snapshot = triggerPoint.Value.Snapshot; IREditorDocument document = REditorDocument.TryFromTextBuffer(_subjectBuffer); if (document != null) { // Document may be null in REPL window as projections are not // getting set immediately or may change as user moves mouse over. AugmentQuickInfoSession(document.EditorTree.AstRoot, position, session, quickInfoContent, out applicableToSpan, (object o, string p) => RetriggerQuickInfoSession(o as IQuickInfoSession, p), null); } } } }
/// <summary> /// Determines which pieces of QuickInfo content should be part of the specified <see cref="T:Microsoft.VisualStudio.Language.Intellisense.IQuickInfoSession"/>. /// </summary> /// <param name="session">The session for which completions are to be computed.</param> /// <param name="quickInfoContent">The QuickInfo content to be added to the session.</param> /// <param name="applicableToSpan">The <see cref="T:Microsoft.VisualStudio.Text.ITrackingSpan"/> to which this session applies.</param> /// <remarks> /// Each applicable <see cref="M:Microsoft.VisualStudio.Language.Intellisense.IQuickInfoSource.AugmentQuickInfoSession(Microsoft.VisualStudio.Language.Intellisense.IQuickInfoSession,System.Collections.Generic.IList{System.Object},Microsoft.VisualStudio.Text.ITrackingSpan@)"/> instance will be called in-order to (re)calculate a /// <see cref="T:Microsoft.VisualStudio.Language.Intellisense.IQuickInfoSession"/>. Objects can be added to the session by adding them to the quickInfoContent collection /// passed-in as a parameter. In addition, by removing items from the collection, a source may filter content provided by /// <see cref="T:Microsoft.VisualStudio.Language.Intellisense.IQuickInfoSource"/>s earlier in the calculation chain. /// </remarks> public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> quickInfoContent, out ITrackingSpan applicableToSpan) { // Map the trigger point down to our buffer. SnapshotPoint? triggerPoint = session.GetTriggerPoint(_buffer.CurrentSnapshot); applicableToSpan = null; if (!triggerPoint.HasValue) { return; } foreach (var token in _parser.GetTokens(new SnapshotSpan(triggerPoint.Value, triggerPoint.Value))) { applicableToSpan = token.Span; if (!quickInfoContent.Contains(token.TarnslationsString)) { quickInfoContent.Insert(0, token.TarnslationsString); } } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (_disposed) throw new ObjectDisposedException("TestQuickInfoSource"); var triggerPoint = (SnapshotPoint)session.GetTriggerPoint(_buffer.CurrentSnapshot); if (triggerPoint == null) return; foreach (IMappingTagSpan<JetTokenTag> curTag in _aggregator.GetTags(new SnapshotSpan(triggerPoint, triggerPoint))) { if (curTag.Tag.type == JetTokenTypes.JetType) { var tagSpan = curTag.Span.GetSpans(_buffer).First(); applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); quickInfoContent.Add(tagSpan.GetText()); } else if (curTag.Tag.type == JetTokenTypes.JetName) { var tagSpan = curTag.Span.GetSpans(_buffer).First(); applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); //look it up yo //string path = GetFilePath(_buffer); //need to somehow pass the filename var path = GetFilePath(this._buffer); var name = Path.GetFileName(path); var symbol = tagSpan.GetText(); if (symbol != " ") { var res = GetSymbolInfo(path, name, symbol, tagSpan.Snapshot.GetLineFromPosition(tagSpan.Span.Start).LineNumber + 1); string info = Marshal.PtrToStringAnsi(res); quickInfoContent.Add(info); } } } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; var triggerPoint = (SnapshotPoint)session.GetTriggerPoint(_buffer.CurrentSnapshot); if (triggerPoint == null) return; foreach (IMappingTagSpan<DafnyTokenTag> curTag in _aggregator.GetTags(new SnapshotSpan(triggerPoint, triggerPoint))) { var s = curTag.Tag.HoverText; if (s != null) { var tagSpan = curTag.Span.GetSpans(_buffer).First(); applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); quickInfoContent.Add(s); } } if (applicableToSpan == null) TacnyLanguage.TacticsHoverText.TestForAndAddHoverText(ref applicableToSpan, triggerPoint, _buffer, quickInfoContent); }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if ( !provider.Settings.RainbowToolTipsEnabled ) { return; } SnapshotPoint? triggerPoint = session.GetTriggerPoint(textBuffer.CurrentSnapshot); if ( !triggerPoint.HasValue ) { return; } SnapshotPoint? otherBrace; if ( !FindOtherBrace(triggerPoint.Value, out otherBrace) ) { // triggerPoint is not a brace return; } if ( !otherBrace.HasValue ) { TextEditor.DisplayMessageInStatusBar("No matching brace found."); return; } if ( IsTooClose(triggerPoint.Value, otherBrace.Value) ) { return; } session.Dismissed += OnSessionDismissed; if ( toolTipWindow == null ) { toolTipWindow = this.provider.ToolTipProvider.CreateToolTip(session.TextView); toolTipWindow.SetSize(60, 5); } var span = new SnapshotSpan(triggerPoint.Value, 1); applicableToSpan = span.Snapshot.CreateTrackingSpan(span, SpanTrackingMode.EdgePositive); var element = toolTipWindow.GetWindow(otherBrace.Value); if ( element != null ) { quickInfoContent.Add(element); session.Set(new RainbowToolTipContext()); } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; // Map the trigger point down to our buffer. SnapshotPoint?subjectTriggerPoint = session.GetTriggerPoint(m_textBuffer.CurrentSnapshot); if (!subjectTriggerPoint.HasValue) { return; } ITextSnapshot currentSnapshot = subjectTriggerPoint.Value.Snapshot; SnapshotSpan querySpan = new SnapshotSpan(subjectTriggerPoint.Value, 0); //look for occurrences of our QuickInfo words in the span ITextStructureNavigator navigator = m_provider.NavigatorService.GetTextStructureNavigator(m_textBuffer); TextExtent extent = navigator.GetExtentOfWord(subjectTriggerPoint.Value); var spans = m_classifier.GetClassificationSpans(extent.Span); var textView = session.TextView as IWpfTextView; SimpleAdroner box = null; if (textView != null) { if (textView.Properties.TryGetProperty(typeof(SimpleAdroner), out box)) { box.CleanUp(); } } if (box != null && spans.Count != 0) { var spobj = (HurunaClassificationSpan)spans.FirstOrDefault(sp => sp is HurunaClassificationSpan); if (spobj != null && spobj.Definition != null) { applicableToSpan = currentSnapshot.CreateTrackingSpan( querySpan.Start.Position, querySpan.Length, SpanTrackingMode.EdgeExclusive); if (!string.IsNullOrEmpty(spobj.Definition.brief)) { qiContent.Add(spobj.Definition.brief); } if (!string.IsNullOrEmpty(spobj.Definition.usage)) { box.SetText(spobj.Definition.usage); } // Debug.WriteLine("QuickInfo: {0}", new[] { spobj.Span.GetText() }); return; } } if (HasSpecialChar(extent.Span.GetText())) { return; } var t = subjectTriggerPoint.Value.GetContainingLine(); var line = t.GetText(); if (string.IsNullOrEmpty(line)) { return; } int i = subjectTriggerPoint.Value.Position; for (; i >= t.Start.Position; i--) { if (IsSpecialChar(line[i - t.Start.Position])) { break; } } if (i < t.Start.Position) { i = t.Start.Position; } else { i++; } int j = subjectTriggerPoint.Value.Position; for (; j <= t.End.Position; j++) { if (j == t.End.Position || IsSpecialChar(line[j - t.Start.Position])) { break; } } if (j > t.End.Position) { j = t.End.Position; } var k = line.Substring(i - t.Start.Position, j - i); if (char.IsNumber(k[0])) { ulong u; if (ParseULong(k, out u)) { applicableToSpan = currentSnapshot.CreateTrackingSpan( querySpan.Start.Position, querySpan.Length, SpanTrackingMode.EdgeInclusive); qiContent.Add(string.Format("DEC: {0:D}\nHEX: {0:X}", u)); } } else if (k[0] == '?') { string str; if (s_dictUndname.TryGetValue(k, out str) == false) { Process ps = new Process(); ps.StartInfo = new ProcessStartInfo() { FileName = mutable.Loader.UndnamePath, Arguments = k, RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }; ps.Start(); str = ps.StandardOutput.ReadLine(); while (str != null) { if (str.StartsWith("is :- ")) { str = str.Substring(7).Trim(' ', '"'); s_dictUndname[k] = str; break; } str = ps.StandardOutput.ReadLine(); } } applicableToSpan = currentSnapshot.CreateTrackingSpan( querySpan.Start.Position, querySpan.Length, SpanTrackingMode.EdgeInclusive); qiContent.Add("UNDECORATED TO"); qiContent.Add(str); // the content can be string or WPF element. } else if (i != t.Start) { if (line[i - t.Start.Position - 1] == '.') { NasmClassifier nasmclassifier; if (m_textBuffer.Properties.TryGetProperty(typeof(NasmClassifier), out nasmclassifier)) { var lbs = nasmclassifier.GetLabels(); if (lbs.Count != 0) { int?z = lbs.Keys.Where(y => y <= t.LineNumber).Max(p => (int?)p); if (z.HasValue && lbs.ContainsKey(z.Value)) { applicableToSpan = currentSnapshot.CreateTrackingSpan( querySpan.Start.Position, querySpan.Length, SpanTrackingMode.EdgeInclusive); qiContent.Add("LOCAL LABEL FOR"); qiContent.Add(string.Format("{0}\nAT LINE #{1}", lbs[z.Value], z.Value + 1)); } } } } } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (session.TextView.TextBuffer == this.TextBuffer) { ITextSnapshot currentSnapshot = this.TextBuffer.CurrentSnapshot; SnapshotPoint?triggerPoint = session.GetTriggerPoint(currentSnapshot); if (!triggerPoint.HasValue) { return; } foreach (var span in this.Aggregator.GetTags(new SnapshotSpan(triggerPoint.Value, triggerPoint.Value))) { if (!span.Tag.ClassificationType.IsOfType(AntlrClassificationTypeNames.LexerRule) && !span.Tag.ClassificationType.IsOfType(AntlrClassificationTypeNames.ParserRule)) { continue; } NormalizedSnapshotSpanCollection spans = span.Span.GetSpans(currentSnapshot); if (spans.Count != 1) { continue; } SnapshotSpan span2 = spans[0]; SnapshotSpan anchorSpan = span.Span.GetSpans(span.Span.AnchorBuffer)[0]; if (span2.Length != anchorSpan.Length) { continue; } if (!span2.Contains(triggerPoint.Value)) { continue; } var rules = EditorNavigationSourceAggregator.GetNavigationTargets().ToArray(); if (rules.Length == 0) { quickInfoContent.Add("Parsing..."); applicableToSpan = currentSnapshot.CreateTrackingSpan(span2, SpanTrackingMode.EdgeExclusive); return; } string ruleName = span2.GetText(); IEditorNavigationTarget target = null; foreach (var rule in rules) { if (string.Equals(rule.Name, ruleName)) { target = rule; break; } } if (target == null) { continue; } SnapshotSpan targetSpan = target.Span; quickInfoContent.Add(!targetSpan.IsEmpty ? targetSpan.GetText() : target.Name); applicableToSpan = currentSnapshot.CreateTrackingSpan(span2, SpanTrackingMode.EdgeExclusive); return; } } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { // Map the trigger point down to our buffer. SnapshotPoint?subjectTriggerPoint = session.GetTriggerPoint(this.subjectBuffer.CurrentSnapshot); if (!subjectTriggerPoint.HasValue) { applicableToSpan = null; return; } ITextSnapshot currentSnapshot = subjectTriggerPoint.Value.Snapshot; SnapshotSpan querySpan = new SnapshotSpan(subjectTriggerPoint.Value, 0); //look for occurrences of our QuickInfo words in the span ITextStructureNavigator navigator = this.provider.NavigatorService.GetTextStructureNavigator(this.subjectBuffer); var extent = navigator.GetSpanOfEnclosing(new SnapshotSpan(this.subjectBuffer.CurrentSnapshot, querySpan)); string searchText = extent.GetText()?.Trim('"'); Guid parsedId; var allFiles = Rainbow.Repository.rainbowFiles.Values.ToList(); if (Guid.TryParse(searchText, out parsedId)) { var file = allFiles.FirstOrDefault(f => f != null && parsedId.Equals(f.Id)); if (file != null) { applicableToSpan = currentSnapshot.CreateTrackingSpan ( extent.Span.Start, file.Id.ToString().Length, SpanTrackingMode.EdgeInclusive ); try { qiContent.Add($"Sitecore path: {file.Path}"); } catch (InvalidOperationException ex) { // The collection may be modified, so we can't add anything here right now Debug.Write($"Exception occurred when trying to add path {file.Path} (skipping as it is not essential): {ex.Message}"); } return; } } else { foreach (var file in allFiles.Where(f => f != null && f.Id != Guid.Empty && f.Path != null).OrderByDescending(f => f.Path)) { int foundIndex = searchText.IndexOf(file.Path, StringComparison.CurrentCultureIgnoreCase); if (foundIndex > -1) { applicableToSpan = currentSnapshot.CreateTrackingSpan ( extent.Span.Start + foundIndex, file.Id.ToString().Length, SpanTrackingMode.EdgeInclusive ); try { qiContent.Add($"Sitecore ID: {{{file.Id}}}"); } catch (InvalidOperationException ex) { // The collection may be modified, so we can't add anything here right now Debug.Write($"Exception occurred when trying to add ID {file.Id} (skipping as it is not essential): {ex.Message}"); } return; } } } applicableToSpan = null; }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (!provider.Settings.RainbowToolTipsEnabled) { return; } SnapshotPoint?triggerPoint = session.GetTriggerPoint(textBuffer.CurrentSnapshot); if (!triggerPoint.HasValue) { return; } SnapshotPoint?otherBrace; if (!FindOtherBrace(triggerPoint.Value, out otherBrace)) { // triggerPoint is not a brace return; } if (!otherBrace.HasValue) { TextEditor.DisplayMessageInStatusBar("No matching brace found."); return; } if (IsTooClose(triggerPoint.Value, otherBrace.Value)) { return; } // IQuickInfoSession.Dismissed is never firing in VS2017 15.6 // so if the tooltip window still exists, kill it // and hope to god leaving IQuickInfoSession.Dismissed hooked // up doesn't end up in a memory leak if (toolTipWindow != null) { toolTipWindow.Dispose(); toolTipWindow = null; } session.Dismissed += OnSessionDismissed; if (toolTipWindow == null) { toolTipWindow = this.provider.ToolTipProvider.CreateToolTip(session.TextView); toolTipWindow.SetSize(60, 5); } var span = new SnapshotSpan(triggerPoint.Value, 1); applicableToSpan = span.Snapshot.CreateTrackingSpan(span, SpanTrackingMode.EdgePositive); var element = toolTipWindow.GetWindow(otherBrace.Value); if (element != null) { quickInfoContent.Add(element); session.Set(new RainbowToolTipContext()); } }
private List <Parser.Variable> GetApplicableVariables(IQuickInfoSession session) { var pt = session.GetTriggerPoint(session.TextView.TextBuffer).GetPoint(session.TextView.TextSnapshot); return(m_parsedProject.GetAvailableVariables(m_subjectBuffer, pt)); }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (!XSharpProjectPackage.Instance.DebuggerIsRunning) { try { XSharpModel.ModelWalker.Suspend(); var package = XSharp.Project.XSharpProjectPackage.Instance; var optionsPage = package.GetIntellisenseOptionsPage(); if (optionsPage.DisableQuickInfo) { return; } // Map the trigger point down to our buffer. SnapshotPoint?subjectTriggerPoint = session.GetTriggerPoint(_subjectBuffer.CurrentSnapshot); if (!subjectTriggerPoint.HasValue) { return; } ITextSnapshot currentSnapshot = subjectTriggerPoint.Value.Snapshot; if (subjectTriggerPoint.Value.Position == lastTriggerPoint) { if (!string.IsNullOrEmpty(lastHelp)) { qiContent.Add(lastHelp); } if (lastSpan != null) { applicableToSpan = currentSnapshot.CreateTrackingSpan( lastSpan.GetSpan(currentSnapshot), SpanTrackingMode.EdgeInclusive); } return; } lastTriggerPoint = subjectTriggerPoint.Value.Position; //look for occurrences of our QuickInfo words in the span ITextStructureNavigator navigator = _provider.NavigatorService.GetTextStructureNavigator(_subjectBuffer); TextExtent extent = navigator.GetExtentOfWord(subjectTriggerPoint.Value); string searchText = extent.Span.GetText(); // First, where are we ? int caretPos = subjectTriggerPoint.Value.Position; int lineNumber = subjectTriggerPoint.Value.GetContainingLine().LineNumber; var snapshot = session.TextView.TextBuffer.CurrentSnapshot; if (_file == null) { return; } // Then, the corresponding Type/Element if possible IToken stopToken; //ITokenStream tokenStream; XSharpModel.XTypeMember member = XSharpLanguage.XSharpTokenTools.FindMember(lineNumber, _file); XSharpModel.XType currentNamespace = XSharpLanguage.XSharpTokenTools.FindNamespace(caretPos, _file); // adjust caretpos, for other completions we need to stop before the caret. Now we include the caret List <String> tokenList = XSharpLanguage.XSharpTokenTools.GetTokenList(caretPos + 1, lineNumber, snapshot, out stopToken, true, _file, false, member); // Check if we can get the member where we are //if (tokenList.Count > 1) //{ // tokenList.RemoveRange(0, tokenList.Count - 1); //} // LookUp for the BaseType, reading the TokenList (From left to right) XSharpLanguage.CompletionElement gotoElement; String currentNS = ""; if (currentNamespace != null) { currentNS = currentNamespace.Name; } XSharpModel.CompletionType cType = XSharpLanguage.XSharpTokenTools.RetrieveType(_file, tokenList, member, currentNS, stopToken, out gotoElement, snapshot, lineNumber); // // if ((gotoElement != null) && (gotoElement.IsInitialized)) { // Ok, find it ! Let's go ;) applicableToSpan = currentSnapshot.CreateTrackingSpan ( extent.Span.Start, searchText.Length, SpanTrackingMode.EdgeInclusive ); if (gotoElement.XSharpElement != null) { if (gotoElement.XSharpElement.Kind == XSharpModel.Kind.Constructor) { if (gotoElement.XSharpElement.Parent != null) { qiContent.Add(gotoElement.XSharpElement.Parent.Description); } } else { qiContent.Add(gotoElement.XSharpElement.Description); } } else if (gotoElement.SystemElement is TypeInfo) { XSharpLanguage.TypeAnalysis analysis = new XSharpLanguage.TypeAnalysis((TypeInfo)gotoElement.SystemElement); qiContent.Add(analysis.Description); } else { // This works with System.MemberInfo AND XSharpLanguage.MemberAnalysis analysis = null; if (gotoElement.SystemElement is MemberInfo) { analysis = new XSharpLanguage.MemberAnalysis(gotoElement.SystemElement); if (analysis.IsInitialized) { if ((analysis.Kind == XSharpModel.Kind.Constructor) && (cType != null) && (cType.SType != null)) { XSharpLanguage.TypeAnalysis typeAnalysis; typeAnalysis = new XSharpLanguage.TypeAnalysis(cType.SType.GetTypeInfo()); if (typeAnalysis.IsInitialized) { qiContent.Add(typeAnalysis.Description); } } else { qiContent.Add(analysis.Description); } } } } if (qiContent.Count > 0) { lastHelp = (string)qiContent[0]; lastSpan = applicableToSpan; } return; } } catch (Exception ex) { XSharpProjectPackage.Instance.DisplayOutPutMessage("XSharpQuickInfo.AugmentQuickInfoSession failed : "); XSharpProjectPackage.Instance.DisplayException(ex); } finally { XSharpModel.ModelWalker.Resume(); } } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (!EnsureTreeInitialized() || session == null || qiContent == null || qiContent.Count > 0 || !WESettings.GetBoolean(WESettings.Keys.ShowBrowserTooltip)) { return; } SnapshotPoint?point = session.GetTriggerPoint(_buffer.CurrentSnapshot); if (!point.HasValue) { return; } ParseItem item = _tree.StyleSheet.ItemBeforePosition(point.Value.Position); if (item == null || !item.IsValid) { return; } ParseItem theOne = null; ICssCompletionListEntry entry = null; ICssSchemaInstance schema = CssSchemaManager.SchemaManager.GetSchemaForItem(_rootSchema, item); // Declaration Declaration dec = item.FindType <Declaration>(); if (dec != null && dec.PropertyName != null && dec.PropertyName.ContainsRange(point.Value.Position, 1)) { entry = schema.GetProperty(dec.PropertyName.Text); theOne = dec.PropertyName; } else if (dec != null && dec.IsValid && dec.Values.TextStart <= point.Value.Position && dec.Values.TextAfterEnd >= point.Value.Position) { entry = schema.GetProperty(dec.PropertyName.Text); if (entry != null) { var list = schema.GetPropertyValues(entry.DisplayText); theOne = dec.StyleSheet.ItemFromRange(point.Value.Position, 0); entry = list.SingleOrDefault(r => r.DisplayText.Equals(theOne.Text, StringComparison.OrdinalIgnoreCase)); } } // Pseudo class if (entry == null) { PseudoClassSelector pseudoClass = item.FindType <PseudoClassSelector>(); if (pseudoClass != null) { entry = schema.GetPseudo(pseudoClass.Text); theOne = pseudoClass; } } // Pseudo class function if (entry == null) { PseudoClassFunctionSelector pseudoClassFunction = item.FindType <PseudoClassFunctionSelector>(); if (pseudoClassFunction != null) { entry = schema.GetPseudo(pseudoClassFunction.Text); theOne = pseudoClassFunction; } } // Pseudo element if (entry == null) { PseudoElementSelector pseudoElement = item.FindType <PseudoElementSelector>(); if (pseudoElement != null) { entry = schema.GetPseudo(pseudoElement.Text); theOne = pseudoElement; } } // Pseudo element function if (entry == null) { PseudoElementFunctionSelector pseudoElementFunction = item.FindType <PseudoElementFunctionSelector>(); if (pseudoElementFunction != null) { entry = schema.GetPseudo(pseudoElementFunction.Text); theOne = pseudoElementFunction; } } // @-directive if (entry == null) { AtDirective atDirective = item.Parent as AtDirective; if (atDirective != null && atDirective.Keyword != null) { entry = schema.GetAtDirective("@" + atDirective.Keyword.Text); theOne = atDirective.Keyword; } } if (entry != null) { applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(theOne.Start, theOne.Length, SpanTrackingMode.EdgeNegative); string syntax = entry.GetSyntax(schema.Version); string b = entry.GetAttribute("browsers"); if (string.IsNullOrEmpty(b) && theOne.Parent != null && theOne.Parent is Declaration) { b = schema.GetProperty(((Declaration)theOne.Parent).PropertyName.Text).GetAttribute("browsers"); if (string.IsNullOrEmpty(syntax)) { syntax = theOne.Text; } } if (!string.IsNullOrEmpty(syntax)) { qiContent.Add("Example: " + syntax); } Dictionary <string, string> browsers = GetBrowsers(b); qiContent.Add(CreateBrowserList(browsers)); } }
/// <inheritdoc /> public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; var tagAggregator = provider.AggregatorFactory.CreateTagAggregator <IClassificationTag>(session.TextView); var triggerPoint = session.GetTriggerPoint(textBuffer.CurrentSnapshot); if (triggerPoint != null) { SnapshotSpan tagSpan; var lineSpan = triggerPoint.Value.GetContainingLine(); string elementName = null, attrName = null, identifier = null, name; UIElement content; // Get the tags for the line containing the mouse point foreach (IMappingTagSpan <IClassificationTag> curTag in tagAggregator.GetTags( new SnapshotSpan(lineSpan.Start, lineSpan.End))) { name = curTag.Tag.ClassificationType.Classification.ToLowerInvariant(); tagSpan = curTag.Span.GetSpans(textBuffer).First(); if (name.IndexOf("identifier", StringComparison.Ordinal) != -1) { name = "identifier"; } switch (name) { case "xml doc tag": // Track the last seen element or attribute. The classifier in VS2013 and earlier does // not break up the XML comments into elements and attributes so we may get a mix of text // in the "tag". attrName = tagSpan.GetText(); // If it contains "cref", ten next XML doc attribute value will be the target if (attrName.IndexOf("cref=", StringComparison.Ordinal) != -1 && enableInCRef) { attrName = "cref"; } // As above, for conceptualLink, the next XML doc attribute will be the target if (attrName.StartsWith("<conceptualLink", StringComparison.Ordinal)) { attrName = "conceptualLink"; } // For token, the next XML doc comment will contain the token name if (attrName == "<token>") { attrName = "token"; } break; case "xml doc attribute": if ((attrName == "cref" || attrName == "conceptualLink") && tagSpan.Contains(triggerPoint.Value) && tagSpan.Length > 2) { // Drop the quotes from the span var span = new SnapshotSpan(tagSpan.Snapshot, tagSpan.Start + 1, tagSpan.Length - 2); content = this.CreateInfoText(attrName, span.GetText()); if (content != null) { applicableToSpan = textBuffer.CurrentSnapshot.CreateTrackingSpan(span, SpanTrackingMode.EdgeExclusive); quickInfoContent.Add(content); } return; } break; case "xml doc comment": if (attrName == "token" && tagSpan.Contains(triggerPoint.Value) && tagSpan.Length > 1) { content = this.CreateInfoText(attrName, tagSpan.GetText()); if (content != null) { applicableToSpan = textBuffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); quickInfoContent.Add(content); } return; } break; // VS2015 is more specific in its classifications case "xml doc comment - name": elementName = tagSpan.GetText().Trim(); break; case "xml doc comment - attribute name": attrName = tagSpan.GetText().Trim(); identifier = null; if (attrName == "cref" && !enableInCRef) { attrName = null; } break; case "xml doc comment - attribute value": if ((attrName == "cref" || (elementName == "conceptualLink" && attrName == "target")) && tagSpan.Contains(triggerPoint.Value) && tagSpan.Length > 1) { content = this.CreateInfoText((attrName == "cref") ? attrName : elementName, tagSpan.GetText()); if (content != null) { applicableToSpan = textBuffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); quickInfoContent.Add(content); } return; } break; case "identifier": case "keyword": case "operator": if (attrName != null) { identifier += tagSpan.GetText(); if (name == "keyword") { identifier += " "; } } break; case "punctuation": if (identifier != null) { identifier += tagSpan.GetText(); } break; case "xml doc comment - attribute quotes": if (identifier != null) { // Set the span to that of the identifier var span = new SnapshotSpan(tagSpan.Snapshot, tagSpan.Start - identifier.Length, identifier.Length); if (span.Contains(triggerPoint.Value) && span.Length > 1) { content = this.CreateInfoText("cref", span.GetText()); if (content != null) { applicableToSpan = textBuffer.CurrentSnapshot.CreateTrackingSpan(span, SpanTrackingMode.EdgeExclusive); quickInfoContent.Add(content); } } return; } break; case "xml doc comment - text": if (elementName == "token" && tagSpan.Contains(triggerPoint.Value) && tagSpan.Length > 1) { content = this.CreateInfoText(elementName, tagSpan.GetText()); if (content != null) { applicableToSpan = textBuffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); quickInfoContent.Add(content); } return; } break; default: break; } } } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; // Map the trigger point down to our buffer. SnapshotPoint?subjectTriggerPoint = session.GetTriggerPoint(this.textBuffer.CurrentSnapshot); if (!subjectTriggerPoint.HasValue) { return; } SnapshotPoint point = subjectTriggerPoint.Value; // Find the span we're in... IList <ClassificationSpan> spans = this.classifier.GetClassificationSpans(point.GetContainingLine().Extent); ClassificationSpan span = spans.FirstOrDefault(s => s.Span.Contains(point)); if (span == null) { return; } // If we're over a replacement block, expand the span to include the entire replacement... if (IsReplacementSpan(span)) { // expand to find entire replacement block... int initialSpan = spans.IndexOf(span); int firstSpan = initialSpan; int lastSpan = initialSpan; while (firstSpan > 0 && !spans[firstSpan].ClassificationType.IsOfType(TypeConstants.ReplacementStart)) { --firstSpan; } while (lastSpan < spans.Count - 1 && !spans[lastSpan].ClassificationType.IsOfType(TypeConstants.ReplacementEnd)) { ++lastSpan; } SnapshotSpan replacementSpan = new SnapshotSpan( spans[firstSpan].Span.Start, spans[lastSpan].Span.End); applicableToSpan = point.Snapshot.CreateTrackingSpan(replacementSpan, SpanTrackingMode.EdgeInclusive); // Programmatically build up the expected syntax... var replacementSpans = spans.Skip(firstSpan - 1).Take(lastSpan - firstSpan + 1); bool hasType = replacementSpans.Any(s => s.ClassificationType.IsOfType(TypeConstants.ReplacementType)); bool hasPosition = replacementSpans.Any(s => s.ClassificationType.IsOfType(TypeConstants.ReplacementPosition)); bool hasAlignment = replacementSpans.Any(s => s.ClassificationType.IsOfType(TypeConstants.ReplacementAlignment)); bool hasFormat = replacementSpans.Any(s => s.ClassificationType.IsOfType(TypeConstants.ReplacementFormat)); StringBuilder builder = new StringBuilder(); builder.Append("{"); if (hasType || hasPosition) { builder.Append("["); if (hasType) { builder.Append("type"); } if (hasPosition) { if (hasType) { builder.Append(","); } builder.Append("position"); } builder.Append("]"); } builder.Append("name"); if (hasAlignment) { builder.Append(",alignment"); } if (hasFormat) { builder.Append(":format"); } builder.Append("}"); //// See QuickInfoWithLink class (venus\editors\common\web\quickinfo) for not-just-text implementation. // 4 mutually exclusive attributes means 16 possible formats... quickInfoContent.Add(string.Format( "replacement {0} (+ 15 overloads)\nProvides type-safe replacement parameter.", builder.ToString())); } else if (span.ClassificationType.IsOfType(TypeConstants.Keyword)) { applicableToSpan = point.Snapshot.CreateTrackingSpan(span.Span, SpanTrackingMode.EdgeInclusive); quickInfoContent.Add("Keyword: type"); } else if (span.ClassificationType.IsOfType(TypeConstants.MessageTypeDefinition)) { applicableToSpan = point.Snapshot.CreateTrackingSpan(span.Span, SpanTrackingMode.EdgeInclusive); quickInfoContent.Add(string.Format("Message type definition: {0}", span.Span.GetText())); } else if (span.ClassificationType.IsOfType(TypeConstants.MessageType)) { applicableToSpan = point.Snapshot.CreateTrackingSpan(span.Span, SpanTrackingMode.EdgeInclusive); quickInfoContent.Add(string.Format("Message type: {0}", span.Span.GetText())); } else if (span.ClassificationType.IsOfType(TypeConstants.MessageName)) { applicableToSpan = point.Snapshot.CreateTrackingSpan(span.Span, SpanTrackingMode.EdgeInclusive); quickInfoContent.Add(string.Format("Message name: {0}", span.Span.GetText())); } else if (span.ClassificationType.IsOfType(TypeConstants.Escape)) { applicableToSpan = point.Snapshot.CreateTrackingSpan(span.Span, SpanTrackingMode.EdgeInclusive); quickInfoContent.Add(string.Format("String escape: {0}", span.Span.GetText())); } }
//! \brief create Quickinfo content public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; DoxUtil.CManager manager = DoxUtil.CManager.Manager; if (manager == null) { return; } // Map the trigger point down to our buffer. SnapshotPoint?subjectTriggerPoint = session.GetTriggerPoint(SubjectBuffer.CurrentSnapshot); if (!subjectTriggerPoint.HasValue) { return; } ITextSnapshot currentSnapshot = subjectTriggerPoint.Value.Snapshot; DoxTokenTag spanInfo = DoxTokenTaggerHelper.TagHitTest(this.Aggregator, currentSnapshot, subjectTriggerPoint.Value); if (spanInfo == null) { return; } bool isCmdKnown = spanInfo.Type != DoxTokenType.Cmd || spanInfo.WellKnown; string cmdName = spanInfo.Name; if (spanInfo.Name.Length > 0 && (spanInfo.Name[0] == '@' || spanInfo.Name[0] == '\\')) { cmdName = spanInfo.Name.Substring(1); } var opt = manager.Options; var colDflt = Color.FromRgb(128, 128, 128); var colCmd = CmdClassifications.CmdColor; var colHRef = CmdClassifications.RefColor; var colInc = CmdClassifications.IncludeColor; /* * try * { * var cmdClassify = ClassificationRegistry.GetClassificationType(CmdClassifications.DoxCommand); * if (cmdClassify!=null) * { * * } * } * catch { } */ if (opt.GeneralQT) { // C# String Formatting Dictionary Intellisence // [http://stackoverflow.com/questions/39524387/c-sharp-string-formatting-dictionary-intellisence] var textBlock = new System.Windows.Controls.TextBlock { TextWrapping = System.Windows.TextWrapping.NoWrap }; if (isCmdKnown) { AddText(textBlock, colDflt, false, false, "Doxygen Special Command "); AddText(textBlock, colCmd, true, false, "@" + cmdName); AddText(textBlock, colDflt, false, false, " ["); AddText(textBlock, colHRef, false, true, manager.Options.DoxCommadsHelpURL + "#cmd" + cmdName); AddText(textBlock, colDflt, false, false, "]"); } else { AddText(textBlock, colDflt, false, false, "Unknown Doxygen Special Command "); AddText(textBlock, colDflt, true, false, "@" + cmdName); AddText(textBlock, colDflt, false, false, ", see ["); AddText(textBlock, colHRef, false, true, manager.Options.DoxCommadsHelpURL); AddText(textBlock, colDflt, false, false, "] for more information"); } qiContent.Add(textBlock); } switch (spanInfo.Type) { case DoxTokenType.Cmd: // nothing to do break; case DoxTokenType.Ref: if (opt.RefQT) { var refTextBlock = new System.Windows.Controls.TextBlock { TextWrapping = System.Windows.TextWrapping.NoWrap }; if (spanInfo.WellKnown) { AddText(refTextBlock, colDflt, false, false, "["); AddText(refTextBlock, colHRef, false, true, spanInfo.Argument); AddText(refTextBlock, colDflt, false, false, "]"); } else { AddText(refTextBlock, colDflt, false, false, "unknown doxgen reference "); AddText(refTextBlock, colDflt, true, false, "spanInfo.Argument"); } qiContent.Add(refTextBlock); } break; case DoxTokenType.Image: if (opt.ImageQT) { if (spanInfo.WellKnown) { var imagePath = spanInfo.Argument; AddImage(qiContent, imagePath); qiContent.Add(CreateTextBlockHRef(colDflt, colHRef, "image file", "file:///" + imagePath)); } else { var imgTextBlock = new System.Windows.Controls.TextBlock { TextWrapping = System.Windows.TextWrapping.NoWrap }; AddText(imgTextBlock, colDflt, false, false, "unknown image file "); AddText(imgTextBlock, colDflt, true, false, spanInfo.Argument); qiContent.Add(imgTextBlock); //var hlpURL = manager.FindDoxygenLink(DoxUtil.CManager.DoxRefAddImage, false); //if (hlpURL != "") // qiContent.Add(CreateTextBlockHRef(colDflt, colHRef, "How to add an image to source code documentation", hlpURL)); } } break; case DoxTokenType.Dot: if (opt.DotQT) { // create preview string dotContent = spanInfo.ContentSpan.GetText(); var previewImg = manager.GenerateDotGraphPreview(dotContent); if (previewImg != null) { qiContent.Add(previewImg); } // add help URL qiContent.Add(CreateTextBlockHRef(colDflt, colHRef, "Graphviz - Graph Visualization Software", DoxUtil.CManager.GraphvizHelpURL)); } break; case DoxTokenType.DotFile: if (opt.DotQT) { var dotTextBlock = new System.Windows.Controls.TextBlock { TextWrapping = System.Windows.TextWrapping.NoWrap }; if (spanInfo.WellKnown) { var dotPath = spanInfo.Argument; var previewImg = manager.GenerateDotFileGraphPreview(dotPath); if (previewImg != null) { qiContent.Add(previewImg); } } else { AddText(dotTextBlock, colDflt, false, false, "unknown dot graph file "); AddText(dotTextBlock, colDflt, true, false, spanInfo.Argument); } qiContent.Add(dotTextBlock); } break; case DoxTokenType.Msc: if (opt.MscQT) { // create preview string mscContent = spanInfo.ContentSpan.GetText(); var previewImg = manager.GenerateMscGraphPreview("msc {\n" + mscContent + "\n}\n"); if (previewImg != null) { qiContent.Add(previewImg); } // add help URL qiContent.Add(CreateTextBlockHRef(colDflt, colHRef, "Mscgen", DoxUtil.CManager.MscgenHelpURL)); } break; case DoxTokenType.MscFile: if (opt.MscQT) { var mscTextBlock = new System.Windows.Controls.TextBlock { TextWrapping = System.Windows.TextWrapping.NoWrap }; if (spanInfo.WellKnown) { var mscPath = spanInfo.Argument; var previewImg = manager.GenerateMscFileGraphPreview(mscPath); if (previewImg != null) { qiContent.Add(previewImg); } } else { AddText(mscTextBlock, colDflt, false, false, "unknown dot graph file "); AddText(mscTextBlock, colDflt, true, false, spanInfo.Argument); } qiContent.Add(mscTextBlock); } break; case DoxTokenType.DiaFile: // TODO $$$ not yet implemented break; case DoxTokenType.Uml: if (opt.PlantUmlQT) { // create preview string umlContent = spanInfo.ContentSpan.GetText(); var previewImg = manager.GeneratePlatUMLPreview("@startuml\n" + umlContent + "\n@enduml"); if (previewImg != null) { qiContent.Add(previewImg); } // add help URL qiContent.Add(CreateTextBlockHRef(colDflt, colHRef, "PlantUML in a nutshell", DoxUtil.CManager.PlanUMLHelpURL)); } break; case DoxTokenType.LatexFormula: if (opt.LatexFormulaQT) { // create preview string latexFormula = spanInfo.ContentSpan.GetText(); var previewImg = manager.GenerateLatexFormulaPreview(latexFormula); if (previewImg != null) { qiContent.Add(previewImg); } // add help URL qiContent.Add(CreateTextBlockHRef(colDflt, colHRef, "LaTeX/Mathematics", DoxUtil.CManager.LatexHelpURL)); } break; } if (qiContent.Count > 0) { applicableToSpan = currentSnapshot.CreateTrackingSpan(spanInfo.Span, SpanTrackingMode.EdgeInclusive); } }
/// <inheritdoc /> public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; var tagAggregator = provider.AggregatorFactory.CreateTagAggregator <IClassificationTag>(session.TextView); var triggerPoint = session.GetTriggerPoint(textBuffer.CurrentSnapshot); if (triggerPoint != null) { SnapshotSpan tagSpan; var lineSpan = triggerPoint.Value.GetContainingLine(); string elementName = null, attrName = null, name, spanText; UIElement content; // Get the tags for the line containing the mouse point foreach (IMappingTagSpan <IClassificationTag> curTag in tagAggregator.GetTags( new SnapshotSpan(lineSpan.Start, lineSpan.End))) { name = curTag.Tag.ClassificationType.Classification.ToLowerInvariant(); switch (name) { case "xml name": tagSpan = curTag.Span.GetSpans(textBuffer).First(); elementName = tagSpan.GetText(); break; case "xml attribute": tagSpan = curTag.Span.GetSpans(textBuffer).First(); attrName = tagSpan.GetText(); break; case "xml attribute value": tagSpan = curTag.Span.GetSpans(textBuffer).First(); if (tagSpan.Contains(triggerPoint.Value)) { if (((elementName == "image" || elementName == "link") && attrName == "xlink:href") || (elementName == "topic" && attrName == "id")) { content = this.CreateInfoText(elementName, tagSpan.GetText()); if (content != null) { applicableToSpan = textBuffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); quickInfoContent.Add(content); } } return; } break; case "xml text": tagSpan = curTag.Span.GetSpans(textBuffer).First(); if (tagSpan.Contains(triggerPoint.Value)) { spanText = tagSpan.GetText().Trim(); content = null; switch (elementName) { case "codeEntityReference": if (spanText.IsCodeEntityReference()) { content = this.CreateInfoText(elementName, tagSpan.GetText()); } break; case "codeReference": if (spanText.IsCodeReferenceId()) { content = this.CreateInfoText(elementName, tagSpan.GetText()); } break; case "token": content = this.CreateInfoText(elementName, tagSpan.GetText()); break; default: // We only get info about the current line so we may just get some XML // text if the starting tag is on a prior line. In such cases, see if // the text looks like an entity reference or a code reference ID. If // so, offer it as a clickable link. If not, ignore it. if (String.IsNullOrWhiteSpace(elementName)) { if (spanText.IsCodeEntityReference()) { content = this.CreateInfoText("codeEntityReference", tagSpan.GetText()); } else if (spanText.IsCodeReferenceId()) { content = this.CreateInfoText("codeReference", tagSpan.GetText()); } } break; } if (content != null) { // Ignore any leading whitespace on the span so that the pop-up open directly // under the text. spanText = tagSpan.GetText(); int offset = spanText.Length - spanText.TrimStart().Length; applicableToSpan = textBuffer.CurrentSnapshot.CreateTrackingSpan( tagSpan.Start + offset, tagSpan.Length - offset, SpanTrackingMode.EdgeExclusive); quickInfoContent.Add(content); } return; } break; default: break; } } } }
/// <summary> /// Determine which pieces of Quickinfo content should be displayed /// </summary> public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; try { DateTime time1 = DateTime.Now; if (this._disposed) { throw new ObjectDisposedException("AsmQuickInfoSource"); } var triggerPoint = (SnapshotPoint)session.GetTriggerPoint(_buffer.CurrentSnapshot); if (triggerPoint == null) { return; } string tagString = ""; foreach (IMappingTagSpan <AsmTokenTag> curTag in this._aggregator.GetTags(new SnapshotSpan(triggerPoint, triggerPoint))) { var tagSpan = curTag.Span.GetSpans(_buffer).First(); tagString = tagSpan.GetText(); //AsmDudeToolsStatic.Output(string.Format("INFO: {0}:AugmentQuickInfoSession. tag ", this.ToString(), tagString)); string tagStringUpper = tagString.ToUpper(); applicableToSpan = this._buffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); string description = null; switch (curTag.Tag.type) { case TokenType.Misc: { string descr = this._asmDudeTools.getDescription(tagStringUpper); description = (descr.Length > 0) ? ("Keyword " + tagStringUpper + ": " + descr) : "Keyword " + tagStringUpper; break; } case TokenType.Directive: { string descr = this._asmDudeTools.getDescription(tagStringUpper); description = (descr.Length > 0) ? ("Directive " + tagStringUpper + ": " + descr) : "Directive " + tagStringUpper; break; } case TokenType.Register: { string descr = this._asmDudeTools.getDescription(tagStringUpper); description = (descr.Length > 0) ? (tagStringUpper + ": " + descr) : "Register " + tagStringUpper; break; } case TokenType.Mnemonic: // intentional fall through case TokenType.Jump: { string descr = this._asmDudeTools.getDescription(tagStringUpper); description = (descr.Length > 0) ? ("Mnemonic " + tagStringUpper + ": " + descr) : "Mnemonic " + tagStringUpper; break; } case TokenType.Label: { string descr = AsmDudeToolsStatic.getLabelDescription(tagString, this._buffer); description = (descr.Length > 0) ? descr : "Label " + tagString; break; } case TokenType.Constant: { description = "Constant " + tagString; break; } default: break; } if (description != null) { const int maxLineLength = 100; quickInfoContent.Add(multiLine(description, maxLineLength)); } } double elapsedSec = (double)(DateTime.Now.Ticks - time1.Ticks) / 10000000; if (elapsedSec > AsmDudePackage.slowWarningThresholdSec) { AsmDudeToolsStatic.Output(string.Format("WARNING: SLOW: took {0:F3} seconds to retrieve quick info for tag \"{1}\".", elapsedSec, tagString)); } } catch (Exception e) { AsmDudeToolsStatic.Output(string.Format("ERROR: {0}:AugmentQuickInfoSession; e={1}", this.ToString(), e.ToString())); } }
/// <summary> /// Determine which pieces of Quickinfo content should be displayed /// </summary> public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; try { DateTime time1 = DateTime.Now; ITextSnapshot snapshot = _sourceBuffer.CurrentSnapshot; var triggerPoint = (SnapshotPoint)session.GetTriggerPoint(snapshot); if (triggerPoint == null) { return; } string keyword = ""; IEnumerable <IMappingTagSpan <AsmTokenTag> > enumerator = this._aggregator.GetTags(new SnapshotSpan(triggerPoint, triggerPoint)); if (enumerator.Count() > 0) { if (false) { // TODO: multiple tags at the provided triggerPoint is most likely the result of a bug in AsmTokenTagger, but it seems harmless... if (enumerator.Count() > 1) { foreach (IMappingTagSpan <AsmTokenTag> v in enumerator) { AsmDudeToolsStatic.Output(string.Format("WARNING: {0}:AugmentQuickInfoSession. more than one tag! \"{1}\"", this.ToString(), v.Span.GetSpans(_sourceBuffer).First().GetText())); } } } IMappingTagSpan <AsmTokenTag> asmTokenTag = enumerator.First(); SnapshotSpan tagSpan = asmTokenTag.Span.GetSpans(_sourceBuffer).First(); keyword = tagSpan.GetText(); //AsmDudeToolsStatic.Output(string.Format("INFO: {0}:AugmentQuickInfoSession. keyword=\"{1}\"; type={2}", this.ToString(), keyword, asmTokenTag.Tag.type)); string keywordUpper = keyword.ToUpper(); applicableToSpan = snapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); TextBlock description = null; switch (asmTokenTag.Tag.type) { case AsmTokenType.Misc: { description = new TextBlock(); description.Inlines.Add(makeRun1("Keyword ")); description.Inlines.Add(makeRun2(keyword, Settings.Default.SyntaxHighlighting_Misc)); string descr = this._asmDudeTools.getDescription(keywordUpper); if (descr.Length > 0) { description.Inlines.Add(new Run(AsmSourceTools.linewrap(": " + descr, AsmDudePackage.maxNumberOfCharsInToolTips))); } break; } case AsmTokenType.Directive: { description = new TextBlock(); description.Inlines.Add(makeRun1("Directive ")); description.Inlines.Add(makeRun2(keyword, Settings.Default.SyntaxHighlighting_Directive)); string descr = this._asmDudeTools.getDescription(keywordUpper); if (descr.Length > 0) { description.Inlines.Add(new Run(AsmSourceTools.linewrap(": " + descr, AsmDudePackage.maxNumberOfCharsInToolTips))); } break; } case AsmTokenType.Register: { description = new TextBlock(); description.Inlines.Add(makeRun1("Register ")); description.Inlines.Add(makeRun2(keyword, Settings.Default.SyntaxHighlighting_Register)); string descr = this._asmDudeTools.getDescription(keywordUpper); if (descr.Length > 0) { description.Inlines.Add(new Run(AsmSourceTools.linewrap(": " + descr, AsmDudePackage.maxNumberOfCharsInToolTips))); } break; } case AsmTokenType.Mnemonic: case AsmTokenType.Jump: { description = new TextBlock(); description.Inlines.Add(makeRun1("Mnemonic ")); description.Inlines.Add(makeRun2(keyword, Settings.Default.SyntaxHighlighting_Opcode)); string descr = this._asmDudeTools.mnemonicStore.getDescription(AsmSourceTools.parseMnemonic(keywordUpper)); if (descr.Length > 0) { description.Inlines.Add(new Run(AsmSourceTools.linewrap(": " + descr, AsmDudePackage.maxNumberOfCharsInToolTips))); } break; } case AsmTokenType.Label: { description = new TextBlock(); description.Inlines.Add(makeRun1("Label ")); description.Inlines.Add(makeRun2(keyword, Settings.Default.SyntaxHighlighting_Label)); string descr = this.getLabelDescription(keyword); if (descr.Length > 0) { description.Inlines.Add(new Run(AsmSourceTools.linewrap(": " + descr, AsmDudePackage.maxNumberOfCharsInToolTips))); } break; } case AsmTokenType.LabelDef: { description = new TextBlock(); description.Inlines.Add(makeRun1("Label ")); description.Inlines.Add(makeRun2(keyword, Settings.Default.SyntaxHighlighting_Label)); string descr = this.getLabelDefDescription(keyword); if (descr.Length > 0) { description.Inlines.Add(new Run(AsmSourceTools.linewrap(": " + descr, AsmDudePackage.maxNumberOfCharsInToolTips))); } break; } case AsmTokenType.Constant: { description = new TextBlock(); description.Inlines.Add(makeRun1("Constant ")); description.Inlines.Add(makeRun2(keyword, Settings.Default.SyntaxHighlighting_Constant)); break; } default: //description = new TextBlock(); //description.Inlines.Add(makeRun1("Unused tagType " + asmTokenTag.Tag.type)); break; } if (description != null) { description.FontSize = AsmDudeToolsStatic.getFontSize() + 2; description.FontFamily = AsmDudeToolsStatic.getFontType(); //AsmDudeToolsStatic.Output(string.Format("INFO: {0}:AugmentQuickInfoSession; setting description fontSize={1}; fontFamily={2}", this.ToString(), description.FontSize, description.FontFamily)); quickInfoContent.Add(description); } } AsmDudeToolsStatic.printSpeedWarning(time1, "QuickInfo"); } catch (Exception e) { AsmDudeToolsStatic.Output(string.Format("ERROR: {0}:AugmentQuickInfoSession; e={1}", this.ToString(), e.ToString())); } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { // Map the trigger point down to our buffer. SnapshotPoint?subjectTriggerPoint = session.GetTriggerPoint(m_subjectBuffer.CurrentSnapshot); if (!subjectTriggerPoint.HasValue) { applicableToSpan = null; return; } ITextSnapshot currentSnapshot = subjectTriggerPoint.Value.Snapshot; SnapshotSpan querySpan = new SnapshotSpan(subjectTriggerPoint.Value, 0); //look for occurrences of our QuickInfo words in the span ITextStructureNavigator navigator = m_provider.NavigatorService.GetTextStructureNavigator(m_subjectBuffer); TextExtent extent = navigator.GetExtentOfWord(subjectTriggerPoint.Value); string searchText = extent.Span.GetText(); //don't do anything if the current SnapshotPoint is not initialized or at the end of the buffer if (!subjectTriggerPoint.HasValue || subjectTriggerPoint.Value.Position > subjectTriggerPoint.Value.Snapshot.Length) { applicableToSpan = null; return; } //hold on to a snapshot of the current character SnapshotPoint currentChar = subjectTriggerPoint.Value; //get the current char and the previous char char currentText = currentChar.GetChar(); SnapshotPoint lastChar = currentChar == 0 ? currentChar : currentChar - 1; //if currentChar is 0 (beginning of buffer), don't move it back char lastText = lastChar.GetChar(); // SnapshotSpan pairSpan = new SnapshotSpan(); if (m_braceList.ContainsKey(currentText)) //the key is the open brace { char closeChar; m_braceList.TryGetValue(currentText, out closeChar); String key = currentText.ToString(); int foundIndex = searchText.IndexOf(key, StringComparison.CurrentCultureIgnoreCase); if (foundIndex > -1) { /*applicableToSpan = currentSnapshot.CreateTrackingSpan * ( * querySpan.Start.Add(3).Position, 9, SpanTrackingMode.EdgeInclusive * );*/ applicableToSpan = currentSnapshot.CreateTrackingSpan(2, 2, SpanTrackingMode.EdgeInclusive); string value = closeChar.ToString(); if (value != null) { qiContent.Add(value); } else { qiContent.Add(""); } return; } } applicableToSpan = null; /////////////////// }
//static bool skipFirst = true; public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; //if (skipFirst) //{ // skipFirst = false; // return; //} //else //{ // skipFirst = true; //} if (XSharpProjectPackage.Instance.DebuggerIsRunning) { return; } try { XSharpModel.ModelWalker.Suspend(); if (XSettings.DisableQuickInfo) { return; } // Map the trigger point down to our buffer. SnapshotPoint?subjectTriggerPoint = session.GetTriggerPoint(_subjectBuffer.CurrentSnapshot); if (!subjectTriggerPoint.HasValue) { return; } ITextSnapshot currentSnapshot = subjectTriggerPoint.Value.Snapshot; WriteOutputMessage($"Triggerpoint: {subjectTriggerPoint.Value.Position}"); if ((subjectTriggerPoint.Value.Position == lastTriggerPoint) && (lastVersion == currentSnapshot.Version.VersionNumber)) { if (lastHelp != null) { var description = new TextBlock(); description.Inlines.AddRange(lastHelp); qiContent.Add(description); if (lastxmldoc != null) { qiContent.Add(lastxmldoc); } WriteOutputMessage($"Return last help content: {lastHelp}"); } if (lastSpan != null) { applicableToSpan = lastSpan; } return; } // We don't want to lex the buffer. So get the tokens from the last lex run // and when these are too old, then simply bail out var tokens = _subjectBuffer.GetTokens(); if (tokens != null) { if (tokens.SnapShot.Version != currentSnapshot.Version) { return; } } lastTriggerPoint = subjectTriggerPoint.Value.Position; //look for occurrences of our QuickInfo words in the span ITextStructureNavigator navigator = _provider.NavigatorService.GetTextStructureNavigator(_subjectBuffer); TextExtent extent = navigator.GetExtentOfWord(subjectTriggerPoint.Value); string searchText = extent.Span.GetText(); // First, where are we ? int caretPos = subjectTriggerPoint.Value.Position; int lineNumber = subjectTriggerPoint.Value.GetContainingLine().LineNumber; var snapshot = session.TextView.TextBuffer.CurrentSnapshot; if (_file == null) { return; } // Then, the corresponding Type/Element if possible IToken stopToken; //ITokenStream tokenStream; XMemberDefinition member = XSharpLanguage.XSharpTokenTools.FindMember(lineNumber, _file); XTypeDefinition currentNamespace = XSharpLanguage.XSharpTokenTools.FindNamespace(caretPos, _file); // adjust caretpos, for other completions we need to stop before the caret. Now we include the caret List <String> tokenList = XSharpLanguage.XSharpTokenTools.GetTokenList(caretPos + 1, lineNumber, tokens.TokenStream, out stopToken, true, _file, false, member); // Check if we can get the member where we are //if (tokenList.Count > 1) //{ // tokenList.RemoveRange(0, tokenList.Count - 1); //} // LookUp for the BaseType, reading the TokenList (From left to right) XSharpLanguage.CompletionElement gotoElement; string currentNS = ""; if (currentNamespace != null) { currentNS = currentNamespace.Name; } XSharpModel.CompletionType cType = XSharpLanguage.XSharpTokenTools.RetrieveType(_file, tokenList, member, currentNS, stopToken, out gotoElement, snapshot, lineNumber, _file.Project.Dialect); // // if ((gotoElement != null) && (gotoElement.IsInitialized)) { IClassificationType kwType = _registry.GetClassificationType("keyword"); IClassificationFormatMap fmap = _formatMap.GetClassificationFormatMap(category: "text"); Microsoft.VisualStudio.Text.Formatting.TextFormattingRunProperties kwFormat = fmap.GetTextProperties(kwType); kwType = _registry.GetClassificationType("text"); fmap = _formatMap.GetClassificationFormatMap(category: "text"); Microsoft.VisualStudio.Text.Formatting.TextFormattingRunProperties txtFormat = fmap.GetTextProperties(kwType); // // Ok, find it ! Let's go ;) applicableToSpan = currentSnapshot.CreateTrackingSpan ( extent.Span.Start, searchText.Length, SpanTrackingMode.EdgeInclusive ); if (gotoElement.Result != null) { if (gotoElement.Result.Kind == Kind.Constructor) { if (gotoElement.Result.Parent != null) { var xtype = gotoElement.Result.Parent as IXType; var qitm = new QuickInfoTypeAnalysis(xtype, kwFormat.ForegroundBrush, txtFormat.ForegroundBrush); var description = new TextBlock(); description.Inlines.AddRange(qitm.WPFDescription); qiContent.Add(description); } } else if (gotoElement.Result is IXMember) { QuickInfoTypeMember qitm = new QuickInfoTypeMember((IXMember)gotoElement.Result, kwFormat.ForegroundBrush, txtFormat.ForegroundBrush); var description = new TextBlock(); description.Inlines.AddRange(qitm.WPFDescription); qiContent.Add(description); } else if (gotoElement.Result is IXVariable) { QuickInfoVariable qitm = new QuickInfoVariable((IXVariable)gotoElement.Result, kwFormat.ForegroundBrush, txtFormat.ForegroundBrush); var description = new TextBlock(); description.Inlines.AddRange(qitm.WPFDescription); qiContent.Add(description); } else if (gotoElement.Result is IXType) { var xtype = gotoElement.Result as IXType; var qitm = new QuickInfoTypeAnalysis(xtype, kwFormat.ForegroundBrush, txtFormat.ForegroundBrush); var description = new TextBlock(); description.Inlines.AddRange(qitm.WPFDescription); qiContent.Add(description); } else { var description = new TextBlock(); Run temp; temp = new Run(gotoElement.Result.Description); temp.Foreground = txtFormat.ForegroundBrush; // description.Inlines.Add(temp); qiContent.Add(description); } } if (qiContent.Count > 0) { TextBlock description; description = qiContent[0] as TextBlock; if (qiContent.Count > 1) { lastxmldoc = qiContent[1] as String; } else { lastxmldoc = null; } if (description != null) { lastHelp = new Inline[description.Inlines.Count]; description.Inlines.CopyTo(lastHelp, 0); lastSpan = applicableToSpan; lastVersion = currentSnapshot.Version.VersionNumber; WriteOutputMessage($"Found new help content: {description.Text}"); } } return; } } catch (Exception ex) { XSharpProjectPackage.Instance.DisplayOutPutMessage("XSharpQuickInfo.AugmentQuickInfoSession failed : "); XSharpProjectPackage.Instance.DisplayException(ex); } finally { XSharpModel.ModelWalker.Resume(); } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; SnapshotPoint?point = session.GetTriggerPoint(_buffer.CurrentSnapshot); if (session == null || qiContent == null || !point.HasValue || point.Value.Position >= point.Value.Snapshot.Length) { return; } ParseItem item = _document.ItemAtPosition(point.Value); if (item == null) { return; } applicableToSpan = point.Value.Snapshot.CreateTrackingSpan(item.Span, SpanTrackingMode.EdgeNegative); if (item.Errors.Any()) { foreach (DisplayError error in item.Errors) { qiContent.Add(new Shared.EditorTooltip(error)); return; } } Property property = _document.PropertyAtPosition(point.Value); SchemaCatalog.TryGetKeyword(property?.Keyword?.Text, out Keyword keyword); // Keyword if (keyword != null && item.ItemType == ItemType.Keyword) { qiContent.Add(new Shared.EditorTooltip(keyword)); } // Value else if (keyword != null && item.ItemType == ItemType.Value) { Value value = keyword.Values.FirstOrDefault(v => v.Name.Is(item.Text)); if (value != null && !string.IsNullOrEmpty(value.Description)) { qiContent.Add(new Shared.EditorTooltip(value)); } } // Severity else if (item.ItemType == ItemType.Severity && SchemaCatalog.TryGetSeverity(item.Text, out Severity severity)) { qiContent.Add(new Shared.EditorTooltip(severity)); } // Suppression else if (item.ItemType == ItemType.Suppression && ErrorCatalog.TryGetErrorCode(item.Text, out var code)) { qiContent.Add(new Shared.EditorTooltip(code)); } }
private void Handle(IQuickInfoSession session, IList <object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; DateTime time1 = DateTime.Now; ITextSnapshot snapshot = this._sourceBuffer.CurrentSnapshot; var triggerPoint = (SnapshotPoint)session.GetTriggerPoint(snapshot); if (triggerPoint == null) { AsmDudeToolsStatic.Output_WARNING("AsmQuickInfoSource:AugmentQuickInfoSession: trigger point is null"); return; } Brush foreground = AsmDudeToolsStatic.GetFontColor(); var enumerator = this._aggregator.GetTags(new SnapshotSpan(triggerPoint, triggerPoint)).GetEnumerator(); if (enumerator.MoveNext()) { var asmTokenTag = enumerator.Current; var enumerator2 = asmTokenTag.Span.GetSpans(this._sourceBuffer).GetEnumerator(); if (enumerator2.MoveNext()) { SnapshotSpan tagSpan = enumerator2.Current; string keyword = tagSpan.GetText(); string keywordUpper = keyword.ToUpper(); #region Tests // TODO: multiple tags at the provided triggerPoint is most likely the result of a bug in AsmTokenTagger, but it seems harmless... if (false) { if (enumerator.MoveNext()) { var asmTokenTagX = enumerator.Current; var enumeratorX = asmTokenTagX.Span.GetSpans(this._sourceBuffer).GetEnumerator(); enumeratorX.MoveNext(); AsmDudeToolsStatic.Output_WARNING(string.Format("{0}:AugmentQuickInfoSession. current keyword " + keyword + ": but span has more than one tag! next tag=\"{1}\"", this.ToString(), enumeratorX.Current.GetText())); } } #endregion //AsmDudeToolsStatic.Output_INFO("AsmQuickInfoSource:AugmentQuickInfoSession: keyword=\""+ keyword + "\"; type=" + asmTokenTag.Tag.type +"; file="+AsmDudeToolsStatic.GetFileName(session.TextView.TextBuffer)); applicableToSpan = snapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeInclusive); TextBlock description = null; AsmTokenType type = asmTokenTag.Tag.Type; switch (type) { case AsmTokenType.Misc: { description = new TextBlock(); description.Inlines.Add(Make_Run1("Keyword ", foreground)); description.Inlines.Add(Make_Run2(keyword, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Misc)))); string descr = this._asmDudeTools.Get_Description(keywordUpper); if (descr.Length > 0) { if (keyword.Length > (AsmDudePackage.maxNumberOfCharsInToolTips / 2)) { descr = "\n" + descr; } description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + descr, AsmDudePackage.maxNumberOfCharsInToolTips)) { Foreground = foreground }); } break; } case AsmTokenType.Directive: { description = new TextBlock(); description.Inlines.Add(Make_Run1("Directive ", foreground)); description.Inlines.Add(Make_Run2(keyword, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Directive)))); string descr = this._asmDudeTools.Get_Description(keywordUpper); if (descr.Length > 0) { if (keyword.Length > (AsmDudePackage.maxNumberOfCharsInToolTips / 2)) { descr = "\n" + descr; } description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + descr, AsmDudePackage.maxNumberOfCharsInToolTips)) { Foreground = foreground }); } break; } case AsmTokenType.Register: { int lineNumber = AsmDudeToolsStatic.Get_LineNumber(tagSpan); if (keywordUpper.StartsWith("%")) { keywordUpper = keywordUpper.Substring(1); // remove the preceding % in AT&T syntax } Rn reg = RegisterTools.ParseRn(keywordUpper, true); if (this._asmDudeTools.RegisterSwitchedOn(reg)) { var registerTooltipWindow = new RegisterTooltipWindow(foreground); registerTooltipWindow.SetDescription(reg, this._asmDudeTools); registerTooltipWindow.SetAsmSim(this._asmSimulator, reg, lineNumber, true); quickInfoContent.Add(registerTooltipWindow); } break; } case AsmTokenType.Mnemonic: case AsmTokenType.Jump: { int lineNumber = AsmDudeToolsStatic.Get_LineNumber(tagSpan); Mnemonic mnemonic = AsmSourceTools.ParseMnemonic_Att(keywordUpper, true); if (this._asmDudeTools.MnemonicSwitchedOn(mnemonic)) { var instructionTooltipWindow = new InstructionTooltipWindow(foreground) { Session = session // set the owner of this windows such that we can manually close this window }; instructionTooltipWindow.SetDescription(mnemonic, this._asmDudeTools); instructionTooltipWindow.SetPerformanceInfo(mnemonic, this._asmDudeTools); instructionTooltipWindow.SetAsmSim(this._asmSimulator, lineNumber, true); quickInfoContent.Add(instructionTooltipWindow); } break; } case AsmTokenType.Label: { string label = keyword; string labelPrefix = asmTokenTag.Tag.Misc; string full_Qualified_Label = AsmDudeToolsStatic.Make_Full_Qualified_Label(labelPrefix, label, AsmDudeToolsStatic.Used_Assembler); description = new TextBlock(); description.Inlines.Add(Make_Run1("Label ", foreground)); description.Inlines.Add(Make_Run2(full_Qualified_Label, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Label)))); string descr = this.Get_Label_Description(full_Qualified_Label); if (descr.Length == 0) { descr = this.Get_Label_Description(label); } if (descr.Length > 0) { if (keyword.Length > (AsmDudePackage.maxNumberOfCharsInToolTips / 2)) { descr = "\n" + descr; } description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + descr, AsmDudePackage.maxNumberOfCharsInToolTips)) { Foreground = foreground }); } break; } case AsmTokenType.LabelDef: { string label = keyword; string extra_Tag_Info = asmTokenTag.Tag.Misc; string full_Qualified_Label; if ((extra_Tag_Info != null) && extra_Tag_Info.Equals(AsmTokenTag.MISC_KEYWORD_PROTO)) { full_Qualified_Label = label; } else { full_Qualified_Label = AsmDudeToolsStatic.Make_Full_Qualified_Label(extra_Tag_Info, label, AsmDudeToolsStatic.Used_Assembler); } AsmDudeToolsStatic.Output_INFO("AsmQuickInfoSource:AugmentQuickInfoSession: found label def " + full_Qualified_Label); description = new TextBlock(); description.Inlines.Add(Make_Run1("Label ", foreground)); description.Inlines.Add(Make_Run2(full_Qualified_Label, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Label)))); string descr = this.Get_Label_Def_Description(full_Qualified_Label, label); if (descr.Length > 0) { if (keyword.Length > (AsmDudePackage.maxNumberOfCharsInToolTips / 2)) { descr = "\n" + descr; } description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + descr, AsmDudePackage.maxNumberOfCharsInToolTips)) { Foreground = foreground }); } break; } case AsmTokenType.Constant: { description = new TextBlock(); description.Inlines.Add(Make_Run1("Constant ", foreground)); var(Valid, Value, NBits) = AsmSourceTools.Evaluate_Constant(keyword); string constantStr = Valid ? Value + "d = " + Value.ToString("X") + "h = " + AsmSourceTools.ToStringBin(Value, NBits) + "b" : keyword; description.Inlines.Add(Make_Run2(constantStr, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Constant)))); break; } case AsmTokenType.UserDefined1: { description = new TextBlock(); description.Inlines.Add(Make_Run1("User defined 1: ", foreground)); description.Inlines.Add(Make_Run2(keyword, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Userdefined1)))); string descr = this._asmDudeTools.Get_Description(keywordUpper); if (descr.Length > 0) { if (keyword.Length > (AsmDudePackage.maxNumberOfCharsInToolTips / 2)) { descr = "\n" + descr; } description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + descr, AsmDudePackage.maxNumberOfCharsInToolTips)) { Foreground = foreground }); } break; } case AsmTokenType.UserDefined2: { description = new TextBlock(); description.Inlines.Add(Make_Run1("User defined 2: ", foreground)); description.Inlines.Add(Make_Run2(keyword, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Userdefined2)))); string descr = this._asmDudeTools.Get_Description(keywordUpper); if (descr.Length > 0) { if (keyword.Length > (AsmDudePackage.maxNumberOfCharsInToolTips / 2)) { descr = "\n" + descr; } description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + descr, AsmDudePackage.maxNumberOfCharsInToolTips)) { Foreground = foreground }); } break; } case AsmTokenType.UserDefined3: { description = new TextBlock(); description.Inlines.Add(Make_Run1("User defined 3: ", foreground)); description.Inlines.Add(Make_Run2(keyword, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Userdefined3)))); string descr = this._asmDudeTools.Get_Description(keywordUpper); if (descr.Length > 0) { if (keyword.Length > (AsmDudePackage.maxNumberOfCharsInToolTips / 2)) { descr = "\n" + descr; } description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + descr, AsmDudePackage.maxNumberOfCharsInToolTips)) { Foreground = foreground }); } break; } default: //description = new TextBlock(); //description.Inlines.Add(makeRun1("Unused tagType " + asmTokenTag.Tag.type)); break; } if (description != null) { description.FontSize = AsmDudeToolsStatic.GetFontSize() + 2; description.FontFamily = AsmDudeToolsStatic.GetFontType(); //AsmDudeToolsStatic.Output_INFO(string.Format("{0}:AugmentQuickInfoSession; setting description fontSize={1}; fontFamily={2}", this.ToString(), description.FontSize, description.FontFamily)); quickInfoContent.Add(description); } } } //AsmDudeToolsStatic.Output_INFO("AsmQuickInfoSource:AugmentQuickInfoSession: applicableToSpan=\"" + applicableToSpan + "\"; quickInfoContent,Count=" + quickInfoContent.Count); AsmDudeToolsStatic.Print_Speed_Warning(time1, "QuickInfo"); }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (session.TextView.TextBuffer == this.TextBuffer) { ITextSnapshot currentSnapshot = this.TextBuffer.CurrentSnapshot; SnapshotPoint?triggerPoint = session.GetTriggerPoint(currentSnapshot); if (!triggerPoint.HasValue) { return; } foreach (var span in this.Aggregator.GetTags(new SnapshotSpan(triggerPoint.Value, triggerPoint.Value))) { if (!span.Tag.ClassificationType.IsOfType(AntlrClassificationTypeNames.LexerRule) && !span.Tag.ClassificationType.IsOfType(AntlrClassificationTypeNames.ParserRule)) { continue; } NormalizedSnapshotSpanCollection spans = span.Span.GetSpans(currentSnapshot); if (spans.Count == 1) { SnapshotSpan span2 = spans[0]; SnapshotSpan span3 = span.Span.GetSpans(span.Span.AnchorBuffer)[0]; if (span2.Length == span3.Length) { SnapshotSpan span4 = spans[0]; if (span4.Contains(triggerPoint.Value)) { StringBuilder builder = new StringBuilder(); string ruleName = span2.GetText(); var rules = BackgroundParser.RuleSpans; KeyValuePair <ITrackingSpan, ITrackingPoint> value; if (rules == null || !rules.TryGetValue(ruleName, out value)) { #if DEBUG if (span.Tag.ClassificationType.IsOfType(AntlrClassificationTypeNames.LexerRule)) { builder.Append("Found an unknown lexer rule."); } else { builder.Append("Found an unknown parser rule."); } #else return; #endif } else { SnapshotPoint ruleSeek = value.Value.GetPoint(triggerPoint.Value.Snapshot); if (span2.Contains(ruleSeek)) { return; } builder.Append(value.Key.GetText(span2.Snapshot)); } //builder.AppendLine(span.Tag.Url.OriginalString); //builder.Append(Strings.UrlQuickInfoFollowLink); quickInfoContent.Add(builder.ToString()); applicableToSpan = currentSnapshot.CreateTrackingSpan((Span)spans[0], SpanTrackingMode.EdgeExclusive); } } } } } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> quickInfoContent, out ITrackingSpan applicableToSpan) { Current = this; _timer.Stop(); _activeAreaRect = default(D.Rectangle); _activeAreaRect = default(D.Rectangle); if (_subHuntWindow != null) { _subHuntWindow.Close(); } _subHuntWindow = null; _container = null; Debug.WriteLine("AugmentQuickInfoSession"); _wpfTextView = (IWpfTextView)session.TextView; _fileModel = VsUtils.TryGetFileModel(_textBuffer); Debug.Assert(_fileModel != null); _textViewModel = VsUtils.GetOrCreateTextViewModel(_wpfTextView, _fileModel); Debug.Assert(_textViewModel != null); Hint.SetCallbacks(SubHintText, SpanClassToBrush); Hint.Click += Hint_Click; Hint.BackgroundResourceReference = EnvironmentColors.ToolTipBrushKey; Hint.ForegroundResourceReference = EnvironmentColors.ToolTipTextBrushKey; var snapshot = _textBuffer.CurrentSnapshot; var triggerPoint = session.GetTriggerPoint(snapshot); if (triggerPoint.HasValue) { _wpfTextView = (IWpfTextView)session.TextView; var extent = GetTextExtent(triggerPoint.Value); var text = extent.Span.GetText(); if (!text.All(c => char.IsLetterOrDigit(c) || c == '_')) { applicableToSpan = null; return; } var trackingSpan = snapshot.CreateTrackingSpan(extent.Span, SpanTrackingMode.EdgeInclusive); applicableToSpan = trackingSpan; var rectOpt = GetViewSpanRect(trackingSpan); if (!rectOpt.HasValue) { return; } _wpfTextView.VisualElement.MouseWheel += MouseWheel; _activeAreaRect = rectOpt.Value.ToRectangle(); _session = session; session.Dismissed += OnDismissed; var container = new PopupContainer(); Subscribe(container); container.LayoutUpdated += Container_LayoutUpdated; container.PopupOpened += PopupOpened; _container = container; _container.Children.Add(new System.Windows.Controls.TextBlock() { Text = "loading.." }); quickInfoContent.Add(container); _timer.Tick += _timer_Tick; //Externals.FillRect(_activeAreaRect); return; } applicableToSpan = null; }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (!XSharpProjectPackage.Instance.DebuggerIsRunning) { try { XSharpModel.ModelWalker.Suspend(); var package = XSharp.Project.XSharpProjectPackage.Instance; var optionsPage = package.GetIntellisenseOptionsPage(); if (optionsPage.DisableQuickInfo) { return; } // Map the trigger point down to our buffer. SnapshotPoint?subjectTriggerPoint = session.GetTriggerPoint(_subjectBuffer.CurrentSnapshot); if (!subjectTriggerPoint.HasValue) { return; } ITextSnapshot currentSnapshot = subjectTriggerPoint.Value.Snapshot; WriteOutputMessage($"Triggerpoint: {subjectTriggerPoint.Value.Position}"); if ((subjectTriggerPoint.Value.Position == lastTriggerPoint) && (lastVersion == currentSnapshot.Version.VersionNumber)) { if (lastHelp != null) { var description = new TextBlock(); description.Inlines.AddRange(lastHelp); qiContent.Add(description); WriteOutputMessage($"Return last help content: {lastHelp}"); } if (lastSpan != null) { applicableToSpan = lastSpan; } return; } // We don't want to lex the buffer. So get the tokens from the last lex run // and when these are too old, then simply bail out var tokens = _subjectBuffer.GetTokens(); if (tokens != null) { if (tokens.SnapShot.Version != currentSnapshot.Version) { return; } } lastTriggerPoint = subjectTriggerPoint.Value.Position; //look for occurrences of our QuickInfo words in the span ITextStructureNavigator navigator = _provider.NavigatorService.GetTextStructureNavigator(_subjectBuffer); TextExtent extent = navigator.GetExtentOfWord(subjectTriggerPoint.Value); string searchText = extent.Span.GetText(); // First, where are we ? int caretPos = subjectTriggerPoint.Value.Position; int lineNumber = subjectTriggerPoint.Value.GetContainingLine().LineNumber; var snapshot = session.TextView.TextBuffer.CurrentSnapshot; if (_file == null) { return; } // Then, the corresponding Type/Element if possible IToken stopToken; //ITokenStream tokenStream; XSharpModel.XTypeMember member = XSharpLanguage.XSharpTokenTools.FindMember(lineNumber, _file); XSharpModel.XType currentNamespace = XSharpLanguage.XSharpTokenTools.FindNamespace(caretPos, _file); // adjust caretpos, for other completions we need to stop before the caret. Now we include the caret List <String> tokenList = XSharpLanguage.XSharpTokenTools.GetTokenList(caretPos + 1, lineNumber, tokens.TokenStream, out stopToken, true, _file, false); // Check if we can get the member where we are //if (tokenList.Count > 1) //{ // tokenList.RemoveRange(0, tokenList.Count - 1); //} // LookUp for the BaseType, reading the TokenList (From left to right) XSharpLanguage.CompletionElement gotoElement; String currentNS = ""; if (currentNamespace != null) { currentNS = currentNamespace.Name; } XSharpModel.CompletionType cType = XSharpLanguage.XSharpTokenTools.RetrieveType(_file, tokenList, member, currentNS, stopToken, out gotoElement, snapshot, lineNumber); // // if ((gotoElement != null) && (gotoElement.IsInitialized)) { // Ok, find it ! Let's go ;) applicableToSpan = currentSnapshot.CreateTrackingSpan ( extent.Span.Start, searchText.Length, SpanTrackingMode.EdgeInclusive ); if (gotoElement.XSharpElement != null) { if (gotoElement.XSharpElement.Kind == XSharpModel.Kind.Constructor) { if (gotoElement.XSharpElement.Parent != null) { var description = new TextBlock(); description.Inlines.Add(new Run(gotoElement.XSharpElement.Parent.Description)); qiContent.Add(description); } } else { var description = new TextBlock(); description.Inlines.Add(new Run(gotoElement.XSharpElement.Description)); qiContent.Add(description); } } else if (gotoElement.SystemElement is TypeInfo) { QuickInfoTypeAnalysis analysis = new QuickInfoTypeAnalysis((TypeInfo)gotoElement.SystemElement); var description = new TextBlock(); description.Inlines.AddRange(analysis.WPFDescription); qiContent.Add(description); } else { // This works with System.MemberInfo AND QuickInfoMemberAnalysis analysis = null; if (gotoElement.SystemElement is MemberInfo) { string xmldoc = XSharpXMLDocMember.GetDocSummary(gotoElement.SystemElement, member.File.Project); analysis = new QuickInfoMemberAnalysis(gotoElement.SystemElement); if (analysis.IsInitialized) { if ((analysis.Kind == XSharpModel.Kind.Constructor) && (cType != null) && (cType.SType != null)) { QuickInfoTypeAnalysis typeAnalysis; typeAnalysis = new QuickInfoTypeAnalysis(cType.SType.GetTypeInfo()); if (typeAnalysis.IsInitialized) { var description = new TextBlock(); description.Inlines.AddRange(typeAnalysis.WPFDescription); qiContent.Add(description); } } else { var description = new TextBlock(); description.Inlines.AddRange(analysis.WPFDescription); qiContent.Add(description); } if (xmldoc != null) { qiContent.Add(xmldoc); } } } } if (qiContent.Count > 0) { TextBlock description; description = qiContent[0] as TextBlock; if (description != null) { lastHelp = new Inline[description.Inlines.Count]; description.Inlines.CopyTo(lastHelp, 0); lastSpan = applicableToSpan; lastVersion = currentSnapshot.Version.VersionNumber; WriteOutputMessage($"Found new help content: {lastHelp}"); } } return; } } catch (Exception ex) { XSharpProjectPackage.Instance.DisplayOutPutMessage("XSharpQuickInfo.AugmentQuickInfoSession failed : "); XSharpProjectPackage.Instance.DisplayException(ex); } finally { XSharpModel.ModelWalker.Resume(); } } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { // Map the trigger point down to our buffer. SnapshotPoint?subjectTriggerPoint = session.GetTriggerPoint(m_subjectBuffer.CurrentSnapshot); if (!subjectTriggerPoint.HasValue) { applicableToSpan = null; return; } var funclist = m_parsedProject.GetAvailableFunctionSignatures(); m_dictionary = new Dictionary <string, string>(); foreach (var func in funclist) { m_dictionary.Add(func.Name.Text, func.ToString()); } var structlist = m_parsedProject.GetAvailableStructureDefinitions(); foreach (var st in structlist) { m_dictionary.Add(st.Key, st.Value.ToString()); } var variables = GetApplicableVariables(session); foreach (var v in variables) { m_dictionary.Add(v.Name.Text, v.ToString()); } ITextSnapshot currentSnapshot = subjectTriggerPoint.Value.Snapshot; SnapshotSpan querySpan = new SnapshotSpan(subjectTriggerPoint.Value, 0); //look for occurrences of our QuickInfo words in the span ITextStructureNavigator navigator = m_provider.NavigatorService.GetTextStructureNavigator(m_subjectBuffer); TextExtent extent = navigator.GetExtentOfWord(subjectTriggerPoint.Value); string searchText = extent.Span.GetText(); foreach (string key in m_dictionary.Keys) { if (key.CompareTo(searchText) == 0) { applicableToSpan = currentSnapshot.CreateTrackingSpan(extent.Span.Start, key.Length, SpanTrackingMode.EdgeInclusive); string value; m_dictionary.TryGetValue(key, out value); if (value != null) { qiContent.Add(value); } else { qiContent.Add(""); } return; } } applicableToSpan = null; }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; #if false // TODO if (!ProjectionBufferGraph.GetFromProperties(session.TextView.BufferGraph.TopBuffer, out ProjectionBufferGraph projectionBufferGraph)) { return; } #endif // If the mouse position maps down to the csharp buffer then it should be handled by C# only. this.csharpBuffer = this.csharpBuffer ?? PSharpQuickInfoController.GetCSharpBuffer(session.TextView.BufferGraph.TopBuffer); if (this.csharpBuffer != null && session.GetTriggerPoint(this.csharpBuffer.CurrentSnapshot) != null) { return; } // Map the trigger point down to our buffer. SnapshotPoint?subjectTriggerPoint = session.GetTriggerPoint(this.subjectBuffer.CurrentSnapshot); if (!subjectTriggerPoint.HasValue) { return; } #if false // TODO var isEmbeddedPSharp = projectionBufferGraph.IsEmbeddedPSharpPoint(subjectTriggerPoint.Value); #endif TokenType preprocessTokenType(TokenType tokenType) { #if false // TODO if (isEmbeddedPSharp) { switch (tokenType) { case TokenType.MachineDecl: return(TokenType.MachineIdDecl); } } #endif return(tokenType); } var currentSnapshot = subjectTriggerPoint.Value.Snapshot; var querySpan = new SnapshotSpan(subjectTriggerPoint.Value, 0); foreach (var tagSpan in this.tagAggregator.GetTags(new SnapshotSpan(subjectTriggerPoint.Value, subjectTriggerPoint.Value))) { var tokenType = preprocessTokenType(tagSpan.Tag.Type); if (IsIgnoreTokenType(tokenType) || !TokenTypeTips.TryGetValue(tokenType, out string content)) { continue; } var firstSpan = tagSpan.Span.GetSpans(this.subjectBuffer).First(); applicableToSpan = this.subjectBuffer.CurrentSnapshot.CreateTrackingSpan(firstSpan, SpanTrackingMode.EdgeExclusive); var start = tagSpan.Span.Start.GetPoint(this.subjectBuffer, PositionAffinity.Predecessor).Value.Position; var end = tagSpan.Span.End.GetPoint(this.subjectBuffer, PositionAffinity.Predecessor).Value.Position; var text = currentSnapshot.GetText().Substring(start, end - start); var prefix = IdentifierTokenTypes.TryGetValue(tokenType, out string identifierTypeName) ? $"({identifierTypeName}) {text}: " : string.Empty; qiContent.Add($"{prefix}{content}"); } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (_disposed) { throw new ObjectDisposedException("StaDynQuickInfoSource"); } var triggerPoint = (SnapshotPoint)session.GetTriggerPoint(_buffer.CurrentSnapshot); char c = triggerPoint.GetChar(); if (triggerPoint == null || Char.IsWhiteSpace(c)) { return; } //StaDynParser parser = new StaDynParser(session.TextView.TextBuffer, FileUtilities.Instance.getCurrentOpenDocumentFilePath()); ////Parse source //StaDynSourceFileAST parseResult = parser.parseSource(); ////parseResult = DecorateAST.Instance.completeDecorateAST(parseResult); ////parseResult= DecorateAST.Instance.completeDecorateAndUpdate(parseResult.FileName, true); //parseResult = DecorateAST.Instance.completeDecorateAndUpdate(parseResult); StaDynParser parser = new StaDynParser(); parser.parseAll(); StaDynSourceFileAST parseResult = ProjectFileAST.Instance.getAstFile(FileUtilities.Instance.getCurrentOpenDocumentFilePath()); if (parseResult == null || parseResult.Ast == null) { return; } foreach (IMappingTagSpan <StaDynTokenTag> curTag in _aggregator.GetTags(new SnapshotSpan(triggerPoint, triggerPoint))) { var tagType = curTag.Tag.type; var tagSpan = curTag.Span.GetSpans(_buffer).First(); applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); string output = String.Empty; switch (tagType) { case StaDynTokenTypes.Text: case StaDynTokenTypes.Identifier: case StaDynTokenTypes.String: case StaDynTokenTypes.TypeDefinition: case StaDynTokenTypes.DynamicVar: case StaDynTokenTypes.Literal: //Gets the tag info output = this.getQuickInfo(curTag, parseResult); break; case StaDynTokenTypes.Operator: case StaDynTokenTypes.Delimiter: case StaDynTokenTypes.WhiteSpace: //Nothing to do continue; case StaDynTokenTypes.Keyword: case StaDynTokenTypes.LineComment: case StaDynTokenTypes.Comment: case StaDynTokenTypes.Number: if (curTag.Tag.StaDynToken.getText() == ".") { continue; } //Show the same tag output = curTag.Tag.StaDynToken.getText(); break; default: break; } quickInfoContent.Add(output); } }
private void Handle(IQuickInfoSession session, IList <object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; DateTime time1 = DateTime.Now; ITextSnapshot snapshot = this._textBuffer.CurrentSnapshot; SnapshotPoint?triggerPoint = session.GetTriggerPoint(snapshot); if (!triggerPoint.HasValue) { AsmDudeToolsStatic.Output_WARNING(string.Format("{0}:Handle: trigger point is null", this.ToString())); return; } Brush foreground = AsmDudeToolsStatic.GetFontColor(); (AsmTokenTag tag, SnapshotSpan? keywordSpan) = AsmDudeToolsStatic.GetAsmTokenTag(this._aggregator, triggerPoint.Value); if (keywordSpan.HasValue) { SnapshotSpan tagSpan = keywordSpan.Value; string keyword = tagSpan.GetText(); string keywordUpper = keyword.ToUpper(); AsmDudeToolsStatic.Output_INFO(string.Format("{0}:Handle: keyword=\"{1}\"; type={2}; file=\"{3}\"", this.ToString(), keyword, tag.Type, AsmDudeToolsStatic.GetFilename(session.TextView.TextBuffer))); applicableToSpan = snapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeInclusive); TextBlock description = null; switch (tag.Type) { case AsmTokenType.Misc: { description = new TextBlock(); description.Inlines.Add(Make_Run1("Keyword ", foreground)); description.Inlines.Add(Make_Run2(keyword, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Misc)))); string descr = this._asmDudeTools.Get_Description(keywordUpper); if (descr.Length > 0) { if (keyword.Length > (AsmDudePackage.MaxNumberOfCharsInToolTips / 2)) { descr = "\n" + descr; } description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + descr, AsmDudePackage.MaxNumberOfCharsInToolTips)) { Foreground = foreground, }); } break; } case AsmTokenType.Directive: { description = new TextBlock(); description.Inlines.Add(Make_Run1("Directive ", foreground)); description.Inlines.Add(Make_Run2(keyword, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Directive)))); string descr = this._asmDudeTools.Get_Description(keywordUpper); if (descr.Length > 0) { if (keyword.Length > (AsmDudePackage.MaxNumberOfCharsInToolTips / 2)) { descr = "\n" + descr; } description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + descr, AsmDudePackage.MaxNumberOfCharsInToolTips)) { Foreground = foreground, }); } break; } case AsmTokenType.Register: { int lineNumber = AsmDudeToolsStatic.Get_LineNumber(tagSpan); if (keywordUpper.StartsWith("%")) { keywordUpper = keywordUpper.Substring(1); // remove the preceding % in AT&T syntax } Rn reg = RegisterTools.ParseRn(keywordUpper, true); if (this._asmDudeTools.RegisterSwitchedOn(reg)) { RegisterTooltipWindow registerTooltipWindow = new RegisterTooltipWindow(foreground); registerTooltipWindow.SetDescription(reg, this._asmDudeTools); registerTooltipWindow.SetAsmSim(this._asmSimulator, reg, lineNumber, true); quickInfoContent.Add(registerTooltipWindow); } break; } case AsmTokenType.Mnemonic: // intentional fall through case AsmTokenType.MnemonicOff: // intentional fall through case AsmTokenType.Jump: { (Mnemonic mnemonic, _) = AsmSourceTools.ParseMnemonic_Att(keywordUpper, true); InstructionTooltipWindow instructionTooltipWindow = new InstructionTooltipWindow(foreground) { Session = session, // set the owner of this windows such that we can manually close this window }; instructionTooltipWindow.SetDescription(mnemonic, this._asmDudeTools); instructionTooltipWindow.SetPerformanceInfo(mnemonic, this._asmDudeTools); int lineNumber = AsmDudeToolsStatic.Get_LineNumber(tagSpan); instructionTooltipWindow.SetAsmSim(this._asmSimulator, lineNumber, true); quickInfoContent.Add(instructionTooltipWindow); break; } case AsmTokenType.Label: { string label = keyword; string labelPrefix = tag.Misc; string full_Qualified_Label = AsmDudeToolsStatic.Make_Full_Qualified_Label(labelPrefix, label, AsmDudeToolsStatic.Used_Assembler); description = new TextBlock(); description.Inlines.Add(Make_Run1("Label ", foreground)); description.Inlines.Add(Make_Run2(full_Qualified_Label, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Label)))); string descr = this.Get_Label_Description(full_Qualified_Label); if (descr.Length == 0) { descr = this.Get_Label_Description(label); } if (descr.Length > 0) { if (keyword.Length > (AsmDudePackage.MaxNumberOfCharsInToolTips / 2)) { descr = "\n" + descr; } description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + descr, AsmDudePackage.MaxNumberOfCharsInToolTips)) { Foreground = foreground, }); } break; } case AsmTokenType.LabelDef: { string label = keyword; string extra_Tag_Info = tag.Misc; string full_Qualified_Label; if ((extra_Tag_Info != null) && extra_Tag_Info.Equals(AsmTokenTag.MISC_KEYWORD_PROTO)) { full_Qualified_Label = label; } else { full_Qualified_Label = AsmDudeToolsStatic.Make_Full_Qualified_Label(extra_Tag_Info, label, AsmDudeToolsStatic.Used_Assembler); } AsmDudeToolsStatic.Output_INFO("AsmQuickInfoSource:AugmentQuickInfoSession: found label def " + full_Qualified_Label); description = new TextBlock(); description.Inlines.Add(Make_Run1("Label ", foreground)); description.Inlines.Add(Make_Run2(full_Qualified_Label, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Label)))); string descr = this.Get_Label_Def_Description(full_Qualified_Label, label); if (descr.Length > 0) { if (keyword.Length > (AsmDudePackage.MaxNumberOfCharsInToolTips / 2)) { descr = "\n" + descr; } description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + descr, AsmDudePackage.MaxNumberOfCharsInToolTips)) { Foreground = foreground, }); } break; } case AsmTokenType.Constant: { (bool valid, ulong value, int nBits) = AsmSourceTools.Evaluate_Constant(keyword); string constantStr = valid ? value + "d = " + value.ToString("X") + "h = " + AsmSourceTools.ToStringBin(value, nBits) + "b" : keyword; if (true) { TextBoxWindow myWindow = new TextBoxWindow(); myWindow.MouseRightButtonUp += this.MyWindow_MouseRightButtonUp; myWindow.MyContent.Text = "Constant X: " + constantStr; myWindow.MyContent.Foreground = foreground; myWindow.MyContent.MouseRightButtonUp += this.MyContent_MouseRightButtonUp; quickInfoContent.Add(myWindow); } else { description = new SelectableTextBlock(); description.Inlines.Add(Make_Run1("Constant ", foreground)); description.Inlines.Add(Make_Run2(constantStr, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Constant)))); } break; } case AsmTokenType.UserDefined1: { description = new TextBlock(); description.Inlines.Add(Make_Run1("User defined 1: ", foreground)); description.Inlines.Add(Make_Run2(keyword, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Userdefined1)))); string descr = this._asmDudeTools.Get_Description(keywordUpper); if (descr.Length > 0) { if (keyword.Length > (AsmDudePackage.MaxNumberOfCharsInToolTips / 2)) { descr = "\n" + descr; } description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + descr, AsmDudePackage.MaxNumberOfCharsInToolTips)) { Foreground = foreground, }); } break; } case AsmTokenType.UserDefined2: { description = new TextBlock(); description.Inlines.Add(Make_Run1("User defined 2: ", foreground)); description.Inlines.Add(Make_Run2(keyword, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Userdefined2)))); string descr = this._asmDudeTools.Get_Description(keywordUpper); if (descr.Length > 0) { if (keyword.Length > (AsmDudePackage.MaxNumberOfCharsInToolTips / 2)) { descr = "\n" + descr; } description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + descr, AsmDudePackage.MaxNumberOfCharsInToolTips)) { Foreground = foreground, }); } break; } case AsmTokenType.UserDefined3: { description = new TextBlock(); description.Inlines.Add(Make_Run1("User defined 3: ", foreground)); description.Inlines.Add(Make_Run2(keyword, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Userdefined3)))); string descr = this._asmDudeTools.Get_Description(keywordUpper); if (descr.Length > 0) { if (keyword.Length > (AsmDudePackage.MaxNumberOfCharsInToolTips / 2)) { descr = "\n" + descr; } description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + descr, AsmDudePackage.MaxNumberOfCharsInToolTips)) { Foreground = foreground, }); } break; } default: //description = new TextBlock(); //description.Inlines.Add(makeRun1("Unused tagType " + asmTokenTag.Tag.type)); break; } if (description != null) { description.Focusable = true; description.FontSize = AsmDudeToolsStatic.GetFontSize() + 2; description.FontFamily = AsmDudeToolsStatic.GetFontType(); //AsmDudeToolsStatic.Output_INFO(string.Format("{0}:AugmentQuickInfoSession; setting description fontSize={1}; fontFamily={2}", this.ToString(), description.FontSize, description.FontFamily)); quickInfoContent.Add(description); } } //AsmDudeToolsStatic.Output_INFO("AsmQuickInfoSource:AugmentQuickInfoSession: applicableToSpan=\"" + applicableToSpan + "\"; quickInfoContent,Count=" + quickInfoContent.Count); AsmDudeToolsStatic.Print_Speed_Warning(time1, "QuickInfo"); }
/// <summary> /// Determine which pieces of Quickinfo content should be displayed /// </summary> public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> quickInfoContent, out ITrackingSpan applicableToSpan) { //AsmDudeToolsStatic.Output_INFO("AsmQuickInfoSource:AugmentQuickInfoSession"); applicableToSpan = null; try { DateTime time1 = DateTime.Now; ITextSnapshot snapshot = this._sourceBuffer.CurrentSnapshot; var triggerPoint = (SnapshotPoint)session.GetTriggerPoint(snapshot); if (triggerPoint == null) { AsmDudeToolsStatic.Output_INFO("AsmQuickInfoSource:AugmentQuickInfoSession: trigger point is null"); return; } string keyword = ""; IEnumerable <IMappingTagSpan <AsmTokenTag> > enumerator = this._aggregator.GetTags(new SnapshotSpan(triggerPoint, triggerPoint)); //AsmDudeToolsStatic.Output("INFO: AsmQuickInfoSource:AugmentQuickInfoSession: enumerator.Count="+ enumerator.Count()); if (enumerator.Count() > 0) { if (false) { // TODO: multiple tags at the provided triggerPoint is most likely the result of a bug in AsmTokenTagger, but it seems harmless... if (enumerator.Count() > 1) { foreach (IMappingTagSpan <AsmTokenTag> v in enumerator) { AsmDudeToolsStatic.Output(string.Format("WARNING: {0}:AugmentQuickInfoSession. more than one tag! \"{1}\"", ToString(), v.Span.GetSpans(this._sourceBuffer).First().GetText())); } } } IMappingTagSpan <AsmTokenTag> asmTokenTag = enumerator.First(); SnapshotSpan tagSpan = asmTokenTag.Span.GetSpans(this._sourceBuffer).First(); keyword = tagSpan.GetText(); int lineNumber = tagSpan.Snapshot.GetLineNumberFromPosition(tagSpan.Start); //AsmDudeToolsStatic.Output("INFO: AsmQuickInfoSource:AugmentQuickInfoSession: keyword=\""+ keyword + "\"; type=" + asmTokenTag.Tag.type +"; file="+AsmDudeToolsStatic.GetFileName(session.TextView.TextBuffer)); string keywordUpper = keyword.ToUpper(); applicableToSpan = snapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); TextBlock description = null; switch (asmTokenTag.Tag.Type) { case AsmTokenType.Misc: { description = new TextBlock(); description.Inlines.Add(Make_Run1("Keyword ", this._foreground)); description.Inlines.Add(Make_Run2(keyword, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Misc)))); string descr = this._asmDudeTools.Get_Description(keywordUpper); if (descr.Length > 0) { description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + descr, AsmDudePackage.maxNumberOfCharsInToolTips)) { Foreground = this._foreground }); } break; } case AsmTokenType.Directive: { description = new TextBlock(); description.Inlines.Add(Make_Run1("Directive ", this._foreground)); description.Inlines.Add(Make_Run2(keyword, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Directive)))); string descr = this._asmDudeTools.Get_Description(keywordUpper); if (descr.Length > 0) { description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + descr, AsmDudePackage.maxNumberOfCharsInToolTips)) { Foreground = this._foreground }); } break; } case AsmTokenType.Register: { description = new TextBlock(); description.Inlines.Add(Make_Run1("Register ", this._foreground)); description.Inlines.Add(Make_Run2(keyword, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Register)))); string register_Descr = this._asmDudeTools.Get_Description(keywordUpper); if (register_Descr.Length > 0) { description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + register_Descr, AsmDudePackage.maxNumberOfCharsInToolTips)) { Foreground = this._foreground }); } if (this._asmSimulator.Is_Enabled) { IState_R state = this._asmSimulator.GetState(lineNumber, true); string msg = this._asmSimulator.GetRegisterValue(RegisterTools.ParseRn(keyword), state); if (msg.Length == 0) { msg = "Calculating register content"; } description.Inlines.Add(new Run(AsmSourceTools.Linewrap("\n" + msg, AsmDudePackage.maxNumberOfCharsInToolTips)) { Foreground = this._foreground }); } break; } case AsmTokenType.Mnemonic: case AsmTokenType.Jump: { description = new TextBlock(); description.Inlines.Add(Make_Run1("Mnemonic ", this._foreground)); description.Inlines.Add(Make_Run2(keyword, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Opcode)))); Mnemonic mmemonic = AsmSourceTools.ParseMnemonic(keywordUpper); { string archStr = ":" + ArchTools.ToString(this._asmDudeTools.Mnemonic_Store.GetArch(mmemonic)) + " "; string descr = this._asmDudeTools.Mnemonic_Store.GetDescription(mmemonic); description.Inlines.Add(new Run(AsmSourceTools.Linewrap(archStr + descr, AsmDudePackage.maxNumberOfCharsInToolTips)) { Foreground = this._foreground }); } { // show performance information MicroArch selectedMicroarchitures = AsmDudeToolsStatic.Get_MicroArch_Switched_On(); IReadOnlyList <PerformanceItem> performanceData = this._asmDudeTools.Performance_Store.GetPerformance(mmemonic, selectedMicroarchitures); if (performanceData.Count > 0) { FontFamily family = new FontFamily("Consolas"); IList <Run> list = new List <Run>(); description.Inlines.Add(new Run(string.Format("\n\n{0,-15}{1,-24}{2,-10}{3,-10}\n", "Architecture", "Instruction", "Latency", "Throughput")) { FontFamily = family, FontStyle = FontStyles.Italic, FontWeight = FontWeights.Bold, Foreground = this._foreground }); foreach (PerformanceItem item in performanceData) { description.Inlines.Add(new Run(string.Format("{0,-15}{1,-24}{2,-10}{3,-10}{4,-10}\n", item._microArch, item._instr + " " + item._args, item._latency, item._throughput, item._remark)) { FontFamily = family, Foreground = this._foreground }); } } } break; } case AsmTokenType.Label: { string label = keyword; string labelPrefix = asmTokenTag.Tag.Misc; string full_Qualified_Label = AsmDudeToolsStatic.Make_Full_Qualified_Label(labelPrefix, label, AsmDudeToolsStatic.Used_Assembler); description = new TextBlock(); description.Inlines.Add(Make_Run1("Label ", this._foreground)); description.Inlines.Add(Make_Run2(full_Qualified_Label, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Label)))); string descr = Get_Label_Description(full_Qualified_Label); if (descr.Length == 0) { descr = Get_Label_Description(label); } if (descr.Length > 0) { description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + descr, AsmDudePackage.maxNumberOfCharsInToolTips)) { Foreground = this._foreground }); } break; } case AsmTokenType.LabelDef: { string label = keyword; string extra_Tag_Info = asmTokenTag.Tag.Misc; string full_Qualified_Label; if ((extra_Tag_Info != null) && extra_Tag_Info.Equals(AsmTokenTag.MISC_KEYWORD_PROTO)) { full_Qualified_Label = label; } else { full_Qualified_Label = AsmDudeToolsStatic.Make_Full_Qualified_Label(extra_Tag_Info, label, AsmDudeToolsStatic.Used_Assembler); } AsmDudeToolsStatic.Output_INFO("AsmQuickInfoSource:AugmentQuickInfoSession: found label def " + full_Qualified_Label); description = new TextBlock(); description.Inlines.Add(Make_Run1("Label ", this._foreground)); description.Inlines.Add(Make_Run2(full_Qualified_Label, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Label)))); string descr = Get_Label_Def_Description(full_Qualified_Label, label); if (descr.Length > 0) { description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + descr, AsmDudePackage.maxNumberOfCharsInToolTips)) { Foreground = this._foreground }); } break; } case AsmTokenType.Constant: { description = new TextBlock(); description.Inlines.Add(Make_Run1("Constant ", this._foreground)); description.Inlines.Add(Make_Run2(keyword, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Constant)))); break; } default: //description = new TextBlock(); //description.Inlines.Add(makeRun1("Unused tagType " + asmTokenTag.Tag.type)); break; } if (description != null) { description.FontSize = AsmDudeToolsStatic.Get_Font_Size() + 2; description.FontFamily = AsmDudeToolsStatic.Get_Font_Type(); //AsmDudeToolsStatic.Output(string.Format("INFO: {0}:AugmentQuickInfoSession; setting description fontSize={1}; fontFamily={2}", this.ToString(), description.FontSize, description.FontFamily)); quickInfoContent.Add(description); } } //AsmDudeToolsStatic.Output("INFO: AsmQuickInfoSource:AugmentQuickInfoSession: applicableToSpan=\"" + applicableToSpan + "\"; quickInfoContent,Count=" + quickInfoContent.Count); AsmDudeToolsStatic.Print_Speed_Warning(time1, "QuickInfo"); } catch (Exception e) { AsmDudeToolsStatic.Output(string.Format("ERROR: {0}:AugmentQuickInfoSession; e={1}", ToString(), e.ToString())); } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; // Map the trigger point down to our buffer. SnapshotPoint?subjectTriggerPoint = session.GetTriggerPoint(m_subjectBuffer.CurrentSnapshot); if (!subjectTriggerPoint.HasValue) { return; } ITextSnapshot currentSnapshot = subjectTriggerPoint.Value.Snapshot; SnapshotSpan querySpan = new SnapshotSpan(subjectTriggerPoint.Value, 0); if (_cache == null || _cache.Snapshot != currentSnapshot) { var task = Cache.Resolve(m_subjectBuffer, currentSnapshot); try { task.Wait(); } catch (Exception) { // TODO: report this to someone. return; } _cache = task.Result; if (_cache == null) { // TODO: report this to someone. return; } } ITextStructureNavigator navigator = m_provider.NavigatorService.GetTextStructureNavigator(m_subjectBuffer); TextExtent extent = navigator.GetExtentOfWord(subjectTriggerPoint.Value); string searchText = extent.Span.GetText(); var textSpan = TextSpan.FromBounds(extent.Span.Start, extent.Span.End); var methodCall = _codeModel.GetMethodCall(_cache, textSpan); if (methodCall == null) { return; } string ilSize = "IL Size: " + methodCall.Target.ILSize + " Bytes"; if (!methodCall.IsInlined) { qiContent.Add("Inlining Analyzer: " + methodCall.FailReason + (methodCall.Target.ILSize > 0 ? "\r\n" + ilSize : "")); } else { if (methodCall.Target.ILSize > 0) { qiContent.Add(ilSize); } } }
/// <inheritdoc /> public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; var tagAggregator = provider.AggregatorFactory.CreateTagAggregator <IClassificationTag>(session.TextView); var triggerPoint = session.GetTriggerPoint(textBuffer.CurrentSnapshot); if (triggerPoint != null) { SnapshotSpan tagSpan; var lineSpan = triggerPoint.Value.GetContainingLine(); string elementName = null, attrName = null, identifier = null, name; UIElement content; // Get the tags for the line containing the mouse point foreach (IMappingTagSpan <IClassificationTag> curTag in tagAggregator.GetTags( new SnapshotSpan(lineSpan.Start, lineSpan.End))) { name = curTag.Tag.ClassificationType.Classification.ToLowerInvariant(); tagSpan = curTag.Span.GetSpans(textBuffer).First(); if (name.IndexOf("identifier", StringComparison.Ordinal) != -1) { name = "identifier"; } switch (name) { case "xml doc comment - name": elementName = tagSpan.GetText().Trim(); break; case "xml doc comment - attribute name": attrName = tagSpan.GetText().Trim(); identifier = null; if (attrName == "cref") { attrName = null; } break; case "xml doc comment - attribute value": if (elementName == "conceptualLink" && attrName == "target" && tagSpan.Contains(triggerPoint.Value) && tagSpan.Length > 1) { #pragma warning disable VSTHRD010 content = this.CreateInfoText(elementName, tagSpan.GetText()); #pragma warning restore VSTHRD010 if (content != null) { applicableToSpan = textBuffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); quickInfoContent.Add(content); } return; } break; case "identifier": case "keyword": case "operator": if (attrName != null) { identifier += tagSpan.GetText(); if (name == "keyword") { identifier += " "; } } break; case "punctuation": if (identifier != null) { identifier += tagSpan.GetText(); } break; case "xml doc comment - attribute quotes": if (identifier != null) { // Set the span to that of the identifier var span = new SnapshotSpan(tagSpan.Snapshot, tagSpan.Start - identifier.Length, identifier.Length); if (span.Contains(triggerPoint.Value) && span.Length > 1) { content = this.CreateInfoText("cref", span.GetText()); if (content != null) { applicableToSpan = textBuffer.CurrentSnapshot.CreateTrackingSpan(span, SpanTrackingMode.EdgeExclusive); quickInfoContent.Add(content); } } return; } break; case "xml doc comment - text": if (elementName == "token" && tagSpan.Contains(triggerPoint.Value) && tagSpan.Length > 1) { content = this.CreateInfoText(elementName, tagSpan.GetText()); if (content != null) { applicableToSpan = textBuffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); quickInfoContent.Add(content); } return; } break; default: break; } } } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (session == null || qiContent == null || qiContent.Count > 0 || !WESettings.Instance.Css.ShowBrowserTooltip) { return; } SnapshotPoint?point = session.GetTriggerPoint(_buffer.CurrentSnapshot); if (!point.HasValue) { return; } var tree = CssEditorDocument.FromTextBuffer(_buffer); ParseItem item = tree.StyleSheet.ItemBeforePosition(point.Value.Position); if (item == null || !item.IsValid) { return; } ICssSchemaInstance schema = CssSchemaManager.SchemaManager.GetSchemaForItem(_rootSchema, item); Tuple <ParseItem, ICssCompletionListEntry> tuple = GetEntriesAndPoint(item, point.Value, schema); if (tuple == null) { return; } ParseItem tipItem = tuple.Item1; ICssCompletionListEntry entry = tuple.Item2; if (tipItem == null || entry == null) { return; } var ruleSet = item.FindType <RuleSet>(); //If the selector's full name would require computation (it's nested), compute it and add it to the output if (ruleSet != null && ruleSet.Parent.FindType <RuleSet>() != null) { qiContent.Add(LessDocument.GetLessSelectorName(ruleSet)); } applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(tipItem.Start, tipItem.Length, SpanTrackingMode.EdgeNegative); string syntax = entry.GetSyntax(schema.Version); string b = entry.GetAttribute("browsers"); if (string.IsNullOrEmpty(b) && tipItem.Parent != null && tipItem.Parent is Declaration) { b = schema.GetProperty(((Declaration)tipItem.Parent).PropertyName.Text).GetAttribute("browsers"); if (string.IsNullOrEmpty(syntax)) { syntax = tipItem.Text; } } if (!string.IsNullOrEmpty(syntax)) { //var example = CreateExample(syntax); qiContent.Add("Example: " + syntax); } Dictionary <string, string> browsers = GetBrowsers(b); qiContent.Add(CreateBrowserList(browsers)); }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { this._eventsFilter?.Remove(); this._eventsFilter = Helpers.DemandEventsFilterForCurrentNativeTextView(); session.Dismissed += this.RemoveFilter; applicableToSpan = null; var buffer = session.TextView.TextBuffer; SnapshotPoint?point = session.GetTriggerPoint(buffer.CurrentSnapshot); if (!point.HasValue) { return; } int position = point.Value.Position; var line = point.Value.GetContainingLine(); var span = new SnapshotSpan(line.Start, line.Length); var tags = this._classifier.GetClassificationSpans(span); foreach (var tag in tags.Where(t => t.Span.Contains(position))) { if (tag.ClassificationType.IsOfType(IgnoreClassificationTypes.PathNoMatch)) { string text = tag.Span.GetText(); // Only show error tooltips if (!text.Contains("../") && !IgnorePackage.Options.ShowTooltip) { continue; } string tooltip = $"The path \"{text}\" does not point to any existing file"; if (text.StartsWith("../")) { tooltip = "The entry contains a relative path segment which is not allowed"; } applicableToSpan = buffer.CurrentSnapshot.CreateTrackingSpan(tag.Span.Span, SpanTrackingMode.EdgeNegative); qiContent.Add(tooltip); break; } else if (tag.ClassificationType.IsOfType(IgnoreClassificationTypes.Path)) { if (!IgnorePackage.Options.ShowTooltip) { continue; } string pattern = tag.Span.GetText().Trim(); IgnoreTree tree = new IgnoreTree(this._root, pattern, () => { try { session.Dismiss(); } catch { } }); //Resizing in quick info causes the position to change relative to the mouse's position relative to // the original launch point. Fix the size of the control when launching from QI tree.Width = tree.MaxWidth; tree.Height = (tree.MaxHeight + tree.MinHeight) / 2; qiContent.Add(tree); applicableToSpan = buffer.CurrentSnapshot.CreateTrackingSpan(tag.Span.Span, SpanTrackingMode.EdgeNegative); //var files = GetFiles(_root, pattern); //qiContent.Add(string.Join(Environment.NewLine, files.Take(_maxFiles))); //if (files.Count() > _maxFiles) //{ // qiContent.Add($"...and {files.Count() - _maxFiles} more"); //} break; } } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> quickInfoContent, out ITrackingSpan applicableToSpan) { if (session == null) { applicableToSpan = null; return; } var span = applicableToSpan = session.ApplicableToSpan; if (quickInfoContent == null) { return; } //Wrap our method body in a safty net that checks for exceptions ContractsPackageAccessor.Current.Logger.PublicEntry(() => { //Record our start time for preformance considerations var startTime = DateTime.Now; //Is our session valid? if (session == null) { return; } //Can we get our trigger point? var triggerPoint = session.GetTriggerPoint(_textBuffer); if (triggerPoint == null) { return; } //Can we get our snapshot? var workingSnapshot = _textBuffer.CurrentSnapshot; if (workingSnapshot == null) { return; } //Can we get our SourceFile? var sourceFile = _textViewTracker.LatestSourceFile; if (sourceFile == null) { return; } //Can we get our ParseTree? var parseTree = sourceFile.GetParseTree(); if (parseTree == null) { return; } //Can we get our compilation? var comp = _textViewTracker.LatestCompilation; if (comp == null) { return; } //Is the model ready? if (!parseTree.IsModelReady() || _textViewTracker.IsLatestCompilationStale || _textViewTracker.IsLatestSourceFileStale) { //Ask for a new model ContractsPackageAccessor.Current.AskForNewVSModel(_textBuffer); //Return a message saying we aren't ready yet ContractsPackageAccessor.Current.Logger.WriteToLog("The VS model is out of date! Aborting contract lookup."); return;//"(VS isn't ready for possible contract lookup yet. Please try again in a few seconds.)"; } //Proceed cautiously string formattedContracts; try { //Can we get a call node? var targetNode = IntellisenseContractsHelper.GetTargetAtTriggerPoint(triggerPoint, workingSnapshot, parseTree); if (targetNode == null) { return; } //Can we get our semantic member? var semanticMember = IntellisenseContractsHelper.GetSemanticMember(targetNode, comp, sourceFile); if (semanticMember == null) { return; } //Can we get our contracts? formattedContracts = GetFormattedContracts(semanticMember); if (formattedContracts == null) { return; } if (span == null) { span = workingSnapshot.CreateTrackingSpan(triggerPoint.GetPosition(workingSnapshot), 1, SpanTrackingMode.EdgeInclusive); } //Give up on our contracts if we get an exception } catch (IllFormedSemanticModelException) { return; } catch (InvalidOperationException e) { if (!e.Message.Contains(ContractsPackageAccessor.InvalidOperationExceptionMessage_TheSnapshotIsOutOfDate)) { throw e; } else { this._textViewTracker.IsLatestCompilationStale = true; return; } } catch (System.Runtime.InteropServices.COMException e) { // various reasons for ComExceptions: // - binding failed // - project unavailable if (e.Message.EndsWith("out of date")) { this._textViewTracker.IsLatestCompilationStale = true; } return; } //Append our formatted contract info quickInfoContent.Add(formattedContracts); //Print our elapsed time for preformance considerations var elapseTime = DateTime.Now - startTime; ContractsPackageAccessor.Current.Logger.WriteToLog("Time to compute quickinfo: " + elapseTime.Milliseconds + "ms"); }, "AugmentQuickInfoSession"); if (span != null) { applicableToSpan = span; } }