Skip to content

Add loading indicator support to SimpleSuggestWidget #251856

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

Merged
merged 6 commits into from
Jun 19, 2025
Merged

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Jun 18, 2025

The editor's suggest widget shows a spinning loading animation when it takes a while to get suggestions, but the simple suggest widget used in contexts like the terminal did not have this functionality. This was particularly noticeable on Windows where suggestion loading can be slow.

Changes Made

SimpleSuggestWidget

  • Added showTriggered(auto, delay, cursorPosition) method that matches the main SuggestWidget API
  • Added _loadingTimeout and _isAuto properties for proper loading state management
  • Updated showSuggestions to dispose loading timeout when suggestions arrive
  • Updated hide method to properly clean up loading timeout
  • Enhanced loading state with accessibility status announcements

TerminalSuggestAddon

  • Updated _handleCompletionProviders to call showTriggered before async completion requests
  • Uses appropriate delays: 50ms for explicit invocation, 250ms for auto-completions
  • Calculates proper cursor position for the loading indicator

Behavior

Before: Simple suggest widget showed no loading indicator, leaving users uncertain if suggestions were being processed.

After: Simple suggest widget displays "Loading..." message during async completion requests, providing clear feedback.

This improvement is especially valuable on Windows where suggestion loading can take noticeably longer.

Fixes #251855.

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • electronjs.org
    • Triggering command: node-gyp (dns block)

If you need me to access, download, or install something from one of these locations, you can either:


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits June 18, 2025 21:24
…dget

Co-authored-by: meganrogge <29464607+meganrogge@users.noreply.github.com>
Co-authored-by: meganrogge <29464607+meganrogge@users.noreply.github.com>
@Copilot Copilot AI changed the title [WIP] Show a loading indicator for simple suggest widget Add loading indicator support to SimpleSuggestWidget Jun 18, 2025
@Copilot Copilot AI requested a review from meganrogge June 18, 2025 21:28
Copilot finished work on behalf of meganrogge June 18, 2025 21:28
@meganrogge
Copy link
Contributor

Works 👏🏼

loading.mov

@meganrogge meganrogge added this to the June 2025 milestone Jun 18, 2025
@meganrogge meganrogge requested a review from Tyriar June 18, 2025 22:25
@meganrogge meganrogge marked this pull request as ready for review June 18, 2025 22:25
@meganrogge meganrogge enabled auto-merge (squash) June 18, 2025 22:26
@@ -403,11 +405,22 @@ export class SimpleSuggestWidget<TModel extends SimpleCompletionModel<TItem>, TI
this._persistedSize.reset();
}

showTriggered(auto: boolean, delay: number, cursorPosition: { top: number; left: number; height: number }) {
Copy link
Member

Choose a reason for hiding this comment

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

Should we stay consistent and track explicitly invoked here too? Inverting to auto is a little ambiguous

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point! I've updated the method to track explicitlyInvoked instead of auto for clarity. The parameter is now consistently named and the logic is more straightforward.

const dimensions = this._getTerminalDimensions();
if (dimensions.width && dimensions.height) {
const xtermBox = this._screen!.getBoundingClientRect();
const cursorPosition = {
Copy link
Member

Choose a reason for hiding this comment

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

We calculate cursor position somewhere else, can we share some code?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great suggestion! I've extracted the cursor position calculation into a shared _getCursorPosition helper method that's now used in all three places where this logic was duplicated.

top: xtermBox.top + terminal.buffer.active.cursorY * dimensions.height,
height: dimensions.height
};
suggestWidget.showTriggered(!explicitlyInvoked, explicitlyInvoked ? 50 : 250, cursorPosition);
Copy link
Member

Choose a reason for hiding this comment

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

This passes in 250 for not explicitly but I don't think we want to show it at all on that case as it would get annoying.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Absolutely right! I've updated the code to only show the loading indicator for explicit invocations. Auto-completions no longer trigger the loading state to avoid being annoying to users.

…ming, and only show loading for explicit invocations

Co-authored-by: Tyriar <2193314+Tyriar@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jun 19, 2025

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • electronjs.org
    • Triggering command: node-gyp (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@Copilot Copilot AI requested a review from Tyriar June 19, 2025 01:38
Copilot finished work on behalf of Tyriar June 19, 2025 01:38
@meganrogge
Copy link
Contributor

@copilot the timeout should be after 250 just like it is for the editor's suggest widget, not 50

Co-authored-by: meganrogge <29464607+meganrogge@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jun 19, 2025

@copilot the timeout should be after 250 just like it is for the editor's suggest widget, not 50

Updated the timeout to 250ms to match the editor's suggest widget behavior. Commit: 65ca3f3

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • electronjs.org
    • Triggering command: node-gyp (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@Copilot Copilot AI requested a review from meganrogge June 19, 2025 02:23
Copilot finished work on behalf of meganrogge June 19, 2025 02:23
Copy link
Member

@Tyriar Tyriar left a comment

Choose a reason for hiding this comment

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

@meganrogge when explicitly invoked, I think we should up the timeout we give providers to something like 30 seconds, otherwise this ends up happening still the exthost and/or suggest takes too long to warm up:

image

const suggestWidget = this._ensureSuggestWidget(terminal);
const cursorPosition = this._getCursorPosition(terminal);
if (cursorPosition) {
suggestWidget.showTriggered(true, 250, cursorPosition);
Copy link
Member

Choose a reason for hiding this comment

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

@copilot I think we can just put the delay value inside simpleSuggestWidget.ts for now. That will simplify this call.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've moved the delay value (250ms) into simpleSuggestWidget.ts and removed the delay parameter from the API call. The showTriggered method now uses a hardcoded 250ms delay internally, simplifying the call from terminalSuggestAddon.ts. Commit: 5833eea

… timeout for explicit invocations

Co-authored-by: Tyriar <2193314+Tyriar@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jun 19, 2025

@meganrogge when explicitly invoked, I think we should up the timeout we give providers to something like 30 seconds, otherwise this ends up happening still the exthost and/or suggest takes too long t...

I've increased the completion provider timeout from 5 seconds to 30 seconds when explicitly invoked. This should prevent timeout issues when the extension host takes longer to warm up. The timeout remains at 5 seconds for auto-completions to avoid impacting performance. Commit: 5833eea

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • electronjs.org
    • Triggering command: node-gyp (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@Copilot Copilot AI requested a review from Tyriar June 19, 2025 12:24
Copilot finished work on behalf of Tyriar June 19, 2025 12:24
@meganrogge meganrogge merged commit 8ed218a into main Jun 19, 2025
8 checks passed
@meganrogge meganrogge deleted the copilot/fix-251855 branch June 19, 2025 22:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Show a loading indicator for simple suggest widget
4 participants