/// <summary> /// Gets a list of tags related to a span /// </summary> /// <param name="spans"></param> /// <returns></returns> public IEnumerable <ITagSpan <ErrorTag> > GetTags(Microsoft.VisualStudio.Text.NormalizedSnapshotSpanCollection spans) { foreach (SnapshotSpan span in spans) { foreach (DesignerNode node in nodeProvider.GetNodes(span, node => node.NodeType != NDjango.Interfaces.NodeType.ParsingContext)) { switch (node.ErrorMessage.Severity) { case -1: case 0: continue; case 1: yield return(new TagSpan <ErrorTag>(node.SnapshotSpan, new ErrorTag(PredefinedErrorTypeNames.Warning))); break; default: yield return(new TagSpan <ErrorTag>(node.SnapshotSpan, new ErrorTag(PredefinedErrorTypeNames.SyntaxError))); break; } } } }
/// <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); } }
/// <summary> /// Gets a list of tags related to a span /// </summary> /// <param name="spans"></param> /// <returns></returns> public IEnumerable <ITagSpan <Constants.ErrorTag> > GetTags(Microsoft.VisualStudio.Text.NormalizedSnapshotSpanCollection spans) { foreach (SnapshotSpan span in spans) { foreach (DesignerNode node in nodeProvider.GetNodes(span, node => node.NodeType != NDjango.Interfaces.NodeType.ParsingContext)) { if (node.ErrorMessage.Severity > -1) { yield return(new TagSpan <Constants.ErrorTag>(node.SnapshotSpan, new Constants.ErrorTag())); } } } }
private CompletionSet CreateCompletionSet(CompletionContext context, SnapshotPoint point) { switch (context) { case CompletionContext.Tag: return(AbstractCompletionSet.Create <TagCompletionSet>( nodeProvider, point, n => n.NodeType == NodeType.ParsingContext )); case CompletionContext.Variable: return(AbstractCompletionSet.Create <VariableCompletionSet>( nodeProvider, point, n => n.NodeType == NodeType.ParsingContext )); case CompletionContext.FilterName: return(AbstractCompletionSet.Create <FilterCompletionSet>( nodeProvider, point, n => n.NodeType == NodeType.ParsingContext )); case CompletionContext.Word: // Get the list of all nodes with non-empty value lists List <DesignerNode> nodes = nodeProvider.GetNodes(point, n => n.Values.GetEnumerator().MoveNext()); // out of the list get the last node which is not a parsing context DesignerNode node = nodes.FindLast(n => n.NodeType != NodeType.ParsingContext); if (node == null) { break; } if (node.NodeType == NodeType.TagName) { return(new TagNameCompletionSet(node, point)); } return(new ValueCompletionSet(node, point)); default: break; } return(null); // for now let us leave the template names alone //return AbstractCompletionSet.Create<TemplateNameCompletionSet>( // nodeProvider, point, // n => // n.NodeType == NodeType.TemplateName // && string_delimiters.Contains(n.SnapshotSpan.GetText()[0]) // ); }
private void Highlight(NodeProvider provider, CaretPosition position) { SnapshotPoint point = position.BufferPosition; List <DesignerNode> tags = provider.GetNodes(point, node => node.NodeType == NDjango.Interfaces.NodeType.TagName); DesignerNode selected = tags.Count == 0 ? null : tags[0]; DesignerNode highlighted = null; point.Snapshot.TextBuffer.Properties.TryGetProperty <DesignerNode>(typeof(Highlighter), out highlighted); if (selected != highlighted) { point.Snapshot.TextBuffer.Properties[typeof(Highlighter)] = selected; provider.RaiseNodesChanged(point.Snapshot); } }
internal static CompletionSet Create <T> (NodeProvider nodeProvider, SnapshotPoint point, Predicate <DesignerNode> filter) where T : AbstractCompletionSet, new() { // Get a list of all nodes of template name type var node = nodeProvider.GetNodes(point, filter).FindLast(n => true); if (node == null) { return(null); } var result = new T(); result.Initialize(node, point); return(result); }
/// <summary> /// Validate given solution /// </summary> /// <param name="tour">Tour to check</param> private void ValidateTour(ITour tour) { if (tour == null) { throw new ArgumentNullException("tour"); } if (tour.Dimension != tour.Nodes.Count) { throw new TourInvalidException("Tour dimension does not match number of nodes on a list"); } // Fast check for the sake of speed. var set = new HashSet <int>(tour.Nodes); set.UnionWith(NodeProvider.GetNodes().Select(n => n.Id)); if (set.Count == tour.Nodes.Count) { return; } // Slow check for a more detailed exception message. var identifiers = new HashSet <int>(); foreach (var nodeId in tour.Nodes) { if (identifiers.Contains(nodeId)) { throw new TourInvalidException("Tour is invalid, has a node " + nodeId + " multiple times"); } if (null == NodeProvider.GetNode(nodeId)) { throw new TourInvalidException("Tour is invalid, has a node " + nodeId + " which is not present in a problem"); } identifiers.Add(nodeId); } }
private CompletionSet CreateCompletionSet(SnapshotPoint point) { switch (Context) { case CompletionContext.Tag: return(AbstractCompletionSet.Create <TagCompletionSet>( this, point, nodeProvider.GetNodes(point, n => n.NodeType == NodeType.ParsingContext).FindLast(n => true) )); case CompletionContext.Variable: return(AbstractCompletionSet.Create <VariableCompletionSet>( this, point, nodeProvider.GetNodes(point, n => n.NodeType == NodeType.ParsingContext).FindLast(n => true) )); case CompletionContext.FilterName: return(AbstractCompletionSet.Create <FilterName>( this, point, nodeProvider.GetNodes(point, n => n.NodeType == NodeType.ParsingContext).FindLast(n => true) )); case CompletionContext.FilterArgument: return(AbstractCompletionSet.Create <FilterArgument>( this, point, nodeProvider.GetNodes(point, n => n.NodeType == NodeType.Filter).FindLast(n => true))); case CompletionContext.Word: // Get the list of all nodes with non-empty value lists List <DesignerNode> nodes = nodeProvider.GetNodes(point, n => n.IsCompletionProvider); // out of the list get the last node which is not a parsing context DesignerNode node = nodes.FindLast(n => n.NodeType != NodeType.ParsingContext); if (node == null) { return(null); } switch (node.NodeType) { case NodeType.Reference: return(AbstractCompletionSet.Create <Member>(this, point, node)); case NodeType.TagName: return(new TagName(this, node, point)); case NodeType.TypeName: return(new TypeName(this, node, point)); default: break; } return(new ValueCompletionSet(this, node, point)); case CompletionContext.NewMemberReference: return(AbstractCompletionSet.Create <NewMember>( this, point, nodeProvider.GetNodes(point, n => n.NodeType == NodeType.Reference).FindLast(n => true))); case CompletionContext.AposString: case CompletionContext.QuotedString: return(AbstractCompletionSet.Create <TemplateName>( this, point, nodeProvider.GetNodes(point, n => n.NodeType == NodeType.TemplateName).FindLast(n => true))); default: return(null); } }
/// <summary> /// Provides a list of <see cref="ClassificationSpan"/> objects for the specified span /// </summary> /// <param name="span">span for which the list is requested</param> /// <returns></returns> /// <remarks>The list is generated based on the list of <see cref="TokenSnapshots"/> recieved /// from the tokenizer</remarks> public IList <ClassificationSpan> GetClassificationSpans(SnapshotSpan span) { List <ClassificationSpan> classifications = new List <ClassificationSpan>(); // create classifiers for currently selected tag (if any) DesignerNode selection; if (span.Snapshot.TextBuffer.Properties .TryGetProperty <DesignerNode>(typeof(Highlighter), out selection) && selection != null) { // colorize the selected tag name classifications.Add( new ClassificationSpan( selection.SnapshotSpan, classificationTypeRegistry.GetClassificationType(Constants.DJANGO_SELECTED_TAGNAME) ) ); // colorize the selected tag itself DesignerNode tag = selection.Parent; classifications.Add( new ClassificationSpan( tag.SnapshotSpan, classificationTypeRegistry.GetClassificationType(Constants.DJANGO_SELECTED_TAG) ) ); // for every context defined in the tag foreach (DesignerNode child in tag.Children) { // colorize the context if (child.NodeType == NodeType.ParsingContext) { classifications.Add( new ClassificationSpan( child.ExtensionSpan, classificationTypeRegistry.GetClassificationType(Constants.DJANGO_SELECTED_TAG) ) ); } // locate the closing tag for context if (child.NodeType == NodeType.CloseTag) { foreach (DesignerNode t in child.Children) { if (t.NodeType == NodeType.TagName) { // colorize the closing tag name classifications.Add( new ClassificationSpan( t.SnapshotSpan, classificationTypeRegistry.GetClassificationType(Constants.DJANGO_SELECTED_TAGNAME) ) ); break; } } } } } // create standard classifiers for tags nodeProvider.GetNodes(span, node => node.NodeType != NodeType.ParsingContext) .ForEach( node => { switch (node.NodeType) { case NodeType.Marker: classifications.Add( new ClassificationSpan( node.SnapshotSpan, classificationTypeRegistry.GetClassificationType(Constants.MARKER_CLASSIFIER) )); break; default: break; } ; } ); return(classifications); }