/// <param name="kind">The type of template tag we are processing</param> /// <param name="templateText">The text of the template tag which we are offering a completion in</param> /// <param name="templateStart">The offset in the buffer where the template starts</param> /// <param name="triggerPoint">The point in the buffer where the completion was triggered</param> internal CompletionSet GetCompletionSet(CompletionOptions options, VsProjectAnalyzer analyzer, TemplateTokenKind kind, string templateText, int templateStart, SnapshotPoint triggerPoint, out ITrackingSpan applicableSpan) { int position = triggerPoint.Position - templateStart; IEnumerable <CompletionInfo> tags; IDjangoCompletionContext context; applicableSpan = GetWordSpan(templateText, templateStart, triggerPoint); switch (kind) { case TemplateTokenKind.Block: var block = DjangoBlock.Parse(templateText); if (block != null) { if (position <= block.ParseInfo.Start + block.ParseInfo.Command.Length) { // we are completing before the command // TODO: Return a new set of tags? Do nothing? Do this based upon ctrl-space? tags = FilterBlocks(CompletionInfo.ToCompletionInfo(analyzer.GetTags(), StandardGlyphGroup.GlyphKeyword), triggerPoint); } else { // we are in the arguments, let the block handle the completions context = new ProjectBlockCompletionContext(analyzer, _buffer); tags = block.GetCompletions(context, position); } } else { // no tag entered yet, provide the known list of tags. tags = FilterBlocks(CompletionInfo.ToCompletionInfo(analyzer.GetTags(), StandardGlyphGroup.GlyphKeyword), triggerPoint); } break; case TemplateTokenKind.Variable: var variable = DjangoVariable.Parse(templateText); context = new ProjectBlockCompletionContext(analyzer, _buffer); if (variable != null) { tags = variable.GetCompletions(context, position); } else { // show variable names tags = CompletionInfo.ToCompletionInfo(context.Variables, StandardGlyphGroup.GlyphGroupVariable); } break; default: throw new InvalidOperationException(); } var completions = tags .OrderBy(tag => tag.DisplayText, StringComparer.OrdinalIgnoreCase) .Select(tag => new DynamicallyVisibleCompletion( tag.DisplayText, tag.InsertionText, StripDocumentation(tag.Documentation), _glyphService.GetGlyph(tag.Glyph, StandardGlyphItem.GlyphItemPublic), "tag")); return(new FuzzyCompletionSet( "PythonDjangoTags", Resources.DjangoTagsCompletionSetDisplayName, applicableSpan, completions, options, CompletionComparer.UnderscoresLast)); }