Skip to content

Conversation

@Tyriar
Copy link
Member

@Tyriar Tyriar commented Dec 26, 2025

Part of #284277
Part of #282268

New status bar that is more clear that these things can be clicked to configure:

image

Left action can be clicked to rotate selection modes (ie. what keybinding is used when it shows):

image

The eye icon can be used to easily enable quick suggestions and suggest on trigger chars:

image

The initial hint now and calls out how to show suggestions:

image

The initial hint will show more often now as it was kind of weird before. Now it will show for all new terminals that have shell integration on the first prompt. Clicking don't show will change a setting and permanently disable.

Terminal suggest is still enabled by default, but quick suggestions and suggest on trigger character are off. What this means is that suggest will never show up unless ctrl+space is pressed explicitly. I expect this to pretty dramatically impact feature usage but it will keep it out of the way for users that don't want it and it will keep terminal input as low latency as possible by default.

@Tyriar Tyriar added this to the December / January 2026 milestone Dec 26, 2025
@Tyriar Tyriar self-assigned this Dec 26, 2025
Copilot AI review requested due to automatic review settings December 26, 2025 00:09
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the terminal suggest status bar to add new actions for controlling IntelliSense behavior and adds icon support to the suggest widget status bar. The changes include refactoring the configuration schema to support boolean values for quickSuggestions, changing default values for suggest settings, and adding new menu actions with icons.

Key Changes

  • Added icon support to SuggestWidgetStatus through a new ISuggestWidgetStatusOptions interface
  • Changed quickSuggestions configuration to accept boolean or object values, with a new normalization function
  • Changed configuration defaults: quickSuggestions from object to false, suggestOnTriggerCharacters from true to false
  • Reorganized terminal suggest status bar menu with new actions for toggling selection modes and IntelliSense visibility

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
suggestWidgetStatus.ts Added ISuggestWidgetStatusOptions interface and updated constructor to support icon display via allowIcons option
simpleSuggestWidget.ts Updated two instances of SuggestWidgetStatus instantiation to pass { allowIcons: true } option
suggestWidget.ts Updated SuggestWidgetStatus instantiation to pass { allowIcons: true } option
terminalSuggestConfiguration.ts Changed quickSuggestions type to accept boolean or object, added normalizeQuickSuggestionsConfig function, changed defaults for quickSuggestions and suggestOnTriggerCharacters to false
terminal.suggest.ts Added six new command IDs for selection mode changes and show/hide IntelliSense actions
terminalSuggestAddon.ts Updated to use normalizeQuickSuggestionsConfig when reading quickSuggestions configuration
terminal.suggest.contribution.ts Refactored status bar actions: added three selection mode toggle actions, two show/hide IntelliSense actions with icons, reorganized existing actions into right group with icons, removed menu entry from AcceptSelectedSuggestion action

@diffray-bot

This comment was marked as spam.

(commandLineHasSpace && quickSuggestions.arguments !== 'off')
) {
if (promptInputState.prefix.match(/[^\s]$/)) {
sent = this._requestTriggerCharQuickSuggestCompletions();

Choose a reason for hiding this comment

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

🟡 MEDIUM - Duplicate nested loop for trigger character checking
Agent: performance

Category: performance

Description:
The same nested loop pattern appears in _sync method (lines 557-570), checking trigger characters on every keystroke.

Suggestion:
Refactor to use a cached trigger character Set. Move trigger character compilation to a dedicated method that only runs when providers change.

Confidence: 70%
Rule: perf_quadratic_loops
Review ID: 34d87b36-1c2b-444c-96bb-3508e6175650
Rate it 👍 or 👎 to improve future reviews | Powered by diffray

Comment on lines +77 to +84
export function normalizeQuickSuggestionsConfig(config: ITerminalSuggestConfiguration['quickSuggestions']): ITerminalQuickSuggestionsOptions {
if (typeof config === 'boolean') {
return config
? { commands: 'on', arguments: 'on', unknown: 'off' }
: { commands: 'off', arguments: 'off', unknown: 'off' };
}
return config;
}

Choose a reason for hiding this comment

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

🟡 MEDIUM - Exported function missing JSDoc documentation
Agent: react

Category: docs

Description:
The exported function 'normalizeQuickSuggestionsConfig' lacks JSDoc documentation. Has inline comments (lines 71-76) but no formal JSDoc.

Suggestion:
Convert existing inline comments to proper JSDoc format with @param and @returns tags.

Confidence: 60%
Rule: ts_always_use_jsdoc_for_documentation
Review ID: 34d87b36-1c2b-444c-96bb-3508e6175650
Rate it 👍 or 👎 to improve future reviews | Powered by diffray

return this._lastUserData === '\t';
}

private _sync(promptInputState: IPromptInputModelState): void {

Choose a reason for hiding this comment

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

🟠 HIGH - Very long method with excessive nesting (4-5 levels)
Agent: refactoring

Category: quality

Description:
_sync is 141 lines long with deeply nested if-statements. Contains a brace scope block (lines 520-595) that increases indentation.

Suggestion:
Extract nested logic into separate methods: (1) _handleCursorMovedRight() for cursor movement logic, (2) _handleCursorMovedLeft() for left cursor logic.

Confidence: 75%
Rule: quality_guard_clauses
Review ID: 34d87b36-1c2b-444c-96bb-3508e6175650
Rate it 👍 or 👎 to improve future reviews | Powered by diffray

@diffray-bot
Copy link

Review Summary

Free public review - Want AI code reviews on your PRs? Check out diffray.ai

Validated 87 issues: 19 kept, 68 filtered

Issues Found: 19

💬 See 4 individual line comment(s) for details.

📊 10 unique issue type(s) across 19 location(s)

📋 Full issue list (click to expand)

🟠 HIGH - Floating promise: async function not awaited (2 occurrences)

Agent: nodejs

Category: bug

📍 View all locations
File Description Suggestion Confidence
src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts:166 The async function _loadLspCompletionAddon() is called without await in the synchronous _loadAddons(... Either make _loadAddons() async and await the call, or use void operator with explicit comment if fi... 90%
src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts:208 The async function _loadLspCompletionAddon() is called without await in the synchronous _refreshAddo... Either make _refreshAddons() async and await the call, or use void operator with explicit comment if... 90%

Rule: node_floating_promise


🟠 HIGH - Unsafe type assertion of potentially null value

Agent: bugs

Category: bug

File: src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts:171-172

Description: The code casts e.relatedTarget as HTMLElement without checking if it's null. FocusEvent.relatedTarget can be null when focus moves to nothing.

Suggestion: Use 'if (e.relatedTarget instanceof HTMLElement && e.relatedTarget.classList.contains(SuggestDetailsClassName))' for proper type checking.

Confidence: 60%

Rule: bug_null_pointer


🟠 HIGH - Very long method with excessive nesting and complexity (2 occurrences)

Agent: refactoring

Category: quality

📍 View all locations
File Description Suggestion Confidence
src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts:263-387 _handleCompletionProviders is 125 lines long with multiple levels of nested conditionals. High cyclo... Extract methods: (1) Create _validateTerminalState() for initial validations, (2) Create _prepareCom... 75%
src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts:517 _sync is 141 lines long with deeply nested if-statements. Contains a brace scope block (lines 520-59... Extract nested logic into separate methods: (1) _handleCursorMovedRight() for cursor movement logic,... 75%

Rule: quality_guard_clauses


🟠 HIGH - Unused variable 'barrier' declared but never initialized

Agent: refactoring

Category: bug

File: src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts:190-195

Description: The variable 'barrier' is declared as 'AutoOpenBarrier | undefined' but never initialized. barrier?.open() will never call open() since barrier remains undefined. This appears to be incomplete code.

Suggestion: Either initialize the barrier variable with 'barrier = new AutoOpenBarrier(timeoutMs)' before it's used, or remove this block entirely if it's not needed.

Confidence: 90%

Rule: quality_unused_variable


🟠 HIGH - Non-null assertion on untrusted get() result (2 occurrences)

Agent: typescript

Category: bug

📍 View all locations
File Description Suggestion Confidence
src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts:183 Line 183 uses non-null assertion (!) on TerminalClipboardContribution.get(this._ctx.instance) withou... Add a null check guard before using the clipboardContrib. Store the result in a variable and check i... 85%
src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts:717 Line 717 uses non-null assertion (!) on this._screen without ensuring it's not null. The function _g... Add a type guard at the start of _getCursorPosition: 'if (!this._screen) { return undefined; }' to e... 80%

Rule: ts_non_null_assertion


🟡 MEDIUM - Module-level mutable state for configuration (3 occurrences)

Agent: nodejs

Category: quality

📍 View all locations
File Description Suggestion Confidence
src/vs/workbench/contrib/terminalContrib/suggest/common/terminalSuggestConfiguration.ts:216-270 The variable 'terminalSuggestProvidersConfiguration' is declared at module scope (line 216) and reas... Document the invariants clearly since this appears intentional for VS Code's configuration system. C... 65%
src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts:86 The class uses a static property 'SuggestAddon.lastAcceptedCompletionTimestamp' which is mutable sta... If cross-instance tracking is truly needed, document this requirement clearly. Consider whether this... 65%
src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts:94 TerminalSuggestProvidersConfigurationManager.initialize() is called in constructor. The static _inst... The existing guard (if (!this._instance)) prevents multiple initializations. Add a comment documenti... 60%

Rule: node_module_level_state


🟡 MEDIUM - Nested loops in trigger character check (2 occurrences)

Agent: performance

Category: performance

📍 View all locations
File Description Suggestion Confidence
src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts:477-489 The _checkProviderTriggerCharacters method uses nested loops to check if a character matches any pro... Build a Set of all trigger characters upfront (in constructor or when providers change), then do O(1... 70%
src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts:539 The same nested loop pattern appears in _sync method (lines 557-570), checking trigger characters on... Refactor to use a cached trigger character Set. Move trigger character compilation to a dedicated me... 70%

Rule: perf_quadratic_loops


🟡 MEDIUM - Exported function missing JSDoc documentation

Agent: react

Category: docs

File: src/vs/workbench/contrib/terminalContrib/suggest/common/terminalSuggestConfiguration.ts:77-84

Description: The exported function 'normalizeQuickSuggestionsConfig' lacks JSDoc documentation. Has inline comments (lines 71-76) but no formal JSDoc.

Suggestion: Convert existing inline comments to proper JSDoc format with @param and @returns tags.

Confidence: 60%

Rule: ts_always_use_jsdoc_for_documentation


🟡 MEDIUM - Type assertion from function return without type guarantee (4 occurrences)

Agent: typescript

Category: bug

📍 View all locations
File Description Suggestion Confidence
src/vs/editor/contrib/suggest/browser/suggestWidgetStatus.ts:37 Line 37 uses '' type assertion on an arrow function. While this is a common... Consider using type annotation instead: `const actionViewItemProvider: IActionViewItemProvider = (ac... 60%
src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts:705 Line 705 casts 'this._terminal as XtermWithCore' to access private _core property. This accesses und... Use proper public APIs from Terminal type instead of accessing private _core properties, or document... 70%
src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts:819 Line 819 uses 'as unknown as SimpleSuggestWidget<...>' pattern which is a double assertion that bypa... Fix the underlying type mismatch instead of using double assertions. Ensure createInstance is proper... 90%
src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts:880 Line 880 directly asserts 'event.target as HTMLElement' without checking if the target is actually a... Use a type guard function like 'dom.isHTMLElement()' or check 'instanceof HTMLElement' before access... 65%

Rule: ts_type_assertion_abuse


🟡 MEDIUM - Missing JSDoc for exported function

Agent: react

Category: docs

Why this matters: Improves IntelliSense, cross-language usage, and code navigation.

File: src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts:1099-1104

Description: Exported function 'normalizePathSeparator' lacks JSDoc documentation

Suggestion: Add JSDoc comment with @param and @returns tags describing path normalization behavior

Confidence: 60%

Rule: ts_jsdoc_required_for_exported_apis


ℹ️ 15 issue(s) outside PR diff (click to expand)

These issues were found in lines not modified in this PR.

🟠 HIGH - Floating promise: async function not awaited (2 occurrences)

Agent: nodejs

Category: bug

📍 View all locations
File Description Suggestion Confidence
src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts:166 The async function _loadLspCompletionAddon() is called without await in the synchronous _loadAddons(... Either make _loadAddons() async and await the call, or use void operator with explicit comment if fi... 90%
src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts:208 The async function _loadLspCompletionAddon() is called without await in the synchronous _refreshAddo... Either make _refreshAddons() async and await the call, or use void operator with explicit comment if... 90%

Rule: node_floating_promise


🟠 HIGH - Unsafe type assertion of potentially null value

Agent: bugs

Category: bug

File: src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts:171-172

Description: The code casts e.relatedTarget as HTMLElement without checking if it's null. FocusEvent.relatedTarget can be null when focus moves to nothing.

Suggestion: Use 'if (e.relatedTarget instanceof HTMLElement && e.relatedTarget.classList.contains(SuggestDetailsClassName))' for proper type checking.

Confidence: 60%

Rule: bug_null_pointer


🟠 HIGH - Very long method with excessive nesting and complexity

Agent: refactoring

Category: quality

File: src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts:263-387

Description: _handleCompletionProviders is 125 lines long with multiple levels of nested conditionals. High cyclomatic complexity due to if-statements handling different scenarios.

Suggestion: Extract methods: (1) Create _validateTerminalState() for initial validations, (2) Create _prepareCompletionRequest() for request setup, (3) Create _processCompletions() for completion processing

Confidence: 75%

Rule: quality_guard_clauses


🟠 HIGH - Unused variable 'barrier' declared but never initialized

Agent: refactoring

Category: bug

File: src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts:190-195

Description: The variable 'barrier' is declared as 'AutoOpenBarrier | undefined' but never initialized. barrier?.open() will never call open() since barrier remains undefined. This appears to be incomplete code.

Suggestion: Either initialize the barrier variable with 'barrier = new AutoOpenBarrier(timeoutMs)' before it's used, or remove this block entirely if it's not needed.

Confidence: 90%

Rule: quality_unused_variable


🟠 HIGH - Non-null assertion on untrusted get() result (2 occurrences)

Agent: typescript

Category: bug

📍 View all locations
File Description Suggestion Confidence
src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts:183 Line 183 uses non-null assertion (!) on TerminalClipboardContribution.get(this._ctx.instance) withou... Add a null check guard before using the clipboardContrib. Store the result in a variable and check i... 85%
src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts:717 Line 717 uses non-null assertion (!) on this._screen without ensuring it's not null. The function _g... Add a type guard at the start of _getCursorPosition: 'if (!this._screen) { return undefined; }' to e... 80%

Rule: ts_non_null_assertion


🟡 MEDIUM - Module-level mutable state for configuration (3 occurrences)

Agent: nodejs

Category: quality

📍 View all locations
File Description Suggestion Confidence
src/vs/workbench/contrib/terminalContrib/suggest/common/terminalSuggestConfiguration.ts:216-270 The variable 'terminalSuggestProvidersConfiguration' is declared at module scope (line 216) and reas... Document the invariants clearly since this appears intentional for VS Code's configuration system. C... 65%
src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts:86 The class uses a static property 'SuggestAddon.lastAcceptedCompletionTimestamp' which is mutable sta... If cross-instance tracking is truly needed, document this requirement clearly. Consider whether this... 65%
src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts:94 TerminalSuggestProvidersConfigurationManager.initialize() is called in constructor. The static _inst... The existing guard (if (!this._instance)) prevents multiple initializations. Add a comment documenti... 60%

Rule: node_module_level_state


🟡 MEDIUM - Nested loops in trigger character check

Agent: performance

Category: performance

File: src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts:477-489

Description: The _checkProviderTriggerCharacters method uses nested loops to check if a character matches any provider trigger characters. O(n*m) complexity could cause lag with many providers.

Suggestion: Build a Set of all trigger characters upfront (in constructor or when providers change), then do O(1) lookups.

Confidence: 70%

Rule: perf_quadratic_loops


🟡 MEDIUM - Unsafe type assertion to access private property (3 occurrences)

Agent: typescript

Category: bug

📍 View all locations
File Description Suggestion Confidence
src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts:705 Line 705 casts 'this._terminal as XtermWithCore' to access private _core property. This accesses und... Use proper public APIs from Terminal type instead of accessing private _core properties, or document... 70%
src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts:819 Line 819 uses 'as unknown as SimpleSuggestWidget<...>' pattern which is a double assertion that bypa... Fix the underlying type mismatch instead of using double assertions. Ensure createInstance is proper... 90%
src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts:880 Line 880 directly asserts 'event.target as HTMLElement' without checking if the target is actually a... Use a type guard function like 'dom.isHTMLElement()' or check 'instanceof HTMLElement' before access... 65%

Rule: ts_type_assertion_abuse


🟡 MEDIUM - Missing JSDoc for exported function

Agent: react

Category: docs

Why this matters: Improves IntelliSense, cross-language usage, and code navigation.

File: src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts:1099-1104

Description: Exported function 'normalizePathSeparator' lacks JSDoc documentation

Suggestion: Add JSDoc comment with @param and @returns tags describing path normalization behavior

Confidence: 60%

Rule: ts_jsdoc_required_for_exported_apis



Review ID: 34d87b36-1c2b-444c-96bb-3508e6175650
Rate it 👍 or 👎 to improve future reviews | Powered by diffray

@Tyriar Tyriar changed the title Update terminal suggest status bar Update terminal suggest status bar UX, change suggest defaults, show suggest in initial hint Dec 29, 2025
@Tyriar Tyriar marked this pull request as ready for review December 29, 2025 20:06
@vs-code-engineering
Copy link

📬 CODENOTIFY

The following users are being notified based on files changed in this PR:

@jrieken

Matched files:

  • src/vs/editor/contrib/suggest/browser/suggestWidget.ts
  • src/vs/editor/contrib/suggest/browser/suggestWidgetStatus.ts

@Tyriar Tyriar merged commit d51f2a7 into main Dec 30, 2025
28 checks passed
@Tyriar Tyriar deleted the tyriar/284277 branch December 30, 2025 07:50
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.

4 participants