Repository: microsoft/terminal
File: src/cascadia/TerminalApp/TerminalPage.cpp (C++)

Code before:
    Windows::Foundation::IAsyncOperation<IVectorView<MatchResult>> TerminalPage::_FindPackageAsync(hstring query)
    {
        PackageManager packageManager = WindowsPackageManagerFactory::CreatePackageManager();
        PackageCatalogReference catalogRef{
            packageManager.GetPredefinedPackageCatalog(PredefinedPackageCatalog::OpenWindowsCatalog)
        };
        ConnectResult connectResult = catalogRef.Connect();
        if (connectResult.Status() != ConnectResultStatus::Ok)
        {
            co_return nullptr;
        }
        PackageCatalog catalog = connectResult.PackageCatalog();

        auto pkgList = co_await _FindPackagesInCatalogAsync(catalog, PackageMatchField::Command, PackageFieldMatchOption::StartsWithCaseInsensitive, query);
        if (pkgList.Size() > 0)
        {
            co_return pkgList;
        }
        pkgList = co_await _FindPackagesInCatalogAsync(catalog, PackageMatchField::Name, PackageFieldMatchOption::ContainsCaseInsensitive, query);
        if (pkgList.Size() > 0)
        {
            co_return pkgList;
        }
        pkgList = co_await _FindPackagesInCatalogAsync(catalog, PackageMatchField::Moniker, PackageFieldMatchOption::ContainsCaseInsensitive, query);
        co_return pkgList;
    }

    Windows::Foundation::IAsyncAction TerminalPage::_SearchMissingCommandHandler(const IInspectable /*sender*/, const Microsoft::Terminal::Control::SearchMissingCommandEventArgs args)
    {
        assert(!Dispatcher().HasThreadAccess());

        if (!Feature_QuickFix::IsEnabled())
        {
            co_return;
        }

        auto pkgList = co_await _FindPackageAsync(args.MissingCommand());
        for (int retries = 0; !pkgList && retries < 3; ++retries)
        {
            pkgList = co_await _FindPackageAsync(args.MissingCommand());
        }

        // no packages were found, nothing to suggest
        if (pkgList.Size() == 0)
        {
            co_return;
        }

        std::vector<hstring> suggestions;
        suggestions.reserve(pkgList.Size());
        for (auto pkg : pkgList)

Review comment (suggestion):
You could consider rewriting this as a loop. Pseudo code:
```cpp
struct Search {
    PackageMatchField field;
    PackageFieldMatchOption matching;
};
static constexpr std::array searches{ ... };

for (const auto& search : searches) {
    const auto matches = co_await ...;
    if (matches.Size() > 0) {
        co_return matches;
    }
}
```

This has the advantage that we can reuse objects across iterations easily:
```cpp
struct Search {
    PackageMatchField field;
    PackageFieldMatchOption option;
};
static constexpr std::array searches{ ... };

const auto filter = WindowsPackageManagerFactory::CreatePackageMatchFilter();
filter.Value(query);

const auto options = WindowsPackageManagerFactory::CreateFindPackagesOptions();
options.Filters().Append(filter);
options.ResultLimit(20);

for (const auto& search : searches) {
    filter.Field(search.field);
    filter.Option(search.option);

    const auto result = co_await catalog.FindPackagesAsync(options);
    const auto matches = result.Matches();

    if (matches.Size() > 0) {
        co_return matches;
    }
}
```

Whether this works or not depends on whether winget is robust against object reuse of course. But I'd expect this to just work.

Code after:
                break;
            }

            if (++retries == 3)
            {
                co_return nullptr;
            }
        }

        PackageCatalog catalog = connectResult.PackageCatalog();
        // clang-format off
        static constexpr std::array<WinGetSearchParams, 3> searches{ {
            { .Field = PackageMatchField::Command, .MatchOption = PackageFieldMatchOption::StartsWithCaseInsensitive },
            { .Field = PackageMatchField::Name, .MatchOption = PackageFieldMatchOption::ContainsCaseInsensitive },
            { .Field = PackageMatchField::Moniker, .MatchOption = PackageFieldMatchOption::ContainsCaseInsensitive } } };
        // clang-format on

        PackageMatchFilter filter = WindowsPackageManagerFactory::CreatePackageMatchFilter();
        filter.Value(query);

        FindPackagesOptions options = WindowsPackageManagerFactory::CreateFindPackagesOptions();
        options.Filters().Append(filter);
        options.ResultLimit(20);

        IVectorView<MatchResult> pkgList;
        for (const auto& search : searches)
        {
            filter.Field(search.Field);
            filter.Option(search.MatchOption);

            const auto result = co_await catalog.FindPackagesAsync(options);
            pkgList = result.Matches();
            if (pkgList.Size() > 0)
            {
                break;
            }
        }
        co_return pkgList;
    }

    Windows::Foundation::IAsyncAction TerminalPage::_SearchMissingCommandHandler(const IInspectable /*sender*/, const Microsoft::Terminal::Control::SearchMissingCommandEventArgs args)
    {
        if (!Feature_QuickFix::IsEnabled())
        {
            co_return;
        }
        co_await winrt::resume_background();

        // no packages were found, nothing to suggest
        const auto pkgList = co_await _FindPackageAsync(args.MissingCommand());
        if (!pkgList || pkgList.Size() == 0)