Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use WinGet API to improve Quick Fix results #17614

Merged
merged 19 commits into from
Aug 23, 2024

Conversation

carlos-zamora
Copy link
Member

@carlos-zamora carlos-zamora commented Jul 25, 2024

Summary of the Pull Request

Improves Quick Fix's suggestions to use WinGet API and actually query winget for packages based on the missing command.

To interact with the WinGet API, we need the Microsoft.WindowsPackageManager.ComInterop NuGet package. Microsoft.WindowsPackageManager.ComInterop.Additional.targets is used to copy over the winmd into CascadiaPackage. The build variable TerminalWinGetInterop is used to import the package properly.

WindowsPackageManagerFactory is used as a centralized way to generate the winget objects. Long-term, we may need to do manual activation for elevated sessions, which this class can easily be extended to support. In the meantime, we'll just use the normal winrt::create_instance on all sessions.

In TerminalPage, we conduct the search asynchronously when a missing command was found. Search results are limited to 20 packages. We try to retrieve packages with the following filters set, then fallback into the next step:

  1. PackageMatchField::Command, PackageFieldMatchOption::StartsWithCaseInsensitive
  2. PackageMatchField::Name, PackageFieldMatchOption::ContainsCaseInsensitive
  3. PackageMatchField::Moniker, PackageFieldMatchOption::ContainsCaseInsensitive

This aligns with the Microsoft.WinGet.CommandNotFound PowerShell module (link to relevant code).

Closes #17378
Closes #17631
Support for elevated sessions tracked in #17677

References

Validation Steps Performed

  • unelevated sessions --> winget query performed and presented
  • elevated sessions --> nothing happens (got rid of winget install {} suggestion)

@microsoft-github-policy-service microsoft-github-policy-service bot added Issue-Task It's a feature request, but it doesn't really need a major design. Area-VT Virtual Terminal sequence support Product-Terminal The new Windows Terminal. labels Aug 6, 2024
@carlos-zamora carlos-zamora marked this pull request as ready for review August 6, 2024 22:28
src/cascadia/TerminalApp/TerminalPage.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalApp/TerminalPage.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalApp/TerminalPage.cpp Outdated Show resolved Hide resolved
@carlos-zamora
Copy link
Member Author

Now that we're adding --source, there's a greater chance that the string is too long. Unfortunately, we can't set the TextTrimming property on these MenuFlyoutItems, so I went ahead and did a workaround:

  • suggestions UI: we get a text preview in the commandline, so I think we're fine here
  • quick fix menu: I added a tooltip so the user can get the full string

It's annoying because we're just plain clipping the text and we can't configure it. Looks like the only way is to retemplate the MenuFlyout (or maybe retemplate the MenuFlyoutItem?).

Here's what it looks like:
Suggestions UI with preview text

Quick Fix menu with tooltip

I'll switch to the shorthand of --source and --id to help alleviate some issues, but regardless, this is definitely a case users may hit 🫤

@DHowett
Copy link
Member

DHowett commented Aug 8, 2024

This hangs the UI pretty significantly while it's querying - gotta move that work off the main thread!

@lhecker
Copy link
Member

lhecker commented Aug 8, 2024

This hangs the UI pretty significantly while it's querying - gotta move that work off the main thread!

It's already off the main thread, isn't it?

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

If I'm correct about that, I think it's the console lock that's being held by the terminal during VT parsing. The UI thread tries to acquire the console lock regularly for info. In that case we just need to go to a different background thread instead, just not the VT parser one. 😅 (We could also add debouncing, but... eh. That may be too much for this limited purpose.)

@carlos-zamora
Copy link
Member Author

Ah! We were on the ConptyConnection Output Thread.

@microsoft-github-policy-service microsoft-github-policy-service bot added Issue-Bug It either shouldn't be doing this or needs an investigation. Area-TerminalControl Issues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.) labels Aug 13, 2024
@carlos-zamora
Copy link
Member Author

The newest change now includes the bufferRow in the event args so that we can fix #17631. Unfortunately, we can't reliably get the position of the prompt. Instead, we'll be placing the button right by the error message (which we capture on the way up).

Copy link
Member

@zadjii-msft zadjii-msft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay a minor thought: In 1.22 I added Description's to Commands. If the package catalog gives us a description, we could totally stick that in the teaching tip 👀

Similarly, IMO, we don't need --source winget in the Name of the Command. It's clearer to just say winget install Foo and have the rest of the args in the preview text (but that's just my opinion)

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝: weird to me that this isn't just in their nuget package

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are working on improving this facet.

@@ -20,6 +20,7 @@
<TerminalCppWinrt>true</TerminalCppWinrt>
<TerminalThemeHelpers>true</TerminalThemeHelpers>
<TerminalMUX>true</TerminalMUX>
<TerminalWinGetInterop>true</TerminalWinGetInterop>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need this for WindowsTerminal.exe in addition to TerminalApp? Is this cause the dependency doesn't get rolled up?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. Just tested it without it. The QF menu won't appear.

@@ -0,0 +1,61 @@
// Copyright (c) Microsoft Corporation.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝: it's so gross that we have to write this ourselves

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, which is why the nuget package is soon going to include a DLL that handles this part (exposes the activation factory so that one can just use WinRT language projections as normal).

src/cascadia/TerminalApp/TerminalPage.cpp Outdated Show resolved Hide resolved
@carlos-zamora
Copy link
Member Author

okay a minor thought: In 1.22 I added Description's to Commands. If the package catalog gives us a description, we could totally stick that in the teaching tip 👀

Similarly, IMO, we don't need --source winget in the Name of the Command. It's clearer to just say winget install Foo and have the rest of the args in the preview text (but that's just my opinion)

Opened #17755. I like the idea and it should be pretty straightforward to do, but it's a bit bigger of a change than I'd like for this PR.

@zadjii-msft zadjii-msft added this to the Terminal v1.22 milestone Aug 22, 2024
Copy link
Member

@zadjii-msft zadjii-msft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whoops didn't ✅

Copy link
Member

@lhecker lhecker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I'd approve, but I'll wait a bit for you to read my comments. :)

src/cascadia/TerminalApp/SuggestionsControl.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalApp/TerminalPage.cpp Show resolved Hide resolved
src/cascadia/TerminalApp/TerminalPage.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalApp/TerminalPage.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalApp/TerminalPage.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalCore/Terminal.hpp Outdated Show resolved Hide resolved
@carlos-zamora carlos-zamora self-assigned this Aug 22, 2024
Copy link
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's go!

@DHowett DHowett enabled auto-merge (squash) August 22, 2024 22:58
@DHowett DHowett merged commit dbbc581 into main Aug 23, 2024
20 checks passed
@DHowett DHowett deleted the dev/cazamor/quick-fix/use-winget-api branch August 23, 2024 17:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-TerminalControl Issues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.) Area-VT Virtual Terminal sequence support Issue-Bug It either shouldn't be doing this or needs an investigation. Issue-Task It's a feature request, but it doesn't really need a major design. Product-Terminal The new Windows Terminal.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug Bash] Quick Fix button being rendered to wrong spot Improve OSC 9001; CmdNotFound suggestions
6 participants