protected override IEnumerable <JsonCompletionEntry> GetEntries(JsonCompletionContext context) { MemberNode member = context.ContextNode.FindType <MemberNode>(); if (member == null || member.UnquotedNameText != "files") { yield break; } var parent = member.Parent as ObjectNode; if (!JsonHelpers.TryGetInstallationState(parent, out ILibraryInstallationState state)) { yield break; } if (string.IsNullOrEmpty(state.Name)) { yield break; } IDependencies dependencies = _dependenciesFactory.FromConfigFile(ConfigFilePath); IProvider provider = dependencies.GetProvider(state.ProviderId); ILibraryCatalog catalog = provider?.GetCatalog(); if (catalog == null) { yield break; } Task <ILibrary> task = catalog.GetLibraryAsync(state.Name, state.Version, CancellationToken.None); FrameworkElement presenter = GetPresenter(context); IEnumerable <string> usedFiles = GetUsedFiles(context); if (task.IsCompleted) { if (!(task.Result is ILibrary library)) { yield break; } foreach (string file in library.Files.Keys) { if (!usedFiles.Contains(file)) { ImageSource glyph = WpfUtil.GetIconForFile(presenter, file, out bool isThemeIcon); yield return(new SimpleCompletionEntry(file, glyph, context.Session)); } } } else { yield return(new SimpleCompletionEntry(Resources.Text.Loading, string.Empty, KnownMonikers.Loading, context.Session)); _ = task.ContinueWith(async(t) => { await VisualStudio.Shell.ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); if (!(t.Result is ILibrary library)) { return; } if (!context.Session.IsDismissed) { var results = new List <JsonCompletionEntry>(); foreach (string file in library.Files.Keys) { if (!usedFiles.Contains(file)) { ImageSource glyph = WpfUtil.GetIconForFile(presenter, file, out bool isThemeIcon); results.Add(new SimpleCompletionEntry(file, glyph, context.Session)); } } UpdateListEntriesSync(context, results); } }, TaskScheduler.Default); } }
private async void RetriggerAsync(bool force) { _lastTyped = DateTime.Now; int delay = force ? 50 : _delay; // Don't leave "stale" completion session up while the user is typing, or else we could // get completion from a stale session. ICompletionSession completionSession = _broker.GetSessions(_textView).FirstOrDefault(); if (completionSession != null && completionSession.Properties.TryGetProperty <bool>(RetriggerCompletion, out bool retrigger) && retrigger) { completionSession.Dismiss(); } await System.Threading.Tasks.Task.Delay(delay); // Prevents retriggering from happening while typing fast if (_lastTyped.AddMilliseconds(delay) > DateTime.Now) { return; } // Completion may have gotten invoked via by Web Editor OnPostTypeChar(). Don't invoke again, or else we get flikering completion list // TODO:Review the design here post-preview 4 and make sure this completion controller doesn't clash with Web Editors Json completion controller completionSession = _broker.GetSessions(_textView).FirstOrDefault(); if (completionSession != null && completionSession.Properties.TryGetProperty <bool>(RetriggerCompletion, out retrigger)) { return; } var doc = JsonEditorDocument.FromTextBuffer(_textView.TextDataModel.DocumentBuffer); if (doc == null) { return; } Node node = JsonHelpers.GetNodeBeforePosition(_textView.Caret.Position.BufferPosition, doc.DocumentNode); if (node == null) { return; } MemberNode memberNode = node.FindType <MemberNode>(); if (memberNode == null || (!memberNode.UnquotedNameText.Equals(ManifestConstants.Library, StringComparison.Ordinal) && !memberNode.UnquotedNameText.Equals(ManifestConstants.Destination, StringComparison.Ordinal) && memberNode.UnquotedValueText?.Length <= 1)) { return; } ObjectNode parent = node.FindType <ObjectNode>(); if (JsonHelpers.TryGetInstallationState(parent, out ILibraryInstallationState state)) { VsHelpers.DTE.ExecuteCommand("Edit.ListMembers"); } }
protected override IEnumerable <JSONCompletionEntry> GetEntries(JSONCompletionContext context) { JSONMember member = context.ContextItem.FindType <JSONMember>(); if (member == null || member.UnquotedNameText != "files") { yield break; } var parent = member.Parent as JSONObject; if (!JsonHelpers.TryGetInstallationState(parent, out ILibraryInstallationState state)) { yield break; } if (string.IsNullOrEmpty(state.LibraryId)) { yield break; } var dependencies = Dependencies.FromConfigFile(ConfigFilePath); IProvider provider = dependencies.GetProvider(state.ProviderId); ILibraryCatalog catalog = provider?.GetCatalog(); if (catalog == null) { yield break; } Task <ILibrary> task = catalog.GetLibraryAsync(state.LibraryId, CancellationToken.None); FrameworkElement presenter = GetPresenter(context); IEnumerable <string> usedFiles = GetUsedFiles(context); if (task.IsCompleted) { if (!(task.Result is ILibrary library)) { yield break; } foreach (string file in library.Files.Keys) { if (!usedFiles.Contains(file)) { ImageSource glyph = WpfUtil.GetIconForFile(presenter, file, out bool isThemeIcon); yield return(new SimpleCompletionEntry(file, glyph, context.Session)); } } } else { yield return(new SimpleCompletionEntry(Resources.Text.Loading, string.Empty, KnownMonikers.Loading, context.Session)); task.ContinueWith((a) => { if (!(task.Result is ILibrary library)) { return; } if (!context.Session.IsDismissed) { var results = new List <JSONCompletionEntry>(); foreach (string file in library.Files.Keys) { if (!usedFiles.Contains(file)) { ImageSource glyph = WpfUtil.GetIconForFile(presenter, file, out bool isThemeIcon); results.Add(new SimpleCompletionEntry(file, glyph, context.Session)); } } UpdateListEntriesSync(context, results); } }); } }
protected override IEnumerable <JsonCompletionEntry> GetEntries(JsonCompletionContext context) { var member = context.ContextNode as MemberNode; if (member == null || member.UnquotedNameText != ManifestConstants.Library) { yield break; } var parent = member.Parent as ObjectNode; if (!JsonHelpers.TryGetInstallationState(parent, out ILibraryInstallationState state)) { yield break; } var dependencies = _dependenciesFactory.FromConfigFile(ConfigFilePath); IProvider provider = dependencies.GetProvider(state.ProviderId); ILibraryCatalog catalog = provider?.GetCatalog(); if (catalog == null) { yield break; } // member.Value is null when there is no value yet, e.g. when typing a space at "library":| // where | represents caret position. In this case, set caretPosition to "1" to short circuit execution of this function // and return no entries (member.UnquotedValueText will be empty string in that case). int caretPosition = member.Value != null ? context.Session.TextView.Caret.Position.BufferPosition - member.Value.Start - 1 : 1; if (caretPosition > member.UnquotedValueText.Length) { yield break; } Task <CompletionSet> task = catalog.GetLibraryCompletionSetAsync(member.UnquotedValueText, caretPosition); int count = 0; if (!context.Session.Properties.ContainsProperty(CompletionController.RetriggerCompletion)) { context.Session.Properties.AddProperty(CompletionController.RetriggerCompletion, true); } if (task.IsCompleted) { CompletionSet completionSet = task.Result; if (completionSet.Completions != null) { List <JsonCompletionEntry> results = GetCompletionList(member, context, completionSet, count); foreach (JsonCompletionEntry completionEntry in results) { yield return(completionEntry); } } } else { yield return(new SimpleCompletionEntry(Resources.Text.Loading, string.Empty, KnownMonikers.Loading, context.Session)); _ = task.ContinueWith((t) => { if (!t.IsCanceled || !t.IsFaulted) { if (!context.Session.IsDismissed) { CompletionSet completionSet = t.Result; if (completionSet.Completions != null) { List <JsonCompletionEntry> results = GetCompletionList(member, context, completionSet, count); UpdateListEntriesSync(context, results); } } } }, TaskScheduler.Default); } }