private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            TextChange textChange = e.Changes.Last();

            // We will invoke completion on text insertion and not deletion.
            // Also, we don't want to invoke completion on dialog load as we pre populate the target
            // location textbox with name of the folder when dialog is initially loaded.
            if (textChange.AddedLength > 0 && SearchTextBox.CaretIndex > 0)
            {
                ThreadHelper.JoinableTaskFactory.RunAsync(async() =>
                {
                    // grab these WPF dependant things while we're still on the UI thread
                    int caretIndex = SearchTextBox.CaretIndex;
                    SearchTextBoxViewModel viewModel = ViewModel;

                    string textBeforeGetCompletion = SearchTextBox.Text;

                    // Switch to a background thread to not block the UI thread, as this operation can take
                    // a while for slow network connections
                    await TaskScheduler.Default;
                    CompletionSet completionSet = await viewModel.GetCompletionSetAsync(caretIndex);

                    await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

                    // If the value has changed then this request is out of date.
                    // If focus is elsewhere the work below won't be used anyway
                    if (textBeforeGetCompletion != SearchTextBox.Text || !SearchTextBox.IsFocused)
                    {
                        return;
                    }

                    if (completionSet.Completions == null || !completionSet.Completions.Any())
                    {
                        Flyout.IsOpen = false;
                        return;
                    }

                    // repopulate the completion list
                    CompletionEntries.Clear();
                    foreach (CompletionItem entry in completionSet.Completions)
                    {
                        CompletionEntries.Add(new CompletionEntry(entry, completionSet.Start, completionSet.Length));
                    }

                    PositionCompletionPopup(completionSet.Length);

                    if (CompletionEntries != null && CompletionEntries.Count > 0 && Options.SelectedIndex == -1)
                    {
                        CompletionItem selectionCandidate = await ViewModel.GetRecommendedSelectedCompletionAsync(
                            completionSet: completionSet,
                            lastSelected: SelectedItem?.CompletionItem);
                        SelectedItem = CompletionEntries.FirstOrDefault(x => x.CompletionItem.InsertionText == selectionCandidate.InsertionText) ?? CompletionEntries[0];
                        Options.ScrollIntoView(SelectedItem);
                    }

                    Flyout.IsOpen = true;
                });
            }
        }
Example #2
0
        private void LibrarySearchBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            OnPropertyChanged(nameof(IsTextEntryEmpty));

            TextChange textChange = e.Changes.Last();

            // We will invoke completion on text insertion and not deletion.
            if (textChange.AddedLength > 0 && !string.IsNullOrEmpty(Text))
            {
                VisualStudio.Shell.ThreadHelper.JoinableTaskFactory.Run(async() =>
                {
                    CompletionSet completionSet = await SearchService?.Invoke(Text, LibrarySearchBox.CaretIndex);

                    if (completionSet.Equals(null) || !completionSet.Completions.Any())
                    {
                        Flyout.IsOpen = false;
                        return;
                    }

                    int atIndex = Text.IndexOf('@');

                    if (atIndex >= 0)
                    {
                        completionSet.Completions = FilterOutUnmatchedItems(completionSet.Completions, Text.Substring(atIndex + 1));
                    }

                    CompletionEntries.Clear();

                    foreach (CompletionItem entry in completionSet.Completions)
                    {
                        CompletionEntries.Add(new CompletionEntry(entry, completionSet.Start, completionSet.Length));
                    }

                    PositionCompletions(completionSet.Length);

                    if (CompletionEntries != null && CompletionEntries.Count > 0 && Options.SelectedIndex == -1)
                    {
                        if (atIndex >= 0)
                        {
                            SelectedItem = CompletionEntries.FirstOrDefault(x => x.CompletionItem.DisplayText.StartsWith(Text.Substring(atIndex + 1), StringComparison.OrdinalIgnoreCase)) ?? CompletionEntries[0];
                        }
                        else
                        {
                            string lastSelected = SelectedItem?.CompletionItem.InsertionText;
                            SelectedItem        = CompletionEntries.FirstOrDefault(x => x.CompletionItem.InsertionText == lastSelected) ?? CompletionEntries[0];
                        }

                        Options.ScrollIntoView(SelectedItem);

                        Flyout.IsOpen = true;
                    }
                });
            }
        }
Example #3
0
        private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            TextChange textChange = e.Changes.Last();

            // We will invoke completion on text insertion and not deletion.
            // Also, we don't want to invoke completion on dialog load as we pre populate the target
            // location textbox with name of the folder when dialog is initially loaded.
            if (textChange.AddedLength > 0 && SearchTextBox.CaretIndex > 0)
            {
                VisualStudio.Shell.ThreadHelper.JoinableTaskFactory.Run(async() =>
                {
                    CompletionSet completionSet = await ViewModel.GetCompletionSetAsync(SearchTextBox.CaretIndex);

                    if (completionSet.Completions == null || !completionSet.Completions.Any())
                    {
                        Flyout.IsOpen = false;
                        return;
                    }

                    // repopulate the completion list
                    CompletionEntries.Clear();
                    foreach (CompletionItem entry in completionSet.Completions)
                    {
                        CompletionEntries.Add(new CompletionEntry(entry, completionSet.Start, completionSet.Length));
                    }

                    PositionCompletionPopup(completionSet.Length);

                    if (CompletionEntries != null && CompletionEntries.Count > 0 && Options.SelectedIndex == -1)
                    {
                        CompletionItem selectionCandidate = await ViewModel.GetRecommendedSelectedCompletionAsync(
                            completionSet: completionSet,
                            lastSelected: SelectedItem?.CompletionItem);
                        SelectedItem = CompletionEntries.FirstOrDefault(x => x.CompletionItem.InsertionText == selectionCandidate.InsertionText) ?? CompletionEntries[0];
                        Options.ScrollIntoView(SelectedItem);
                    }

                    Flyout.IsOpen = true;
                });
            }
        }
Example #4
0
        private void TargetLocationSearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            TextChange textChange = e.Changes.Last();

            // We will invoke completion on text insertion and not deletion.
            // Also, we don't want to invoke completion on dialog load as we pre populate the target
            // location textbox with name of the folder when dialog is initially loaded.
            if (textChange.AddedLength > 0 && TargetLocationSearchTextBox.CaretIndex > 0)
            {
                VisualStudio.Shell.ThreadHelper.JoinableTaskFactory.Run(async() =>
                {
                    CompletionSet completionSet = await SearchService?.Invoke(Text, TargetLocationSearchTextBox.CaretIndex);

                    if (completionSet.Equals(null) || !completionSet.Completions.Any())
                    {
                        Flyout.IsOpen = false;
                        return;
                    }

                    CompletionEntries.Clear();

                    foreach (CompletionItem entry in completionSet.Completions)
                    {
                        CompletionEntries.Add(new CompletionEntry(entry, completionSet.Start, completionSet.Length));
                    }

                    PositionCompletions(completionSet.Length);

                    if (CompletionEntries != null && CompletionEntries.Count > 0 && Options.SelectedIndex == -1)
                    {
                        string lastSelected = SelectedItem?.CompletionItem.InsertionText;
                        SelectedItem        = CompletionEntries.FirstOrDefault(x => x.CompletionItem.InsertionText == lastSelected) ?? CompletionEntries[0];
                        Options.ScrollIntoView(SelectedItem);
                    }

                    Flyout.IsOpen = true;
                });
            }

            InstallationFolder.DestinationFolder = TargetLocationSearchTextBox.Text;
        }